
		Local Certificate Authority Setup
                =================================

                 Parakram Khandpur, IITD, India 
  	            parakram@iitd.ernet.in 


Instructions for setting up a local CA (Certificate Authority),
generating certificates and setting up secure Apache webserver. 

OpenSSL is a cryptography toolkit implementing the Secure Sockets
Layer (SSL v2/v3) and Transport Layer Security (TLS v1) network
protocols and related cryptography standards required by them. The
openssl program is a command line tool for using the various
cryptography functions of OpenSSL's crypto library from the shell. It
can be used for:


      * Creation of RSA, DH and DSA key parameters
      * Creation of X.509 certificates, CSRs and CRLs
      * Calculation of Message Digests
      * Encryption and Decryption with Ciphers
      * SSL/TLS Client and Server Tests
      * Handling of S/MIME signed or encrypted mail


Setup
------

Using the CA.pl perl script supplied with OpenSSL one can setup a CA. A 
sample configuration file openssl.cnf is included at the end of this 
document.

      $/usr/share/ssl/misc/CA.pl -newca

      CA certificate filename (or enter to create)
      press Enter
      Making CA certificate ...
      Using configuration from /usr/share/ssl/openssl.cnf
      Generating a 1024 bit RSA private key
      ........++++++
      ..............................++++++
      writing new private key to './demoCA/private/cakey.pem'
      Enter PEM pass phrase: enter a pass phrase
      Verifying password - Enter PEM pass phrase: enter a pass phrase
      -----
      You are about to be asked to enter information that will be incorporated
      into your certificate request.
      What you are about to enter is what is called a Distinguished Name or a DN.
      There are quite a few fields but you can leave some blank
      For some fields there will be a default value,
      If you enter '.', the field will be left blank.
      -----
      Country Name (2 letter code) [AU]: US
      State or Province Name (full name) [Some-State]: CA
      Locality Name (eg, city) []: LA
      Organization Name (eg, company) [Internet Widgits Pty Ltd]: XYZ
      Organizational Unit Name (eg, section) []: ABC
      Common Name (eg, your name or your server's hostname) []: MY_LOCAL_CA
      Email Address []: ca@some_domain.com

This would create a new directory hierarchy called demoCA within which
are a few other files and directories. The CA private key and the CA
certificate files are in a format known as PEM: ASN1 DER data that has
been optionally encrypted (using a DES3 cipher by default) and MIME
base64 encoded with headers and footers added.

To view the information in the CA certificate (demoCA/cacert.pem) :

      $ openssl x509 -text -noout -in demoCA/cacert.pem

To view the information in the private key file (demoCA/cacert.pem) :

      $ openssl rsa -text -noout -in demoCA/private/cakey.pem

You'll need to enter the PEM pass phrase to decrypt the private key
file.


Certificates 
------------


Generating certificates signed by the local CA: 

   o Generating an RSA key
   
      A RSA key can be used both for encryption and for signing. The
      following command generates a password protected 1024 bit RSA
      key.

            openssl genrsa -des3 -out server_key.pem 1024

      If you don't want your key to be protected by a password, remove
      the flag '-des3' from the command line above.If you intend to
      use the key together with a server certificate, it may be a good
      thing to avoid protecting it with a password, since that would
      mean someone would have to type in the password every time the
      server needs to access the key.

    o Creating a Certificate Request
    
      Now using the RSA key, we generate a Certificate Request which
      would be provided to the CA for generating the CA signed
      certificate based on it. The main feature of note is that the
      Common Name field should be set to the fully qualified domain
      name of your machine (the server) as your clients would see it

            openssl req -new -key server_key.pem -out newreq.pem

            You are about to be asked to enter information that will be incorporated
            into your certificate request.
            What you are about to enter is what is called a Distinguished Name or a DN.
            There are quite a few fields but you can leave some blank
            For some fields there will be a default value,
            If you enter '.', the field will be left blank.
            -----
            Country Name (2 letter code) [AU]: US
            State or Province Name (full name) [Some-State]: Your State
            Locality Name (eg, city) []: Your City
            Organization Name (eg, company) [Internet Widgits Pty Ltd]: Your Company Name
            Organizational Unit Name (eg, section) []: Your Group Name
            Common Name (eg, your name or your server's hostname) []: your server's fully qualified domain name
            Email Address []: webmaster@yourdomain.com
            Please enter the following 'extra' attributes
            to be sent with your certificate request
            A challenge password []: Press enter
            An optional company name []: Press enter

    o CA generates certificate for server in response to Certificate Request
    
      We use CA.pl for signing. It looks for a file newreq.pem and
      writes the signed certificate to newcert.pem.

            $./CA.pl -sign

            Using configuration from /usr/share/ssl/openssl.cnf
            Enter pass phrase for ./demoCA/private/cakey.pem: Enter Pass phrase for CA's RSA Key
            Check that the request matches the signature
            Signature ok
            Certificate Details:
            Serial Number: 2 (0x2)
            Validity
            Not Before: Jun 30 23:44:44 2004 GMT
            Not After : Jun 30 23:44:44 2005 GMT
            Subject:
            countryName = IN
            stateOrProvinceName = Your State
            localityName = Your City
            organizationName = Your Company Name
            organizationalUnitName = Your Group
            commonName = your server's fully qualified domain name
            emailAddress = webmaster@yourdomain.com
            X509v3 extensions:
            X509v3 Basic Constraints:
            CA:FALSE
            Netscape Comment:
            OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
            5F:6B:14:F5:D6:CB:D7:F2:67:52:0A:F6:9A:A5:98:D1:5C:0F:1A:17
            X509v3 Authority Key Identifier:
            keyid:D7:8D:E5:DC:93:A1:6D:6E:D2:56:59:1A:77:81:E6:6F:93:58:9F:AA
            DirName:/C=US/ST=CA/L=LA/O=ABC/OU=XYZ/CN=MY_LOCAL_CA/emailAddress=ca@some_domain.com
            serial:00
            Certificate is to be certified until Jun 30 23:44:44 2005 GMT (365 days)
            Sign the certificate? [y/n]: y
            1 out of 1 certificate requests certified, commit? [y/n]: y
            Write out database with 1 new entries
            Data Base Updated
            Signed certificate is in newcert.pem


Notes:

      1. One could generate a self-signed certificate for testing purposes as follows:
    
            openssl req -x509 -in newreq.pem -key server_key.pem -out \
            newcert.pem -days 10

      2. For generating certificates for a user (client) the steps are
         exactly same. Generally, the certificate and key are combined
         into one file in pk12 format and can then be stored on
         devices like USB tokens or imported into the user's web
         browser

                openssl pkcs12 -export -in user_cert.pem -inkey user_key.pem -out user_cert+key.pk12


Apache Setup
------------

The configuration is being done on Apache 2.0.49-4 which uses the
mod_ssl.o module to provide the SSL functionality. In this Apache No
changes are needed to the default httpd.conf that is avaialble in
/etc/httpd/confs/. The changes required in the ssl.conf which is
available in /etc/httpd/conf.d/ are as follows:

     1. For setting up only server authentication, we need to specify
        the location of the RSA key and the X.509 certificate for the
        server in ssl.conf

                 SSLCertificateKeyFile /etc/httpd/conf/ssl.key/server.key
                 SSLCertificateFile /etc/httpd/conf/ssl.crt/server.crt

     2. For setting up mutual authentication between client and
        server, in addition to previous directives in ssl.conf, we
        need to specify in ssl.conf to enable client authentication
        and also provide a file or path for the certificates of the
        CAs against whom the client would be authenticated. We need to
        specify the location of the RSA key and the X.509 certificate
        for the server in ssl.conf

                 SSLCACertificateFile /etc/httpd/conf/ssl.crt/CAcert.pem
                 SSLVerifyClient require
                 SSLVerifyDepth 2


Example openssl.cnf
-------------------
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#

# This definition stops the following lines choking if HOME isn't
# defined.
HOME			= .
RANDFILE		= $ENV::HOME/.rnd

# Extra OBJECT IDENTIFIER info:
#oid_file		= $ENV::HOME/.oid
oid_section		= new_oids

# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions		= 
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)

[ new_oids ]

# We can add new OIDs in here for use by 'ca' and 'req'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6

####################################################################
[ ca ]
default_ca	= CA_default		# The default ca section

####################################################################
[ CA_default ]

dir		= ./demoCA		# Where everything is kept
certs		= $dir/certs		# Where the issued certs are kept
crl_dir		= $dir/crl		# Where the issued crl are kept
database	= $dir/index.txt	# database index file.
new_certs_dir	= $dir/newcerts		# default place for new certs.

certificate	= $dir/cacert.pem 	# The CA certificate
serial		= $dir/serial 		# The current serial number
crl		= $dir/crl.pem 		# The current CRL
private_key	= $dir/private/cakey.pem# The private key
RANDFILE	= $dir/private/.rand	# private random number file

x509_extensions	= usr_cert		# The extentions to add to the cert

# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt 	= ca_default		# Subject Name options
cert_opt 	= ca_default		# Certificate field options

# Extension copying option: use with caution.
# copy_extensions = copy

# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crl_extensions	= crl_ext

default_days	= 365			# how long to certify for
default_crl_days= 30			# how long before next CRL
default_md	= md5			# which md to use.
preserve	= no			# keep passed DN ordering

# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy		= policy_match

# For the CA policy
[ policy_match ]
countryName		= match
stateOrProvinceName	= match
organizationName	= match
organizationalUnitName	= optional
commonName		= supplied
emailAddress		= optional

# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName		= optional
stateOrProvinceName	= optional
localityName		= optional
organizationName	= optional
organizationalUnitName	= optional
commonName		= supplied
emailAddress		= optional

####################################################################
[ req ]
default_bits		= 1024
default_keyfile 	= privkey.pem
distinguished_name	= req_distinguished_name
attributes		= req_attributes
x509_extensions	= v3_ca	

# The extentions to add to the self signed cert

# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret

# This sets a mask for permitted string types. There are several options. 
# default: PrintableString, T61String, BMPString.
# pkix	 : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
string_mask = nombstr

# req_extensions = v3_req # The extensions to add to a certificate request

[ req_distinguished_name ]
countryName			= Country Name (2 letter code)
countryName_default		= AU
countryName_min			= 2
countryName_max			= 2

stateOrProvinceName		= State or Province Name (full name)
stateOrProvinceName_default	= Some-state

localityName			= Locality Name (eg, city)
localityName_default		= Some-city

0.organizationName		= Organization Name (eg, company)
0.organizationName_default	= Internet Widgits Pty Ltd

# we can do this but it is not needed normally :-)
#1.organizationName		= Second Organization Name (eg, company)
#1.organizationName_default	= World Wide Web Pty Ltd

organizationalUnitName		= Organizational Unit Name (eg, section)
#organizationalUnitName_default	=

commonName			= Common Name (eg, your name or your server\'s hostname)
commonName_max			= 64

emailAddress			= Email Address
emailAddress_max		= 64

# SET-ex3			= SET extension number 3

[ req_attributes ]
challengePassword		= A challenge password
challengePassword_min		= 4
challengePassword_max		= 20

unstructuredName		= An optional company name

[ usr_cert ]

# These extensions are added when 'ca' signs a request.

# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.

basicConstraints=CA:FALSE

# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.

# This is OK for an SSL server.
# nsCertType			= server

# For an object signing certificate this would be used.
# nsCertType = objsign

# For normal client use this is typical
# nsCertType = client, email


# and for everything including object signing:
# nsCertType = client, email, objsign

# enable everything
nsCertType = server, client, email, objsign

# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# This will be displayed in Netscape's comment listbox.
nsComment			= "OpenSSL Generated Certificate"

# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always

# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move

# Copy subject details
# issuerAltName=issuer:copy

#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName

[ v3_req ]

# Extensions to add to a certificate request

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

[ v3_ca ]


# Extensions for a typical CA


# PKIX recommendation.

subjectKeyIdentifier=hash

authorityKeyIdentifier=keyid:always,issuer:always

# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true

# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign

# Some might want this also
# nsCertType = sslCA, emailCA

# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy

# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF

[ crl_ext ]

# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.

# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always
