#!/bin/sh
##
##  mca -- My CA (trivial CA management for testing) 
##  Copyright (c) 1998 Ralf S. Engelschall, All Rights Reserved. 
##
##  This script is derived from mkcert.sh from the mod_ssl distribution.
##  It's based on three external programs:
##
##  ssleay ... get it from ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/ 
##  ca-fix ... get it from http://www.drh-consultancy.demon.co.uk/ca-fix.html
##  pkcs12 ... get it from http://www.drh-consultancy.demon.co.uk/pkcs12faq.html
##

#   parameters
ssleay="/sw/pkg/ssleay/bin/ssleay"
cafix="/sw/pkg/ssleay/bin/ca-fix"
pkcs12="/sw/pkg/ssleay/bin/pkcs12"
sslcrtdir="."
sslcsrdir="."
sslkeydir="."

#   some optional terminal sequences
case $TERM in
    xterm|xterm*|vt220|vt220*)
        T_MD=`echo dummy | awk '{ printf("%c%c%c%c", 27, 91, 49, 109); }'`
        T_ME=`echo dummy | awk '{ printf("%c%c%c", 27, 91, 109); }'`
        ;;
    vt100|vt100*)
        T_MD=`echo dummy | awk '{ printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }'`
        T_ME=`echo dummy | awk '{ printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }'`
        ;;
    default)
        T_MD=''
        T_ME=''
        ;;
esac

#   find some random files
#   (do not use /dev/random here, because this device 
#   doesn't work as expected on all platforms)
randfiles=''
for file in /var/log/messages /var/adm/messages \
            /kernel /vmunix /vmlinuz \
            /etc/hosts /etc/resolv.conf; do
    if [ -f $file ]; then
        if [ ".$randfiles" = . ]; then
            randfiles="$file"
        else
            randfiles="${randfiles}:$file"
        fi
    fi
done

if [ ! -f $sslcrtdir/ca.crt ]; then
    echo ""
    echo "${T_MD}Generating custom Certificate Authority (CA)${T_ME}"
    echo "______________________________________________________________________"
    echo ""
    echo "${T_MD}STEP 1: Generating RSA private key for CA (1024 bit)${T_ME}"
    if [ ! -f $HOME/.rnd ]; then
        touch $HOME/.rnd
    fi
    if [ ".$randfiles" != . ]; then
        $ssleay genrsa -rand $randfiles \
                       -out $sslkeydir/ca.key \
                       1024
    else
        $ssleay genrsa -out $sslkeydir/ca.key \
                       1024
    fi
    if [ $? -ne 0 ]; then
        echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2
        exit 1
    fi
    echo "______________________________________________________________________"
    echo ""
    echo "${T_MD}STEP 2: Generating X.509 certificate signing request for CA${T_ME}"
    cat >.mkcert.cfg <<EOT
[ req ]
default_bits                    = 1024
distinguished_name              = req_DN
[ req_DN ]
countryName                     = "1. Country Name             (2 letter code)"
countryName_default             = XY
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = "2. State or Province Name   (full name)    "
stateOrProvinceName_default     = Snake Desert
localityName                    = "3. Locality Name            (eg, city)     "
localityName_default            = Snake Town
0.organizationName              = "4. Organization Name        (eg, company)  "
0.organizationName_default      = Snake Oil, Ltd
organizationalUnitName          = "5. Organizational Unit Name (eg, section)  "
organizationalUnitName_default  = Certificate Authority
commonName                      = "6. Common Name              (eg, CA name)  "
commonName_max                  = 64
commonName_default              = Snake Oil CA
emailAddress                    = "7. Email Address            (eg, name@FQDN)"
emailAddress_max                = 40
emailAddress_default            = ca@snakeoil.dom
EOT
    $ssleay req -config .mkcert.cfg \
                -new \
                -key $sslkeydir/ca.key \
                -out $sslcsrdir/ca.csr
    if [ $? -ne 0 ]; then
        echo "mkcert.sh:Error: Failed to generate certificate signing request" 1>&2
        exit 1
    fi
    echo "______________________________________________________________________"
    echo ""
    echo "${T_MD}STEP 3: Generating X.509 certificate for CA signed by itself${T_ME}"
    $ssleay x509 -req \
                 -days 365 \
                 -signkey $sslkeydir/ca.key \
                 -in  $sslcsrdir/ca.csr \
                 -out $sslcrtdir/ca.crt
    if [ $? -ne 0 ]; then
        echo "mkcert.sh:Error: Failed to generate self-signed CA certificate" 1>&2
        exit 1
    fi
    $cafix \
         -caset \
         -nscertype 0x07 \
         -nobscrit \
         -pathlen 0 \
         -in $sslcrtdir/ca.crt \
         -inkey $sslkeydir/ca.key \
         -out $sslcrtdir/ca-new.crt 
    if [ $? -ne 0 ]; then
        echo "mkcert.sh:Error: Failed to patch X.509 certificate" 1>&2
        exit 1
    fi
    cp $sslcrtdir/ca-new.crt $sslcrtdir/ca.crt
    rm -f $sslcrtdir/ca-new.crt
    echo "______________________________________________________________________"
    echo ""
    echo "${T_MD}RESULT:${T_ME}"
    $ssleay verify $sslcrtdir/ca.crt
    if [ $? -ne 0 ]; then
        echo "mkcert.sh:Error: Failed to verify resulting X.509 certificate" 1>&2
        exit 1
    fi
    $cafix -in $sslcrtdir/ca.crt -inkey $sslkeydir/ca.key -print
fi

echo ""
echo "${T_MD}Generating custom USER${T_ME}"
echo "______________________________________________________________________"
echo ""
echo "${T_MD}STEP 5: Generating RSA private key for USER (1024 bit)${T_ME}"
if [ ! -f $HOME/.rnd ]; then
    touch $HOME/.rnd
fi
if [ ".$randfiles" != . ]; then
    $ssleay genrsa -rand $randfiles \
                   -out $sslkeydir/user.key \
                   1024
else
    $ssleay genrsa -out $sslkeydir/user.key \
                   1024
fi
if [ $? -ne 0 ]; then
    echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2
    exit 1
fi
echo "______________________________________________________________________"
echo ""
echo "${T_MD}STEP 6: Generating X.509 certificate signing request for USER${T_ME}"
cat >.mkcert.cfg <<EOT
[ req ]
default_bits                    = 1024
distinguished_name              = req_DN
[ req_DN ]
countryName                     = "1. Country Name             (2 letter code)"
countryName_default             = XY
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = "2. State or Province Name   (full name)    "
stateOrProvinceName_default     = Snake Desert
localityName                    = "3. Locality Name            (eg, city)     "
localityName_default            = Snake Town
0.organizationName              = "4. Organization Name        (eg, company)  "
0.organizationName_default      = Snake Oil, Ltd
organizationalUnitName          = "5. Organizational Unit Name (eg, section)  "
organizationalUnitName_default  = Webserver Team
commonName                      = "6. Common Name              (eg, FQDN)     "
commonName_max                  = 64
commonName_default              = www.snakeoil.dom
emailAddress                    = "7. Email Address            (eg, name@fqdn)"
emailAddress_max                = 40
emailAddress_default            = www@snakeoil.dom
EOT
$ssleay req -config .mkcert.cfg \
            -new \
            -key $sslkeydir/user.key \
            -out $sslcsrdir/user.csr
if [ $? -ne 0 ]; then
    echo "mkcert.sh:Error: Failed to generate certificate signing request" 1>&2
    exit 1
fi
echo "______________________________________________________________________"
echo ""
echo "${T_MD}STEP 7: Generating X.509 certificate signed by own CA${T_ME}"
if [ ! -f .mkcert.serial ]; then
    echo '01' >.mkcert.serial
fi
$ssleay x509 -days 365 \
             -CAserial .mkcert.serial \
             -CA $sslcrtdir/ca.crt \
             -CAkey $sslkeydir/ca.key \
             -in $sslcsrdir/user.csr -req \
             -out $sslcrtdir/user.crt
if [ $? -ne 0 ]; then
    echo "mkcert.sh:Error: Failed to generate X.509 certificate" 1>&2
    exit 1
fi
$cafix \
     -nscertype 0xB0 \
     -nobscrit \
     -pathlen 0 \
     -in $sslcrtdir/user.crt \
     -inkey $sslkeydir/user.key \
     -nosign \
     -out $sslcrtdir/user-tmp.crt
if [ $? -ne 0 ]; then
    echo "mkcert.sh:Error: Failed to patch X.509 certificate" 1>&2
    exit 1
fi
$cafix \
     -in $sslcrtdir/user-tmp.crt \
     -inkey $sslkeydir/ca.key \
     -out $sslcrtdir/user.crt 
if [ $? -ne 0 ]; then
    echo "mkcert.sh:Error: Failed to patch X.509 certificate" 1>&2
    exit 1
fi
rm -f $sslcrtdir/user-tmp.crt
caname="`$ssleay x509 -noout -text -in $sslcrtdir/ca.crt |\
         grep Subject: | sed -e 's;.*CN=;;' -e 's;/Em.*;;'`"
username="`$ssleay x509 -noout -text -in $sslcrtdir/user.crt |\
            grep Subject: | sed -e 's;.*CN=;;' -e 's;/Em.*;;'`"
$pkcs12 \
    -export \
    -in $sslcrtdir/user.crt \
    -inkey $sslkeydir/user.key \
    -certfile $sslcrtdir/ca.crt \
    -name "$username" \
    -caname "$caname" \
    -out $sslcrtdir/user.p12
echo "______________________________________________________________________"
echo ""
echo "${T_MD}RESULT:${T_ME}"
$ssleay verify -CAfile $sslcrtdir/ca.crt $sslcrtdir/user.crt
if [ $? -ne 0 ]; then
    echo "mkcert.sh:Error: Failed to verify resulting X.509 certificate" 1>&2
    exit 1
fi
$cafix -in $sslcrtdir/user.crt -inkey $sslkeydir/user.key -print
echo "______________________________________________________________________"
echo ""
echo "${T_MD}STEP 8: Enrypting RSA private key of USER with a pass phrase for security${T_ME}"
$ssleay rsa -des3 -in $sslkeydir/user.key -out $sslkeydir/user.key.crypt
if [ $? -ne 0 ]; then
    echo "mkcert.sh:Error: Failed to encrypt RSA private key" 1>&2
    exit 1
fi
cp $sslkeydir/user.key.crypt $sslkeydir/user.key
rm -f $sslkeydir/user.key.crypt

##EOF##
