Originally posted to news groups:
       comp.infosystems.www.servers.unix, comp.os.linux.security,
       comp.infosystems.www.servers.ms-windows, comp.security.misc, comp.os.linux.help

Date: 09-Jan-2005
Subject: OpenSSL Apache self signed server certificates quickstart howto help with RSA DSA SSL TLS

I struggled for a while to get Apache 2 running with both RSA and DSA keys and self signed certificates. I've developed a little bash script that both documents the process and does it for you if you like. I wanted to share my results to hopefully save others the headache I had in gathering all this information and testing and tweaking until it all worked correctly.

Below are three scripts. First, makersa.sh, to generate RSA keys and certificate requests. Next, makedsa.sh, to generate DSA keys and cretificate requests. And last a slightly modified generic script from Ralf Engelschall to sign the certificates which is called by each of the first two scripts. All you need to do to create a complete set of RSA key/cert is "./makersa.sh" and similarly for DSA, "./makedsa.sh".

A copy of this article is archived at: http://john.masinter.net/pub/openssl.html
Hope this helps at least one person out there. Happy and secure web serving to all!


                              ,,,
                             (oo)
  ----------------------o0Oo-(_)-oO0o-----------------------
  |    John F. Masinter      Total Business Computing Inc. |
  | mailto:john@totalb.com        http://www.totalb.com    |
  |     P.O. Box 88584               Atlanta, GA 30356     |
  ------------------------ooO--Ooo--------------------------





#!/bin/bash
# 
# makersa.sh - make a RSA key and self-signed certificate for apache
#
# Author: John Masinter, john@totalb.com, 22-Dec-2003, 09-Jan-2005
#
# For addtl docs, see: http://www.modssl.org/docs/2.8/ssl_faq.html#ToC28 
# Disclaimer: This software is released "As is", without any warranty 
#             expressed nor implied, under the GPL-2 liscense.
#

SEP="======================================================================"
STEP=1

# all new files should be owned by root and "rw----", r/w root only!
umask 077

#----------------------------------------------------------------------
# wipe all files?
printf "Wipe all existing RSA keys and make new ones? [y/n]: "
read ans
if [ $ans == "y" ] ; then
   printf "\nRemoving all existing RSA keys.\n"
   echo "rm server-rsa* ca-rsa*"
   rm server-rsa* ca-rsa*
fi

#----------------------------------------------------------------------
KEY=server-rsa.key
printf "$SEP\nStep $STEP: create a private RSA server key.\n" ; STEP=$((STEP+1))
if [ -f $KEY ] ; then
   printf "RSA private server key '$KEY' already exists. Skipping.\n"
else
   printf "Creating an RSA private server key '$KEY'...\n"
   CMD="openssl genrsa -des3 -out $KEY 2048"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
   # show details
   CMD="openssl rsa -noout -text -in $KEY"
   printf "To see the details server key, do this: $CMD\n"
fi

#----------------------------------------------------------------------
CSR=server-rsa.csr
printf "$SEP\nStep $STEP: create a signing request for RSA server key.\n" ; STEP=$((STEP+1))
printf "\n***NOTE: COMMON NAME is the FQDN of server, e.g. www.totalb.com\n"
if [ -f $CSR ] ; then
   printf "Certificate Signing Request '$CSR' already exists. Skipping.\n"
else
   printf "Creating an Certificate Signing Req '$CSR'...\n"
   CMD="openssl req -new -key $KEY -out $CSR"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
   # show details
   CMD="openssl req -noout -text -in $CSR"
   printf "To see the details of csr, do this: $CSR\n"
fi

#----------------------------------------------------------------------
CAKEY=ca-rsa.key
printf "$SEP\nStep $STEP: create a private key for our CA.\n" ; STEP=$((STEP+1))
printf "\n***NOTE: This key info must be different from the server key info!\n"
if [ -f $CAKEY ] ; then
   printf "RSA private key '$CAKEY' for our CA already exists. Skipping.\n"
else
   printf "Creating an RAS private key '$CAKEY' for our CA...\n"
   CMD="openssl genrsa -des3 -out $CAKEY 2048"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
   # show details
   CMD="openssl rsa -noout -text -in $CAKEY"
   printf "To see the details of your new key, do this: $CMD\n"
fi

#----------------------------------------------------------------------
CACRT=ca-rsa.crt
printf "$SEP\nStep $STEP: create a self-signed certificate for our CA.\n" ; STEP=$((STEP+1))
if [ -f $CACRT ] ; then
   printf "Self signed CA cert '$CACRT' already exists. Skipping.\n"
else
   printf "Creating an 3 year self signed CA cert '$CACRT'...\n"
   CMD="openssl req -new -x509 -days 1095 -key $CAKEY -out $CACRT"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
   # show details
   printf "To see the details of your new key, do this:\n"
   CMD="openssl x509 -noout -text -in $CACRT"
   echo "$CMD"
fi

#----------------------------------------------------------------------
# input CSR output CRT
CRT=server-rsa.crt
printf "$SEP\nStep $STEP: create a self-signed certificate for our server.\n" ; STEP=$((STEP+1))
if [ -f $CRT ] ; then
   printf "Self signed server cert '$CRT' already exists. Skipping.\n"
else
   printf "Creating an self signed server cert '$CRT'...\n"
   CMD="./sign.sh $CSR"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
fi

#----------------------------------------------------------------------
# this is needed so apache will start-up without typing in pass phrase
CLR=server-rsa.key.clr
ORG=server-rsa.key.org
printf "$SEP\nStep $STEP: create unencrypted server key.\n" ; STEP=$((STEP+1))
if [ -f $CLR ] ; then
   printf "Unencrypted server key '$CLR' already exists. Skipping.\n"
else
   printf "Creating an unencrypted server key '$CLR'...\n"
   # make copy of original key as .org
   CMD="mv $KEY $ORG"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
   # unencrypt into .clr
   CMD="openssl rsa -in $ORG -out $CLR"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
   # chmod
   #CMD="chmod 400 $CLR"
   #echo "$CMD"
   #$CMD
   #if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
   # link to key name
   CMD="ln -s $CLR $KEY"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
fi

#----------------------------------------------------------------------
printf "\n\n*** NOTE: Make sure all files are rw---- (e.g. ug-rwx)\n\n"
exit 0

 
 

#!/bin/bash
# 
# makedsa.sh - make a DSA key and self-signed certificate for apache
#
# Author: John Masinter, john@totalb.com, 09-Jan-2005
#
# For addtl docs, see: http://www.modssl.org/docs/2.8/ssl_faq.html#ToC28 
# Disclaimer: This software is released "As is", without any warranty 
#             expressed nor implied, under the GPL-2 liscense.
#

SEP="======================================================================"
STEP=1

# all new files should be owned by root and "rw----", r/w root only!
umask 077

#----------------------------------------------------------------------
# wipe all files?
printf "Wipe all existing DSA keys and make new ones? [y/n]: "
read ans
if [ $ans == "y" ] ; then
   printf "\nRemoving all existing DSA keys.\n"
   echo "rm server-dsa* ca-dsa*"
   rm server-dsa* ca-dsa*
fi

#----------------------------------------------------------------------
PEM=server-dsa.pem
printf "$SEP\nStep $STEP: create a DSA param file '$PEM'.\n" ; STEP=$((STEP+1))
if [ -f $PEM ] ; then
   printf "DSA param file '$PEM' already exists. Skipping.\n"
else
   # create the DSA param file
   printf "Creating a DSA parameter file '$PEM'...\n"
   CMD="openssl dsaparam -outform PEM -out $PEM 2048"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
   # show details
   CMD="openssl dsaparam -noout -text -in $DSAPEM"
   printf "To see the details of pem, do this: $CMD\n"
fi

#----------------------------------------------------------------------
KEY=server-dsa.key
printf "$SEP\nStep $STEP: create a private DSA server key.\n" ; STEP=$((STEP+1))
if [ -f $KEY ] ; then
   printf "DSA private server key '$KEY' already exists. Skipping.\n"
else
   # create a DSA private key
   printf "Creating a DSA private server key '$KEY'...\n"
   CMD="openssl gendsa -out $KEY -aes256 $PEM"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
   # show details
   CMD="openssl dsa -noout -text -in $DSAKEY"
   printf "To see the details server key, do this: $CMD\n"
fi

#----------------------------------------------------------------------
CSR=server-dsa.csr
printf "$SEP\nStep $STEP: create a signing request for DSA server key.\n" ; STEP=$((STEP+1))
printf "\n***NOTE: COMMON NAME is the FQDN of server, e.g. www.totalb.com\n"
if [ -f $CSR ] ; then
   printf "Certificate Signing Request '$CSR' already exists. Skipping.\n"
else
   printf "Creating a Certificate Signing Req '$CSR'...\n"
   CMD="openssl req -new -key $KEY -out $CSR"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
   # show details
   CMD="openssl req -noout -text -in $CSR"
   printf "To see the details of csr, do this: $CMD\n"
fi

#----------------------------------------------------------------------
# this step should already be done makersa
CAKEY=ca-rsa.key
#printf "$SEP\nStep $STEP: create a private key for our CA.\n" ; STEP=$((STEP+1))

#----------------------------------------------------------------------
# this step should already be done makersa
CACRT=ca-rsa.crt
#printf "$SEP\nStep $STEP: create a self-signed certificate for our CA.\n" ; STEP=$((STEP+1))

#----------------------------------------------------------------------
# input CSR output CRT
CRT=server-dsa.crt
printf "$SEP\nStep $STEP: create a self-signed certificate for our server.\n" ; STEP=$((STEP+1))
if [ -f $CRT ] ; then
   printf "Self signed server cert '$CRT' already exists. Skipping.\n"
else
   printf "Creating an self signed server cert '$CRT'...\n"
   CMD="./sign.sh $CSR"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
fi

#----------------------------------------------------------------------
# this is needed so apache will start-up without typing in pass phrase
CLR=server-dsa.key.clr
ORG=server-dsa.key.org
printf "$SEP\nStep $STEP: create unencrypted server key.\n" ; STEP=$((STEP+1))
if [ -f $CLR ] ; then
   printf "Unencrypted server key '$CLR' already exists. Skipping.\n"
else
   printf "Creating an unencrypted server key '$CLR'...\n"
   # make copy of original key as .org
   CMD="mv $KEY $ORG"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
   # unencrypt into .clr
   CMD="openssl dsa -in $ORG -out $CLR"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
   # link to key name
   CMD="ln -s $CLR $KEY"
   echo "$CMD"
   $CMD
   if [ $? -ne 0 ] ; then printf "Failure: $? \n" ; exit 1 ; fi
fi

#----------------------------------------------------------------------
printf "\n\n*** NOTE: Make sure all files are rw---- (e.g. ug-rwx)\n\n"
exit 0


 
 

#!/bin/bash
#
#  sign.sh -- Sign a SSL Certificate Request (CSR)
#  Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved. 
#
#  Very slightly modified by John Masinter  2003
#

# NOTE: This is the basename for CA files
CANAME=ca-rsa

# print usage if needed
CSR=$1
if [ $# -ne 1 ]; then
    echo "Usage: sign.sh .csr"; exit 1
fi

# check for input file
if [ ! -f $CSR ]; then
    echo "CSR not found: $CSR"; exit 1
fi

# format output file name
case $CSR in
   *.csr ) CERT="`echo $CSR | sed -e 's/\.csr/.crt/'`" ;;
       * ) CERT="$CSR.crt" ;;
esac

# create temp dirs and files
if [ ! -d ca.db.certs ]; then
    mkdir ca.db.certs
fi

if [ ! -f ca.db.serial ]; then
    echo '01' >ca.db.serial
fi

if [ ! -f ca.db.index ]; then
    cp /dev/null ca.db.index
fi

#   create an own SSLeay config
cat >ca.config < $CERT:"
echo "openssl ca -config ca.config -out $CERT -infiles $CSR"
openssl ca -config ca.config -out $CERT -infiles $CSR

# did it work?
if [ $? -eq 0 ] ; then
   echo "CA verifying: $CERT <-> CA cert"
   echo "openssl verify -CAfile $CANAME.crt $CERT"
   openssl verify -CAfile $CANAME.crt $CERT
else
   echo "Error: Something went wrong. RC = $?"
fi

#  cleanup after SSLeay 
rm -f ca.config
rm -rf ca.db.* 

#  die gracefully
exit 0