#!/bin/bash
#####################################################################
# kssl_key_gen                                            August 2005
# 
# KSSLD(key_tool): An implementation of SSL/TLS in the Linux Kernel
# Copyright (C) 2005  NTT COMWARE Corporation.
#
# This file based in part on code from LVS www.linuxvirtualserver.org
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#
#####################################################################

DEFAULT_BITS=1024
DEFAULT_COUNTRY="AU"
DEFAULT_STATE="Some-State"
DEFAULT_LOCALITY=""
DEFAULT_ORGANISATION="Internet Widgits Pty Ltd"
DEFAULT_ORGANISATIONAL_UNIT=""
DEFAULT_COMMON_NAME=""
DEFAULT_EMAIL=""

die ()
{
	echo $@ 1>&2
	rm -f $CONFFILE $ERRFILE
	exit 1
}

CONFFILE=`mktemp /tmp/key_gen.conf.XXXXXXX`
if [ $? != 0 ]; then die "Error creating config file"; fi
ERRFILE=`mktemp /tmp/key_gen.err.XXXXXXX`
if [ $? != 0 ]; then die "Error creating config file"; fi


# Get input from user

echo -n "Bit length for keys [$DEFAULT_BITS]: " >&2
read bits

if [ "$bits" = "" ]; then
	bits="$DEFAULT_BITS"
fi


echo -n "Country Name (2 letter code) [$DEFAULT_COUNTRY]: " >&2
read country

if [ "$country" = "" ]; then
	country="$DEFAULT_COUNTRY"
fi


echo -n "State or Province Name (full name) [$DEFAULT_STATE]: " >&2
read state

if [ "$state" = "" ]; then
	state="$DEFAULT_STATE"
fi


echo -n "Locality Name (e.g. city) [$DEFAULT_LOCALITY]: " >&2
read locality

if [ "$locality" = "" ]; then
	locality="$DEFAULT_LOCALITY"
fi


echo -n "Organisation Name (e.g. company) [$DEFAULT_ORGANISATION]: " >&2
read organisation

if [ "$organisation" = "" ]; then
	organisation="$DEFAULT_ORGANISATION"
fi


echo -n "Organizational Unit Name (e.g. section) [$DEFAULT_ORGANISATIONAL_UNIT]: " >&2
read organisational_unit

if [ "$organisational_unit" = "" ]; then
	organisational_unit="$DEFAULT_ORGANISATIONAL_UNIT"
fi


echo -n "Common Name (e.g. fully qualified hostname) [$DEFAULT_COMMON_NAME]: " >&2
read common_name

if [ "$common_name" = "" ]; then
	common_name="$DEFAULT_COMMON_NAME"
fi


echo -n "Email Address [$DEFAULT_EMAIL]: " >&2
read email

if [ "$email" = "" ]; then
	email="$DEFAULT_EMAIL"
fi


cat << __EOF__

Password for encrypted keys. If empty encrypted keys will not
be generated. Unencrypted keys will be generated regardless.
These may be deleted if you do not wish to use them and
have the encrypted versions.

__EOF__

echo -n "Password: " >&2
stty -echo
read pass
stty echo
echo

echo


# Generate configuration file

cat >> $CONFFILE  << __EOF__

[ req ]
distinguished_name     = req_distinguished_name
prompt                 = no
x509_extensions        = v3_ca

[ v3_ca ]

subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = CA:true

[ req_distinguished_name ]

__EOF__
if [ $? != 0 ]; then die "Error creating config file"; fi


if [ "$country" != "" ]; then
	echo "C                      = $country" >> $CONFFILE
	if [ $? != 0 ]; then die "Error creating config file"; fi
fi

if [ "$state" != "" ]; then
	echo "ST                     = $state" >> $CONFFILE
	if [ $? != 0 ]; then die "Error creating config file"; fi
fi

if [ "$locality" != "" ]; then
	echo "L                      = $locality" >> $CONFFILE
	if [ $? != 0 ]; then die "Error creating config file"; fi
fi

if [ "$organisation" != "" ]; then
	echo "O                      = $organisation" >> $CONFFILE
	if [ $? != 0 ]; then die "Error creating config file"; fi
fi

if [ "$organisational_unit" != "" ]; then
	echo "OU                     = $organisational_unit" >> $CONFFILE
	if [ $? != 0 ]; then die "Error creating config file"; fi
fi

if [ "$common_name" != "" ]; then
	echo "CN                     = $common_name" >> $CONFFILE
	if [ $? != 0 ]; then die "Error creating config file"; fi
fi

if [ "$email" != "" ]; then
	echo "emailAddress           = $email" >> $CONFFILE
	if [ $? != 0 ]; then die "Error creating config file"; fi
fi

# # Generate DSA Key
# 
# DSA_PARAMETERS=parameters.dsa.pem
# DSA_KEY=key.dsa.pem
# DSA_KEY_DER=key.dsa.der
# DSA_KEY_ENC=key.dsa.enc.pem
# DSA_KEY_ENC_DER=key.dsa.enc.der
# DSA_CERT=cert.dsa.pem
# 
# echo -n "Generating DSA Key and Certificate (this may take some time)..." >&2
# 
# openssl dsaparam -genkey $bits > $DSA_PARAMETERS 2> $ERRFILE
# if [ $? != 0 ]; then 
# 	cat $ERRFILE
# 	die "Error running openssl dsaparam"; 
# fi
# 
# openssl gendsa -out $DSA_KEY  $DSA_PARAMETERS 2> $ERRFILE
# if [ $? != 0 ]; then 
# 	cat $ERRFILE
# 	die "Error running openssl gendsa"; 
# fi
# 
# openssl req -new -x509 -out $DSA_CERT -days 365 -key $DSA_KEY \
# 	-config $CONFFILE
# if [ $? != 0 ]; then die "Error running openssl req (dsa)"; fi
# 
# openssl dsa -in $DSA_KEY -out $DSA_KEY_DER -outform DER 2> $ERRFILE
# if [ $? != 0 ]; then 
# 	die "Error running openssl rsa plaintext pem -> plaintext der"; 
# fi
# 
# if [ "$pass" != "" ]; then
# cat << __EOF__ | openssl dsa -des3 -in $DSA_KEY -out $DSA_KEY_ENC \
# 	-passout stdin 2> $ERRFILE
# $pass
# __EOF__
# if [ $? != 0 ]; then 
# 	cat $ERRFILE
# 	die "Error running openssl rsa plaintext pem -> encrypted pem"; 
# fi
# cat << __EOF__ | openssl dsa -des3 -in $DSA_KEY -out $DSA_KEY_ENC_DER \
# 	-outform DER -passout stdin 2> $ERRFILE
# $pass
# __EOF__
# if [ $? != 0 ]; then 
# 	cat $ERRFILE
# 	die "Error running openssl rsa plaintext pem -> encrypted der"; 
# fi
# else
# rm -f $DSA_KEY_ENC $DSA_KEY_ENC_DER
# fi
# 
# #openssl x509 -in $DSA_CERT -noout -subject -issuer -email \
# #	-startdate -enddate -fingerprint
# #if [ $? != 0 ]; then die "Error running openssl x509 (dsa)"; fi
# 
# echo
# echo "DSA Parameters (pem): $DSA_PARAMETERS" >&2
# echo "DSA Key (plaintext, pem): $DSA_KEY" >&2
# echo "DSA Key (plaintext, der): $DSA_KEY_DER" >&2
# if [ "$pass" != "" ]; then
# 	echo "DSA Key (encrypted, pem): $DSA_KEY_ENC" >&2
# 	echo "DSA Key (encrypted, der): $DSA_KEY_ENC_DER" >&2
# fi
# echo "DSA Certificate (pem): $DSA_CERT" >&2
# echo


# Generate RSA Key

echo -n "Generating RSA Key and Certificate..." >&2

RSA_KEY=key.rsa.pem
RSA_KEY_DER=key.rsa.der
RSA_KEY_ENC=key.rsa.enc.pem
RSA_KEY_ENC_DER=key.rsa.enc.der
RSA_CERT=cert.rsa.pem

openssl genrsa -out $RSA_KEY $bits 2> $ERRFILE
if [ $? != 0 ]; then 
	cat $ERRFILE
	die "Error running openssl genrsa"; 
fi

openssl req -new -x509 -out $RSA_CERT -days 365 -key $RSA_KEY \
	-config $CONFFILE 2> $ERRFILE
if [ $? != 0 ]; then 
	cat $ERRFILE
	die "Error running openssl req (rsa)"; 
fi

if [ "$pass" != "" ]; then
cat << __EOF__ | openssl rsa -des3 -in $RSA_KEY -out $RSA_KEY_ENC \
	-passout stdin 2> $ERRFILE
$pass
__EOF__
if [ $? != 0 ]; then 
	cat $ERRFILE
	die "Error running openssl rsa plaintext pem -> encrypted pem"; 
fi
cat << __EOF__ | openssl rsa -des3 -in $RSA_KEY -out $RSA_KEY_ENC_DER \
	-passout stdin -outform DER 2> $ERRFILE
$pass
__EOF__
if [ $? != 0 ]; then 
	cat $ERRFILE
	die "Error running openssl rsa plaintext pem -> encrypted der"; 
fi
else
rm -f $RSA_KEY_ENC
fi

#openssl x509 -in $RSA_CERT -noout -subject -issuer -email \
#	-startdate -enddate -fingerprint
#if [ $? != 0 ]; then die "Error running openssl x509 (rsa)"; fi


echo
echo "RSA Key (plaintext, pem): $RSA_KEY" >&2
echo "RSA Key (plaintext, der): $RSA_KEY_DER" >&2
if [ "$pass" != "" ]; then
	echo "RSA Key (encrypted, pem): $RSA_KEY_ENC" >&2
	echo "RSA Key (encrypted, der): $RSA_KEY_ENC_DER" >&2
fi
echo "RSA Certificate: $RSA_CERT" >&2
echo

# # Generate DH Key
# 
# DH_PARAMETERS=parameters.dh.pem
# 
# echo -n "Generating DH Parameters (this may take a long time time)..." >&2
# 
# openssl gendh -out $DH_PARAMETERS $bits 2> $ERRFILE
# if [ $? != 0 ]; then 
# 	echo $ERRFILE
# 	die "Error running openssl gendh"; 
# fi
# 
# echo
# echo "DH parameters (plaintext, pem): $DH_PARAMETERS" >&2
# echo


rm -f $CONFFILE $ERRFILE
exit 0
