Oops.. Sorry.. I thought I had posted a text/plain version (a wrong one must
have sneaked in).. Here it comes again.. 
But, please note that this is just my small utility script, and I haven't
tested it extensively.. If you wanted to add/remove any features, pl. do let
me know..

-Madhu


-----Original Message-----
From: Aaron Bannert [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, November 20, 2001 4:17 PM
To: [EMAIL PROTECTED]
Subject: Re: SSL and certficates script


On Tue, Nov 20, 2001 at 07:00:34PM -0500, MATHIHALLI,MADHUSUDAN
(HP-Cupertino,ex1) wrote:
>       Okay, here it comes.. Pl. do let me know if you have any problems.

Hi Madhu,

Sorry for giving you such a hard time today. :) Your work is appreciated.

Would you mind reposting with either MIME-type text/plain or just posting
the patch inline?

Thanks,
aaron

#!/bin/sh
##
##  mkcert.sh -- SSL Certificate Generation Utility
##

export certdir=/opt/apache2
export PATH=$certdir/ssl/bin:$PATH
openssl=`whence openssl`
type=
algo=
crt=
key=
view=

function Usage
{
echo "+---------------------------------------------------------------------+";
echo "| Before you install the package you now should prepare the SSL       |";
echo "| certificate system by running the 'mkcert.sh' command.              |";
echo "| For different situations the following variants are provided:       |";
echo "|                                                                     |";
echo "| % mkcert.sh --type=dummy    (dummy self-signed Snake Oil cert)      |";
echo "| % mkcert.sh --type=test     (test cert signed by Snake Oil CA)      |";
echo "| % mkcert.sh --type=custom   (custom cert signed by own CA)          |";
echo "| % mkcert.sh --type=existing (existing cert)                         |";
echo "|        --crt=/path/to/your.crt [--key=/path/to/your.key]            |";
echo "|                                                                     |";
echo "| Use type=dummy    when you're a  vendor package maintainer,         |";
echo "| the type=test     when you're an admin but want to do tests only,   |";
echo "| the type=custom   when you're an admin willing to run a real server |";
echo "| and type=existing when you're an admin who upgrades a server.       |";
echo "| (The default is type=test)                                          |";
echo "|                                                                     |";
echo "| Additionally add --algo=RSA (default) or --algo=DSA to select       |";
echo "| the signature algorithm used for the generated certificate.         |";
echo "|                                                                     |";
echo "| Use 'mkcert.sh --view' to display the generated data.               |";
echo "|                                                                     |";
echo "| Thanks for using Apache                                             |";
echo "+---------------------------------------------------------------------+";
exit 0
}

# Terminal Sequences
case $TERM in
  xterm|xterm*|vt220|vt220*)
    BB=`echo dummy | awk '{ printf("%c%c%c%c", 27, 91, 49, 109); }'`
    BE=`echo dummy | awk '{ printf("%c%c%c", 27, 91, 109); }'`
    ;;
  vt100|vt100*)
    BB=`echo dummy | awk '{ printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }'`
    BE=`echo dummy | awk '{ printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }'`
    ;;
  default)
    BB=''
    BE=''
    ;;
esac


# Check if the user has entered the required details :
if [ $# -eq 0 ]; then
    Usage
fi

for opt
  do
    # If previous option needs an argument, assign it.
    if [ "x$prev" != "x" ]; then
        eval "$prev=\$opt"
        prev=""
        continue
    fi

    # Split out arguments
    case "$opt" in
      -*=*) arg=`echo "$opt" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
         *) arg= ;;
    esac

    # Process arguments
    case "$opt" in
      -h|-help|--help)
          Usage
          exit 1
          ;;
      -v|--view)
          view=1
          ;;
      -t|--type=*)
          type="$arg"
          ;;
      -a|--algo=*)
          algo="$arg"
          ;;
      -c|--crt=*)
          crt="$arg"
          ;;
      -k|--key=*)
          key="$arg"
          ;;
      * )
          echo "mkcert.sh:Error: invalid option '$opt'" 1>&2
          exit 1
          ;;
    esac
done


echo "${BB}SSL Certificate Generation Utility${BE} (mkcert.sh)"

echo "Enter the Certificate(s) Location [$certdir] :\c"
read ncertdir < /dev/tty
if [ "x$ncertdir" != "x" ]; then
    certdir=$ncertdir
fi

if [ ! -d $certdir ]; then
    echo "\nERROR: [$certdir] not found."
    echo "Please enter a valid location and try again."
    exit 1
fi

crtdir="$certdir/conf/ssl.crt"
keydir="$certdir/conf/ssl.key"


# Check if the OPENSSL binary is available.
if [ "x$openssl" = "x" ]; then
  for p in /usr/local/bin /usr/bin; do
    if test -f "$p/openssl"; then
      openssl="$p/openssl"
      break
    fi
  done
  if  [ "x$openssl" = "x" ]; then
    echo "Could not find OPENSSL in the path !!."
    exit 0
  fi
fi


# View certificates.
if [ ".$view" != . ]; then
    if [ -f "$crtdir/ca.crt" -a -f "$keydir/ca.key" ]; then
        echo ""
        echo "${BB}CA X.509 Certificate${BE} [ca.crt]"
        echo "______________________________________________________________________"
        $openssl x509 -noout -text -in $crtdir/ca.crt
        echo ""
        if [ ".`$openssl x509 -noout -text -in $crtdir/ca.crt | grep 'Signature 
Algorithm' | grep -i RSA`" != . ]; then
            echo "${BB}CA RSA Private Key${BE} [ca.key]"
            echo 
"______________________________________________________________________"
            $openssl rsa -noout -text -in $keydir/ca.key
        else
            echo "${BB}CA DSA Private Key${BE} [ca.key]"
            echo 
"______________________________________________________________________"
            $openssl dsa -noout -text -in $keydir/ca.key
        fi
    else
        echo ""
        echo "NO CA Certificate found in the directory specified !!."
    fi

    if [ -f "$crtdir/server.crt" -a -f "$keydir/server.key" ]; then
        echo ""
        echo "${BB}Server X.509 Certificate${BE} [server.crt]"
        echo "______________________________________________________________________"
        $openssl x509 -noout -text -in $crtdir/server.crt
        echo ""
        if [ ".`$openssl x509 -noout -text -in $crtdir/server.crt | grep 'Signature 
Algorithm' | grep -i RSA`" != . ]; then
            echo "${BB}Server RSA Private Key${BE} [server.key]"
            echo 
"______________________________________________________________________"
            $openssl rsa -noout -text -in $keydir/server.key
        else
            echo "${BB}Server DSA Private Key${BE} [server.key]"
            echo 
"______________________________________________________________________"
            $openssl dsa -noout -text -in $keydir/server.key
        fi
    else
        echo ""
        echo "NO Server Certificate found in the directory specified !!."
    fi
    exit 0
fi

# Create the directories if required.
if [ ! -d $crtdir ]; then
    echo "Creating Certificates directory [$crtdir]"
    mkdir -p $crtdir
fi

if [ ! -d $keydir ]; then
    echo "Creating keys directory [$crtdir]"
    mkdir -p $keydir
fi

# Find random files and initialize the RANDFILE environment variable
randfiles=''
for file in /var/log/messages /var/adm/messages /var/log/system.log /var/wtmp \
            /etc/hosts /etc/group /etc/resolv.conf /bin/ls; do
  if [ -r $file ]; then
    if [ ".$randfiles" = . ]; then
      randfiles="$file"
    else
      randfiles="${randfiles}:$file"
    fi
  fi
done

if [ -f $HOME/.rnd ]; then
    RANDFILE="$HOME/.rnd"
else
    RANDFILE=".mkcert.rnd"
    (ps; date) >$RANDFILE
fi
export RANDFILE



# Extract parameters
case "x$type" in
    x ) type=test ;;
esac

case "x$algo" in
    xRSA|xrsa ) 
        algo=RSA
        ;;
    xDSA|xdsa ) 
        algo=DSA 
        ;;
    x ) 
        algo=choose
        ;;
    * ) echo "Unknown algorithm \'$algo' (use RSA or DSA!)" 1>&2
        exit 1
        ;;
esac

#   processing
case $type in

    dummy)
        echo ""
        echo "${BB}Generating self-signed Snake Oil certificate [DUMMY]${BE}"
        echo "______________________________________________________________________"
        echo ""
        if [ ".$algo" = .choose ]; then
            algo=RSA
        fi

        if [ ".$algo" = .RSA ]; then
            if [ ! -f "$crtdir/server-rsa.crt" -a ! -f "$keydir/server-rsa.key" ]; then
                echo ""
                echo ""
                echo "There are no dummy certificates loaded on your system."
                echo "You can create certificates using the --custom option."
                exit 1
            fi
            cp $crtdir/server-rsa.crt $crtdir/server.crt
            (umask 077; cp $keydir/server-rsa.key $keydir/server.key)
        else
            if [ ! -f "$crtdir/server-dsa.crt" -a ! -f "$keydir/server-dsa.key" ]; then
                echo ""
                echo ""
                echo "There are no dummy certificates loaded on your system."
                echo "You can create certificates using the --custom option."
                exit 1
            fi
            cp $crtdir/server-dsa.crt $crtdir/server.crt
            (umask 077; cp $keydir/server-dsa.key $keydir/server.key)
        fi
        echo "${BB}RESULT: Server Certification Files${BE}"
        echo ""
        echo "o  ${BB}$keydir/server.key${BE}"
        echo "   The PEM-encoded $algo private key file which you configure"
        echo "   with the 'SSLCertificateKeyFile' directive (automatically done"
        echo "   when you install via APACI). ${BB}KEEP THIS FILE PRIVATE!${BE}"
        echo ""
        echo "o  ${BB}$crtdir/server.crt${BE}"
        echo "   The PEM-encoded X.509 certificate file which you configure"
        echo "   with the 'SSLCertificateFile' directive (automatically done"
        echo "   when you install via APACI)."
        echo ""
        echo "WARNING: Do not use this for real-life/production systems"
        echo ""
        ;;

    test)
        echo ""
        echo "${BB}Generating test certificate signed by Snake Oil CA [TEST]${BE}"
        echo "WARNING: Do not use this for real-life/production systems"
        if [ ".$algo" = .choose ]; then
            echo 
"______________________________________________________________________"
            echo ""
            echo "${BB}STEP 0: Decide the signature algorithm used for 
certificate${BE}"
            echo "The generated X.509 CA certificate can contain either"
            echo "RSA or DSA based ingredients. Select the one you want to use."
            def1=R def2=r def=RSA
            prompt="Signature Algorithm ((R)SA or (D)SA) [$def1]:"
            while [ 1 ]; do
                echo dummy | awk '{ printf("%s", prompt); }' "prompt=$prompt"
                read algo
                if [ ".$algo" = ".$def1" -o ".$algo" = ".$def2" -o ".$algo" = . ]; then
                    algo=$def
                    break
                elif [ ".$algo" = ".R" -o ".$algo" = ".r" ]; then
                    algo=RSA
                    break
                elif [ ".$algo" = ".D" -o ".$algo" = ".d" ]; then
                    algo=DSA
                    break
                else
                    echo "mkcert.sh:Warning: Invalid selection" 1>&2
                fi
            done
        fi
        if [ ".$algo" = ".DSA" ]; then
            echo ""
            echo "${BB}WARNING!${BE} You're generating a DSA based certificate/key 
pair."
            echo "         This implies that RSA based ciphers won't be available 
later,"
            echo "         which for your web server currently still means that mostly 
all"
            echo "         popular web browsers cannot connect to it. At least not 
until"
            echo "         you also generate an additional RSA based certificate/key 
pair"
            echo "         and configure them in parallel."
        fi
        echo "______________________________________________________________________"
        echo ""
        echo "${BB}STEP 1: Generating $algo private key (1024 bit) [server.key]${BE}"
        if [ ".$algo" = .RSA ]; then
            if [ ".$randfiles" != . ]; then
                $openssl genrsa -rand $randfiles -out $keydir/server.key 1024
            else
                $openssl genrsa -out $keydir/server.key 1024
            fi
            if [ $? -ne 0 ]; then
                echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2
                exit 1
            fi
        else
            echo "Generating DSA private key via SnakeOil CA DSA parameters"
            if [ ".$randfiles" != . ]; then
                (umask 077
                 $openssl gendsa -rand $randfiles \
                                 -out $keydir/server.key \
                                 $keydir/ca-dsa.prm)
            else
                (umask 077
                 $openssl gendsa -out $keydir/server.key \
                                 $keydir/ca-dsa.prm)
            fi
            if [ $? -ne 0 ]; then
                echo "mkcert.sh:Error: Failed to generate DSA private key" 1>&2
                exit 1
            fi
        fi
        echo "______________________________________________________________________"
        echo ""
        echo "${BB}STEP 2: Generating X.509 certificate signing request 
[server.csr]${BE}"
        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            = [EMAIL PROTECTED]
EOT
        $openssl req -config .mkcert.cfg \
                     -new \
                     -key $keydir/server.key \
                     -out $crtdir/server.csr
        if [ $? -ne 0 ]; then
            echo "mkcert.sh:Error: Failed to generate certificate signing request" 1>&2
            exit 1
        fi
        rm -f .mkcert.cfg
        prompt="8. Certificate Validity     (days)          [365]:"
        echo dummy | awk '{ printf("%s", prompt); }' "prompt=$prompt"
        read days
        if [ ".$days" = . ]; then
            days=365
        fi
        echo "______________________________________________________________________"
        echo ""
        echo "${BB}STEP 3: Generating X.509 certificate signed by Snake Oil CA 
[server.crt]${BE}"
        echo dummy | awk '{ printf("%s", prompt); }' "prompt=Certificate Version (1 or 
3) [3]:"
        read certversion
        extfile=""
        if [ ".$certversion" = .3 -o ".$certversion" = . ]; then
            extfile="-extfile .mkcert.cfg"
            cat >.mkcert.cfg <<EOT
extensions = x509v3
[ x509v3 ]
subjectAltName   = email:copy
nsComment        = "mod_ssl generated test server certificate"
nsCertType       = server
EOT
        fi
        if [ ! -f .mkcert.serial ]; then
            echo '01' >.mkcert.serial
        fi
        if [ ".$algo" = .RSA ]; then
            $openssl x509 $extfile \
                          -days $days \
                          -CAserial .mkcert.serial \
                          -CA $crtdir/ca.crt \
                          -CAkey $keydir/ca.key \
                          -in $crtdir/server.csr -req \
                          -out $crtdir/server.crt
        else
            $openssl x509 $extfile \
                          -days $days \
                          -CAserial .mkcert.serial \
                          -CA $crtdir/ca-dsa.crt \
                          -CAkey $keydir/ca-dsa.key \
                          -in $crtdir/server.csr -req \
                          -out $crtdir/server.crt
        fi
        if [ $? -ne 0 ]; then
            echo "mkcert.sh:Error: Failed to generate X.509 certificate" 1>&2
            exit 1
        fi
        rm -f .mkcert.cfg
        echo "Verify: matching certificate & key modulus"
        modcrt=`$openssl x509 -noout -modulus -in $crtdir/server.crt | sed -e 
's;.*Modulus=;;'`
        if [ ".$algo" = .RSA ]; then
            modkey=`$openssl rsa -noout -modulus -in $keydir/server.key | sed -e 
's;.*Modulus=;;'`
        else
            modkey=`$openssl dsa -noout -modulus -in $keydir/server.key | sed -e 
's;.*Key=;;'`
        fi
        if [ ".$modcrt" != ".$modkey" ]; then
            echo "mkcert.sh:Error: Failed to verify modulus on resulting X.509 
certificate" 1>&2
            exit 1
        fi
        echo "Verify: matching certificate signature"
        if [ ".$algo" = .RSA ]; then
            $openssl verify -CAfile $crtdir/ca-rsa.crt $crtdir/server.crt
        else
            $openssl verify -CAfile $crtdir/ca-dsa.crt $crtdir/server.crt
        fi
        if [ $? -ne 0 ]; then
            echo "mkcert.sh:Error: Failed to verify signature on resulting X.509 
certificate" 1>&2
            exit 1
        fi
        echo "______________________________________________________________________"
        echo ""
        echo "${BB}STEP 4: Enrypting $algo private key with a pass phrase for security 
[server.key]${BE}"
        echo "The contents of the server.key file (the generated private key) has to 
be"
        echo "kept secret. So we strongly recommend you to encrypt the server.key file"
        echo "with a Triple-DES cipher and a Pass Phrase."
        while [ 1 ]; do
            echo dummy | awk '{ printf("Encrypt the private key now? [Y/n]: "); }'
            read rc
            if [ ".$rc" = .n -o  ".$rc" = .N ]; then
                rc="n"
                break
            fi
            if [ ".$rc" = .y -o  ".$rc" = .Y -o ".$rc" = . ]; then
                rc="y"
                break
            fi
        done
        if [ ".$rc" = .y ]; then
            if [ ".$algo" = .RSA ]; then
                (umask 077
                 $openssl rsa -des3 \
                              -in  $keydir/server.key \
                              -out $keydir/server.key.crypt)
            else
                (umask 077
                 $openssl dsa -des3 \
                              -in  $keydir/server.key \
                              -out $keydir/server.key.crypt)
            fi
            if [ $? -ne 0 ]; then
                echo "mkcert.sh:Error: Failed to encrypt $algo private key" 1>&2
                exit 1
            fi
            (umask 077; cp $keydir/server.key.crypt $keydir/server.key)
            rm -f $keydir/server.key.crypt
            echo "Fine, you're using an encrypted $algo private key."
        else
            echo "Warning, you're using an unencrypted $algo private key."
            echo "Please notice this fact and do this on your own risk."
        fi
        echo "______________________________________________________________________"
        echo ""
        echo "${BB}RESULT: Server Certification Files${BE}"
        echo ""
        echo "o  ${BB}$keydir/server.key${BE}"
        echo "   The PEM-encoded $algo private key file which you configure"
        echo "   with the 'SSLCertificateKeyFile' directive (automatically done"
        echo "   when you install via APACI). ${BB}KEEP THIS FILE PRIVATE!${BE}"
        echo ""
        echo "o  ${BB}$crtdir/server.crt${BE}"
        echo "   The PEM-encoded X.509 certificate file which you configure"
        echo "   with the 'SSLCertificateFile' directive (automatically done"
        echo "   when you install via APACI)."
        echo ""
        echo "o  ${BB}$crtdir/server.csr${BE}"
        echo "   The PEM-encoded X.509 certificate signing request file which" 
        echo "   you can send to an official Certificate Authority (CA) in order"
        echo "   to request a real server certificate (signed by this CA instead"
        echo "   of our demonstration-only Snake Oil CA) which later can replace"
        echo "   the $crtdir/server.crt file."
        echo ""
        echo "WARNING: Do not use this for real-life/production systems"
        echo ""
        ;;

    custom)
        echo ""
        echo "${BB}Generating custom certificate signed by own CA [CUSTOM]${BE}"
        if [ ".$algo" = .choose ]; then
            echo 
"______________________________________________________________________"
            echo ""
            echo "${BB}STEP 0: Decide the signature algorithm used for 
certificates${BE}"
            echo "The generated X.509 certificates can contain either"
            echo "RSA or DSA based ingredients. Select the one you want to use."
            def1=R def2=r def=RSA
            prompt="Signature Algorithm ((R)SA or (D)SA) [$def1]:"
            while [ 1 ]; do
                echo dummy | awk '{ printf("%s", prompt); }' "prompt=$prompt"
                read algo
                if [ ".$algo" = ".$def1" -o ".$algo" = ".$def2" -o ".$algo" = . ]; then
                    algo=$def
                    break
                elif [ ".$algo" = ".R" -o ".$algo" = ".r" ]; then
                    algo=RSA
                    break
                elif [ ".$algo" = ".D" -o ".$algo" = ".d" ]; then
                    algo=DSA
                    break
                else
                    echo "mkcert.sh:Warning: Invalid selection" 1>&2
                fi
            done
        fi
        if [ ".$algo" = ".DSA" ]; then
            echo ""
            echo "${BB}WARNING!${BE} You're generating DSA based certificate/key 
pairs."
            echo "         This implies that RSA based ciphers won't be available 
later,"
            echo "         which for your web server currently still means that mostly 
all"
            echo "         popular web browsers cannot connect to it. At least not 
until"
            echo "         you also generate an additional RSA based certificate/key 
pair"
            echo "         and configure them in parallel."
        fi
        echo "______________________________________________________________________"
        echo ""
        echo "${BB}STEP 1: Generating $algo private key for CA (1024 bit) 
[ca.key]${BE}"
        if [ ".$algo" = .RSA ]; then
            if [ ".$randfiles" != . ]; then
                $openssl genrsa -rand $randfiles -out $keydir/ca.key 1024
            else
                $openssl genrsa -out $keydir/ca.key 1024
            fi
            if [ $? -ne 0 ]; then
                echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2
                exit 1
            fi
        else
            if [ ".$randfiles" != . ]; then
                $openssl dsaparam -rand $randfiles -out $keydir/ca.prm 1024
                echo "Generating DSA private key:"
                (umask 077
                 $openssl gendsa -rand $randfiles -out $keydir/ca.key $keydir/ca.prm)
            else
                $openssl dsaparam -out $keydir/ca.prm 1024
                echo "Generating DSA private key:"
                (umask 077
                 $openssl gendsa -out $keydir/ca.key $keydir/ca.prm)
            fi
            if [ $? -ne 0 ]; then
                echo "mkcert.sh:Error: Failed to generate DSA private key" 1>&2
                exit 1
            fi
        fi
        echo "______________________________________________________________________"
        echo ""
        echo "${BB}STEP 2: Generating X.509 certificate signing request for CA 
[ca.csr]${BE}"
        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            = [EMAIL PROTECTED]
EOT
        $openssl req -config .mkcert.cfg \
                     -new \
                     -key $keydir/ca.key \
                     -out $crtdir/ca.csr
        if [ $? -ne 0 ]; then
            echo "mkcert.sh:Error: Failed to generate certificate signing request" 1>&2
            exit 1
        fi
        rm -f .mkcert.cfg
        prompt="8. Certificate Validity     (days)          [365]:"
        echo dummy | awk '{ printf("%s", prompt); }' "prompt=$prompt"
        read days
        if [ ".$days" = . ]; then
            days=365
        fi
        echo "______________________________________________________________________"
        echo ""
        echo "${BB}STEP 3: Generating X.509 certificate for CA signed by itself 
[ca.crt]${BE}"
        echo dummy | awk '{ printf("%s", prompt); }' "prompt=Certificate Version (1 or 
3) [3]:"
        read certversion
        extfile=""
        if [ ".$certversion" = .3 -o ".$certversion" = . ]; then
            extfile="-extfile .mkcert.cfg"
            cat >.mkcert.cfg <<EOT
extensions = x509v3
[ x509v3 ]
subjectAltName   = email:copy
basicConstraints = CA:true,pathlen:0
nsComment        = "mod_ssl generated custom CA certificate"
nsCertType       = sslCA
EOT
        fi
        $openssl x509 $extfile \
                      -days $days \
                      -signkey $keydir/ca.key \
                      -in      $crtdir/ca.csr -req \
                      -out     $crtdir/ca.crt
        if [ $? -ne 0 ]; then
            echo "mkcert.sh:Error: Failed to generate self-signed CA certificate" 1>&2
            exit 1
        fi
        rm -f .mkcert.cfg
        echo "Verify: matching certificate & key modulus"
        modcrt=`$openssl x509 -noout -modulus -in $crtdir/ca.crt | sed -e 
's;.*Modulus=;;'`
        if [ ".$algo" = .RSA ]; then
            modkey=`$openssl rsa -noout -modulus -in $keydir/ca.key | sed -e 
's;.*Modulus=;;'`
        else
            modkey=`$openssl dsa -noout -modulus -in $keydir/ca.key | sed -e 
's;.*Key=;;'`
        fi
        if [ ".$modcrt" != ".$modkey" ]; then
            echo "mkcert.sh:Error: Failed to verify modulus on resulting X.509 
certificate" 1>&2
            exit 1
        fi
        echo "Verify: matching certificate signature"
        $openssl verify $crtdir/ca.crt
        if [ $? -ne 0 ]; then
            echo "mkcert.sh:Error: Failed to verify signature on resulting X.509 
certificate" 1>&2
            exit 1
        fi

        echo "Saving the CA Certificates"
        if [ ".$algo" = .RSA ]; then
            cp -f $crtdir/ca.crt $crtdir/ca-rsa.crt
            cp -f $keydir/ca.key $keydir/ca-rsa.key
        else
            cp -f $crtdir/ca.crt $crtdir/ca-dsa.crt
            cp -f $keydir/ca.key $keydir/ca-dsa.key
        fi

        echo "______________________________________________________________________"
        echo ""
        echo "${BB}STEP 4: Generating $algo private key for SERVER (1024 bit) 
[server.key]${BE}"
        if [ ".$algo" = .RSA ]; then
            if [ ".$randfiles" != . ]; then
                $openssl genrsa -rand $randfiles -out $keydir/server.key 1024
            else
                $openssl genrsa -out $keydir/server.key 1024
            fi
            if [ $? -ne 0 ]; then
                echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2
                exit 1
            fi
        else
            if [ ".$randfiles" != . ]; then
                (umask 077
                 $openssl gendsa -rand $randfiles \
                                 -out $keydir/server.key $keydir/ca.prm)
            else
                (umask 077
                 $openssl gendsa -out $keydir/server.key $keydir/ca.prm)
            fi
            if [ $? -ne 0 ]; then
                echo "mkcert.sh:Error: Failed to generate DSA private key" 1>&2
                exit 1
            fi
        fi
        echo "______________________________________________________________________"
        echo ""
        echo "${BB}STEP 5: Generating X.509 certificate signing request for SERVER 
[server.csr]${BE}"
        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            = [EMAIL PROTECTED]
EOT
        $openssl req -config .mkcert.cfg \
                     -new \
                     -key $keydir/server.key \
                     -out $crtdir/server.csr
        if [ $? -ne 0 ]; then
            echo "mkcert.sh:Error: Failed to generate certificate signing request" 1>&2
            exit 1
        fi
        rm -f .mkcert.cfg
        prompt="8. Certificate Validity     (days)          [365]:"
        echo dummy | awk '{ printf("%s", prompt); }' "prompt=$prompt"
        read days
        if [ ".$days" = . ]; then
            days=365
        fi
        echo "______________________________________________________________________"
        echo ""
        echo "${BB}STEP 6: Generating X.509 certificate signed by own CA 
[server.crt]${BE}"
        echo dummy | awk '{ printf("%s", prompt); }' "prompt=Certificate Version (1 or 
3) [3]:"
        read certversion
        extfile=""
        if [ ".$certversion" = .3 -o ".$certversion" = . ]; then
            extfile="-extfile .mkcert.cfg"
            cat >.mkcert.cfg <<EOT
extensions = x509v3
[ x509v3 ]
subjectAltName   = email:copy
nsComment        = "mod_ssl generated custom server certificate"
nsCertType       = server
EOT
        fi
        if [ ! -f .mkcert.serial ]; then
            echo '01' >.mkcert.serial
        fi
        $openssl x509 $extfile \
                      -days $days \
                      -CAserial .mkcert.serial \
                      -CA    $crtdir/ca.crt \
                      -CAkey $keydir/ca.key \
                      -in    $crtdir/server.csr -req \
                      -out   $crtdir/server.crt
        if [ $? -ne 0 ]; then
            echo "mkcert.sh:Error: Failed to generate X.509 certificate" 1>&2
            exit 1
        fi
        rm -f .mkcert.cfg
        echo "Verify: matching certificate & key modulus"
        modcrt=`$openssl x509 -noout -modulus -in $crtdir/server.crt | sed -e 
's;.*Modulus=;;'`
        if [ ".$algo" = .RSA ]; then
            modkey=`$openssl rsa -noout -modulus -in $keydir/server.key | sed -e 
's;.*Modulus=;;'`
        else
            modkey=`$openssl dsa -noout -modulus -in $keydir/server.key | sed -e 
's;.*Key=;;'`
        fi
        if [ ".$modcrt" != ".$modkey" ]; then
            echo "mkcert.sh:Error: Failed to verify modulus on resulting X.509 
certificate" 1>&2
            exit 1
        fi
        echo "Verify: matching certificate signature"
        $openssl verify -CAfile $crtdir/ca.crt $crtdir/server.crt
        if [ $? -ne 0 ]; then
            echo "mkcert.sh:Error: Failed to verify signature on resulting X.509 
certificate" 1>&2
            exit 1
        fi
        echo "______________________________________________________________________"
        echo ""
        echo "${BB}STEP 7: Enrypting $algo private key of CA with a pass phrase for 
security [ca.key]${BE}"
        echo "The contents of the ca.key file (the generated private key) has to be"
        echo "kept secret. So we strongly recommend you to encrypt the server.key file"
        echo "with a Triple-DES cipher and a Pass Phrase."
        while [ 1 ]; do
            echo dummy | awk '{ printf("Encrypt the private key now? [Y/n]: "); }'
            read rc
            if [ ".$rc" = .n -o  ".$rc" = .N ]; then
                rc="n"
                break
            fi
            if [ ".$rc" = .y -o  ".$rc" = .Y -o ".$rc" = . ]; then
                rc="y"
                break
            fi
        done
        if [ ".$rc" = .y ]; then
            if [ ".$algo" = .RSA ]; then
                (umask 077
                 $openssl rsa -des3 \
                              -in  $keydir/ca.key -out $keydir/ca.key.crypt)
            else
                (umask 077
                 $openssl dsa -des3 \
                              -in  $keydir/ca.key -out $keydir/ca.key.crypt)
            fi
            if [ $? -ne 0 ]; then
                echo "mkcert.sh:Error: Failed to encrypt $algo private key" 1>&2
                exit 1
            fi
            (umask 077; cp $keydir/ca.key.crypt $keydir/ca.key)
            rm -f $keydir/ca.key.crypt
            echo "Fine, you're using an encrypted private key."
        else
            echo "Warning, you're using an unencrypted private key."
            echo "Please notice this fact and do this on your own risk."
        fi
        echo "______________________________________________________________________"
        echo ""
        echo "${BB}STEP 8: Enrypting $algo private key of SERVER with a pass phrase 
for security [server.key]${BE}"
        echo "The contents of the server.key file (the generated private key) has to 
be"
        echo "kept secret. So we strongly recommend you to encrypt the server.key file"
        echo "with a Triple-DES cipher and a Pass Phrase."
        while [ 1 ]; do
            echo dummy | awk '{ printf("Encrypt the private key now? [Y/n]: "); }'
            read rc
            if [ ".$rc" = .n -o  ".$rc" = .N ]; then
                rc="n"
                break
            fi
            if [ ".$rc" = .y -o  ".$rc" = .Y -o ".$rc" = . ]; then
                rc="y"
                break
            fi
        done
        if [ ".$rc" = .y ]; then
            if [ ".$algo" = .RSA ]; then
                (umask 077
                 $openssl rsa -des3 \
                              -in  $keydir/server.key \
                              -out $keydir/server.key.crypt)
            else
                (umask 077
                 $openssl dsa -des3 \
                              -in  $keydir/server.key \
                              -out $keydir/server.key.crypt)
            fi
            if [ $? -ne 0 ]; then
                echo "mkcert.sh:Error: Failed to encrypt $algo private key" 1>&2
                exit 1
            fi
            (umask 077; cp $keydir/server.key.crypt $keydir/server.key)
            rm -f $keydir/server.key.crypt
            echo "Fine, you're using an encrypted $algo private key."
        else
            echo "Warning, you're using an unencrypted $algo private key."
            echo "Please notice this fact and do this on your own risk."
        fi
        echo "______________________________________________________________________"
        echo ""
        echo "${BB}RESULT: CA and Server Certification Files${BE}"
        echo ""
        echo "o  ${BB}$keydir/ca.key${BE}"
        echo "   The PEM-encoded $algo private key file of the CA which you can"
        echo "   use to sign other servers or clients. ${BB}KEEP THIS FILE 
PRIVATE!${BE}"
        echo ""
        echo "o  ${BB}$crtdir/ca.crt${BE}"
        echo "   The PEM-encoded X.509 certificate file of the CA which you use to"
        echo "   sign other servers or clients. When you sign clients with it (for"
        echo "   SSL client authentication) you can configure this file with the"
        echo "   'SSLCACertificateFile' directive."
        echo ""
        echo "o  ${BB}$keydir/server.key${BE}"
        echo "   The PEM-encoded $algo private key file of the server which you 
configure"
        echo "   with the 'SSLCertificateKeyFile' directive (automatically done"
        echo "   when you install via APACI). ${BB}KEEP THIS FILE PRIVATE!${BE}"
        echo ""
        echo "o  ${BB}$crtdir/server.crt${BE}"
        echo "   The PEM-encoded X.509 certificate file of the server which you 
configure"
        echo "   with the 'SSLCertificateFile' directive (automatically done"
        echo "   when you install via APACI)."
        echo ""
        echo "o  ${BB}$crtdir/server.csr${BE}"
        echo "   The PEM-encoded X.509 certificate signing request of the server file 
which" 
        echo "   you can send to an official Certificate Authority (CA) in order"
        echo "   to request a real server certificate (signed by this CA instead"
        echo "   of our own CA) which later can replace the $crtdir/server.crt"
        echo "   file."
        echo ""
        echo "Congratulations that you establish your server with real certificates."
        echo ""
        ;;

    existing)
        echo ""
        echo "${BB}Using existing custom certificate [EXISTING]${BE}"
        echo "______________________________________________________________________"
        echo ""
        if [ ".$crt" = . ]; then
            echo "mkcert.sh: No certificate file given" 1>&2
            exit 1
        fi
        if [ ! -f "$crt" ]; then
            echo "mkcert.sh: Cannot find certificate file: $crt" 1>&2
            exit 1
        fi
        if [ ".$key" != . ]; then
            if [ ! -f "$key" ]; then
                echo "mkcert.sh: Cannot find private key file: $key" 1>&2
                exit 1
            fi
            cp $crt $crtdir/server.crt
            (umask 077; cp $key $keydir/server.key)
        else
            key=$crt
            umask 077
            touch $keydir/server.key
            sed -e '/-----BEGIN CERTIFICATE/,/-----END CERTIFICATE/p' -e '/.*/d' \
                <$crt >$crtdir/server.crt
            sed -e '/-----BEGIN ... PRIVATE KEY/,/-----END ... PRIVATE KEY/p' -e 
'/.*/d' \
                <$key >$keydir/server.key
        fi
        $openssl x509 -noout -in $crtdir/server.crt
        if [ $? -ne 0 ]; then
            echo "mkcert.sh:Error: Failed to check certificate contents: $crt" 1>&2
            exit 1
        fi
        if [ ".`grep 'PRIVATE KEY' $keydir/server.key | grep RSA`" != . ]; then
            algo=RSA
        else
            algo=DSA
        fi
        echo "${BB}RESULT: Server Certification Files${BE}"
        echo ""
        echo "o  ${BB}$keydir/server.key${BE}"
        echo "   The PEM-encoded $algo private key file which you configure"
        echo "   with the 'SSLCertificateKeyFile' directive (automatically done"
        echo "   when you install via APACI). ${BB}KEEP THIS FILE PRIVATE!${BE}"
        echo ""
        echo "o  ${BB}$crtdir/server.crt${BE}"
        echo "   The PEM-encoded X.509 certificate file which you configure"
        echo "   with the 'SSLCertificateFile' directive (automatically done"
        echo "   when you install via APACI)."
        echo ""
        echo "Congratulations that you establish your server with real certificates."
        echo ""
        ;;

esac

##EOF##

Reply via email to