Generating Self-Signed Test Certificates Using One Single Shell Script

Generating Self-Signed Test Certificates Using One Single Shell Script


Looking at the title, you might say: "Not another openssl certificate generation guide!". I know, I know, but I promise that I will try to be different here.

Indeed, there are abundant resources available on how to use openssl to generate digital certificates and I have learned a lot from them. However, I don't think it is easy for all of us to memorize the complicated openssl command line syntax. A lot of times, all I need is to generate a new certificate and for that I just want to have something simple and straightforward that I can simply invoke without digging through old notes or googling for some guides.

To achieve that, I created a single shell script that is able to do three things and only three things:

  • Generating self-signed root CA certificates
  • Generating "client" certificate with XP client extension
  • Generating "server" certificate with XP server extension

The goal here is to make it as self-contained as possible: it only requires a functional openssl (and a /bin/sh of course) installed on the system. You don't even need to know where the openssl.cnf is or modify its content because it is all dynamically generated in the script itself. You don't need to create a separate XP extension file because it is in the script too.

Another goal is to make it as simple as possible: There are only 3 commands for the 3 things it does, each achieved in one step. You just need to type in all the fields of your certs as usual by following the prompt.

Before going to the script, I must disclaim that the certificates generated this way are intended for testing purposes only (for example, testing your wifi security configurations). Use it for any other purposes at your own risk.

The Script

Now the script itself. Due to lack of imagination, I call it certgen.

#!/bin/sh
#
# A script generates self-signed root CA cert/key and client/server certs with
# xp-extensions, using openssl.
# certs generated are for testing purposes only!
#
# Author: Gong Cheng, chengg11@yahoo.com, Aug. 2008
#
# You are free to use this script in anyway but absolutely no warranty!
#

usage ()
{
    echo "Usage:"
    echo "  certgen ca [<ca key> <ca cert>]"
    echo "  certgen client <ca key> <ca cert> [ <client key>  <client cert> ]"
    echo "  certgen server <ca key> <ca cert> [ <server key>  <server cert> ]"
}

gen_config ()
{
    echo "Generating ca_config.cnf"
    cat > ca_config.cnf <<EOT
HOME                    = .
RANDFILE                = $ENV::HOME/.rnd
[ ca ]
default_ca      = CA_default
[ CA_default ]
certs           = .
crl_dir         = .
database        = index.txt
new_certs_dir   = .
certificate     = $2
serial          = serial
private_key     = $1
RANDFILE        = .rand
x509_extensions = usr_cert
name_opt        = ca_default
cert_opt        = ca_default
default_days    = 365
default_crl_days= 30
default_md      = sha1
preserve        = no
policy          = policy_match
[ policy_match ]
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
[ policy_anything ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
[ req ]
default_bits            = 1024
default_md              = sha1
default_keyfile         = privkey.pem
distinguished_name      = req_distinguished_name
attributes              = req_attributes
x509_extensions = v3_ca
string_mask = MASK:0x2002
[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = GB
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = Berkshire
localityName                    = Locality Name (eg, city)
localityName_default            = Newbury
0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = My Company Ltd
organizationalUnitName          = Organizational Unit Name (eg, section)
commonName                      = Common Name (eg, your name or your server's hostname)
commonName_max                  = 64
emailAddress                    = Email Address
emailAddress_max                = 64
[ req_attributes ]
challengePassword               = A challenge password
challengePassword_min           = 4
challengePassword_max           = 20
unstructuredName                = An optional company name
[ usr_cert ]
basicConstraints=CA:FALSE
nsComment                       = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = CA:true
[xpclient_ext]
extendedKeyUsage = 1.3.6.1.5.5.7.3.2
[xpserver_ext]
extendedKeyUsage = 1.3.6.1.5.5.7.3.1
EOT
}

gen_ca ()
{
    echo "generating CA cert:$1, $2";
    openssl req -config ca_config.cnf -new -x509 -extensions v3_ca -days 3650 -passin pass:whatever -passout pass:whatever -keyout $1 -out $2
}

gen_client_cert ()
{
    echo "generating client cert:$1, $2";
    openssl req -config ca_config.cnf -new -nodes -keyout $1 -out temp.csr -days 3650

    openssl ca -config ca_config.cnf -policy policy_anything -out $2 -days 3650 -key whatever -extensions xpclient_ext -infiles temp.csr

    rm temp.csr
}

gen_server_cert ()
{
    echo "generating server cert:$1, $2";
    openssl req -config ca_config.cnf -new -nodes -keyout $1 -out temp.csr -days 3650

    openssl ca -config ca_config.cnf -policy policy_anything -out $2 -days 3650 -key whatever -extensions xpserver_ext -infiles temp.csr

    rm temp.csr
}

#at least one argument
if [ $# -lt 1 ]
then
    usage
    exit 1
fi


#default file names if not specified in command line
ca_key_file=cakey.pem
ca_cert_file=cacert.pem
client_key_file=client_key.pem
client_cert_file=client_cert.pem
server_key_file=server_key.pem
server_cert_file=server_cert.pem

case $1 in
ca)
    if [ x$2 != x ]
    then
        ca_key_file=$2
        ca_cert_file=$3
    fi
    gen_config $ca_key_file $ca_cert_file
    gen_ca $ca_key_file $ca_cert_file
    if [ -f $ca_key_file -a -f $ca_cert_file ]
    then
        echo "Generated files: key: $ca_key_file , cert: $ca_cert_file"
    else
        echo "Failed to generated all files"
    fi
    ;;
client)
    if [ $# -ne 3 -a $# -ne 5 ]
    then
        usage
        exit 1
    fi
    ca_key_file=$2
    ca_cert_file=$3
    gen_config $ca_key_file $ca_cert_file
    if [ x$4 != x ]
    then
        client_key_file=$4
        client_cert_file=$5
    fi
    if [ ! -f index.txt ]
    then
        touch index.txt
    fi

    if [ ! -f serial ]
    then
        echo 01 > serial
    fi
    gen_client_cert $client_key_file $client_cert_file
    if [ -f $client_key_file -a -f $client_cert_file ]
    then
        echo "Generated files: key: $client_key_file , cert: $client_cert_file"
    else
        echo "Failed to generated all files"
    fi
    if [ $client_cert_file != `cat serial.old`.pem ]
    then
        rm `cat serial.old`.pem
    fi
    ;;
server)
    if [ $# -ne 3 -a $# -ne 5 ]
    then
        usage
        exit 1
    fi
    ca_key_file=$2
    ca_cert_file=$3
    gen_config $ca_key_file $ca_cert_file
    if [ x$4 != x ]
    then
        server_key_file=$4
        server_cert_file=$5
    fi
    if [ ! -f index.txt ]
    then
        touch index.txt
    fi

    if [ ! -f serial ]
    then
        echo 01 > serial
    fi
    gen_server_cert $server_key_file $server_cert_file
    if [ -f $server_key_file -a -f $server_cert_file ]
    then
        echo "Generated files: key: $server_key_file , cert: $server_cert_file"
    else
        echo "Failed to generated all files"
    fi
    if [ $server_cert_file != `cat serial.old`.pem ]
    then
        rm `cat serial.old`.pem
    fi
    ;;
*) usage; exit 1;;
esac



#cleanups
rm ca_config.cnf

How To Use It?

Easy. Invoke certgen without any parameter, it gives you the usage:

$ ./certgen
Usage:
  certgen ca [<ca key> <ca cert>]
  certgen client <ca key> <ca cert> [ <client key>  <client cert> ]
  certgen server <ca key> <ca cert> [ <server key>  <server cert> ]

The generated file names are optional. If you don't specify them, the default file names generated are:

  • cacert.pem, the root CA certificate
  • cakey.pem, the root CA private key file, pass phrase "whatever"
  • client_cert.pem, the client certificate
  • client_key.pem, the client private key, pass phrase your choice
  • server_cert.pem, the server certificate
  • server_key.pem, the server private key, pass phrase your choice

Here is a sample run that should explain everything:

cheng@gong-ubuntu:~/tmp/certs$ ls
gcheng@gong-ubuntu:~/tmp/certs$ /home/gcheng/src/mine/cert/certgen ca mycakey.pem mycacert.pem
Generating ca_config.cnf
generating CA cert:mycakey.pem, mycacert.pem
Generating a 1024 bit RSA private key
.........++++++
.................++++++
unable to write 'random state'
writing new private key to 'mycakey.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) [GB]:US
State or Province Name (full name) [Berkshire]:California
Locality Name (eg, city) [Newbury]:San Jose
Organization Name (eg, company) [My Company Ltd]:test.com
Organizational Unit Name (eg, section) []:eng
Common Name (eg, your name or your servers hostname) []:eng root CA
Email Address []:eng_ca@test.com
Generated files: key: mycakey.pem , cert: mycacert.pem
gcheng@gong-ubuntu:~/tmp/certs$ ls
mycacert.pem  mycakey.pem
gcheng@gong-ubuntu:~/tmp/certs$ /home/gcheng/src/mine/cert/certgen client mycakey.pem mycacert.pem myclientkey.pem myclientcert.pem
Generating ca_config.cnf
generating client cert:myclientkey.pem, myclientcert.pem
Generating a 1024 bit RSA private key
.........................++++++
....................................................................++++++
unable to write 'random state'
writing new private key to 'myclientkey.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) [GB]:US
State or Province Name (full name) [Berkshire]:California
Locality Name (eg, city) [Newbury]:San Jose
Organization Name (eg, company) [My Company Ltd]:test.com
Organizational Unit Name (eg, section) []:eng
Common Name (eg, your name or your servers hostname) []:eng test client
Email Address []:eng_client@test.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:whatever
An optional company name []:test.com
Using configuration from ca_config.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Aug  7 19:51:58 2008 GMT
            Not After : Aug  5 19:51:58 2018 GMT
        Subject:
            countryName               = US
            stateOrProvinceName       = California
            localityName              = San Jose
            organizationName          = test.com
            organizationalUnitName    = eng
            commonName                = eng test client
            emailAddress              = eng_client@test.com
        X509v3 extensions:
            X509v3 Extended Key Usage:
                TLS Web Client Authentication
Certificate is to be certified until Aug  5 19:51:58 2018 GMT (3650 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
unable to write 'random state'
Generated files: key: myclientkey.pem , cert: myclientcert.pem
gcheng@gong-ubuntu:~/tmp/certs$ ls
index.txt       index.txt.old  mycakey.pem       myclientkey.pem  serial.old
index.txt.attr  mycacert.pem   myclientcert.pem  serial
gcheng@gong-ubuntu:~/tmp/certs$ /home/gcheng/src/mine/cert/certgen server mycakey.pem mycacert.pem myserverkey.pem myservercert.pem
Generating ca_config.cnf
generating server cert:myserverkey.pem, myservercert.pem
Generating a 1024 bit RSA private key
...........................++++++
........................................++++++
unable to write 'random state'
writing new private key to 'myserverkey.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) [GB]:US
State or Province Name (full name) [Berkshire]:California
Locality Name (eg, city) [Newbury]:San Jose
Organization Name (eg, company) [My Company Ltd]:test.com
Organizational Unit Name (eg, section) []:eng
Common Name (eg, your name or your servers hostname) []:eng test server
Email Address []:eng_server@test.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:whatever
An optional company name []:test.com
Using configuration from ca_config.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Aug  7 19:53:17 2008 GMT
            Not After : Aug  5 19:53:17 2018 GMT
        Subject:
            countryName               = US
            stateOrProvinceName       = California
            localityName              = San Jose
            organizationName          = test.com
            organizationalUnitName    = eng
            commonName                = eng test server
            emailAddress              = eng_server@test.com
        X509v3 extensions:
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
Certificate is to be certified until Aug  5 19:53:17 2018 GMT (3650 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
unable to write 'random state'
Generated files: key: myserverkey.pem , cert: myservercert.pem
gcheng@gong-ubuntu:~/tmp/certs$ ls
index.txt           index.txt.old  myclientcert.pem  myserverkey.pem
index.txt.attr      mycacert.pem   myclientkey.pem   serial
index.txt.attr.old  mycakey.pem    myservercert.pem  serial.old

Verification of the Certificates

You can use openssl to verify the validity of the certs and print the contents of the fields too. See below:

gcheng@gong-ubuntu:~/tmp/certs$ openssl verify -CAfile mycacert.pem myclientcert.pem myservercert.pem
myclientcert.pem: OK
myservercert.pem: OK
gcheng@gong-ubuntu:~/tmp/certs$ openssl x509 -text -in mycacert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            f2:ed:cf:36:05:b2:91:31
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=US, ST=California, L=San Jose, O=test.com, OU=eng, CN=eng root CA/emailAddress=eng_ca@test.com
        Validity
            Not Before: Aug  7 19:50:15 2008 GMT
            Not After : Aug  5 19:50:15 2018 GMT
        Subject: C=US, ST=California, L=San Jose, O=test.com, OU=eng, CN=eng root CA/emailAddress=eng_ca@test.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:c5:f3:d7:ad:18:ca:07:0e:1d:4a:19:52:e3:ab:
                    93:6f:dd:dd:74:1a:4b:c4:9d:57:8c:60:ec:db:bc:
                    53:b8:94:27:41:78:2b:07:56:9b:66:0b:25:a7:37:
                    13:90:ee:63:2f:8f:5a:6d:a6:f2:a1:fd:ce:28:b3:
                    d1:cb:35:1a:00:cb:7e:5a:f8:a3:44:4b:bc:75:63:
                    f4:04:2e:95:4e:6a:2a:16:27:ca:1d:b1:85:ce:79:
                    53:dd:32:a1:fb:02:25:fe:d1:79:68:51:9c:d1:b6:
                    bc:c2:dc:21:33:32:88:97:07:10:d6:52:65:84:1a:

                    d3:e5:fb:a5:de:2a:05:14:d9
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                7C:00:6A:A9:AB:52:C8:CE:39:65:1B:AF:7C:CF:13:E4:6E:2E:D4:72
            X509v3 Authority Key Identifier:
                keyid:7C:00:6A:A9:AB:52:C8:CE:39:65:1B:AF:7C:CF:13:E4:6E:2E:D4:72
                DirName:/C=US/ST=California/L=San Jose/O=test.com/OU=eng/CN=eng root CA/emailAddress=eng_ca@test.com
                serial:F2:ED:CF:36:05:B2:91:31

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: sha1WithRSAEncryption
        9b:30:4f:61:bd:b1:d9:0b:a0:56:b8:77:5a:08:e6:d2:a6:80:
        13:0b:aa:2d:f5:1e:d1:5f:4e:b2:59:9a:ad:d3:b3:a2:11:8e:
        a1:51:e5:6b:f3:d4:b1:94:d3:9a:ba:43:04:d9:48:dc:d1:c2:
        e9:25:27:81:44:54:1f:bc:7f:2e:44:26:2f:f2:7e:46:ad:26:
        f3:21:47:1b:20:9b:50:61:f7:ae:41:54:8d:e6:41:72:77:4d:
        d0:29:2a:16:56:2a:df:f0:f9:19:2c:19:e6:1d:67:a7:ed:d7:
        6a:49:66:9a:d4:25:1d:36:0f:0a:89:f1:b5:e5:5c:63:e1:c3:
        d5:b3
-----BEGIN CERTIFICATE-----
MIIDjTCCAvagAwIBAgIJAPLtzzYFspExMA0GCSqGSIb3DQEBBQUAMIGMMQswCQYD
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2Ux
ETAPBgNVBAoTCHRlc3QuY29tMQwwCgYDVQQLEwNlbmcxFDASBgNVBAMTC2VuZyBy
b290IENBMR4wHAYJKoZIhvcNAQkBFg9lbmdfY2FAdGVzdC5jb20wHhcNMDgwODA3
MTk1MDE1WhcNMTgwODA1MTk1MDE1WjCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
CkNhbGlmb3JuaWExETAPBgNVBAcTCFNhbiBKb3NlMREwDwYDVQQKEwh0ZXN0LmNv
bTEMMAoGA1UECxMDZW5nMRQwEgYDVQQDEwtlbmcgcm9vdCBDQTEeMBwGCSqGSIb3
DQEJARYPZW5nX2NhQHRlc3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQDF89etGMoHDh1KGVLjq5Nv3d10GkvEnVeMYOzbvFO4lCdBeCsHVptmCyWnNxOQ
7mMvj1ptpvKh/c4os9HLNRoAy35a+KNES7x1Y/QELpVOaioWJ8odsYXOeVPdMqH7
AiX+0XloUZzRtrzC3CEzMoiXBxDWUmWEGtPl+6XeKgUU2QIDAQABo4H0MIHxMB0G
A1UdDgQWBBR8AGqpq1LIzjllG698zxPkbi7UcjCBwQYDVR0jBIG5MIG2gBR8AGqp
q1LIzjllG698zxPkbi7UcqGBkqSBjzCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
CkNhbGlmb3JuaWExETAPBgNVBAcTCFNhbiBKb3NlMREwDwYDVQQKEwh0ZXN0LmNv
bTEMMAoGA1UECxMDZW5nMRQwEgYDVQQDEwtlbmcgcm9vdCBDQTEeMBwGCSqGSIb3
DQEJARYPZW5nX2NhQHRlc3QuY29tggkA8u3PNgWykTEwDAYDVR0TBAUwAwEB/zAN
BgkqhkiG9w0BAQUFAAOBgQCbME9hvbHZC6BWuHdaCObSpoATC6ot9R7RX06yWZqt
07OiEY6hUeVr89SxlNOaukME2Ujc0cLpJSeBRFQfvH8uRCYv8n5GrSbzIUcbIJtQ
YfeuQVSN5kFyd03QKSoWVirf8PkZLBnmHWen7ddqSWaa1CUdNg8KifG15Vxj4cPV
sw==
-----END CERTIFICATE-----
gcheng@gong-ubuntu:~/tmp/certs$ openssl x509 -text -in myclientcert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=US, ST=California, L=San Jose, O=test.com, OU=eng, CN=eng root CA/emailAddress=eng_ca@test.com
        Validity
            Not Before: Aug  7 19:51:58 2008 GMT
            Not After : Aug  5 19:51:58 2018 GMT
        Subject: C=US, ST=California, L=San Jose, O=test.com, OU=eng, CN=eng test client/emailAddress=eng_client@test.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:91:96:8d:69:88:6d:a3:80:b4:6b:d0:07:3c:1b:
                    2e:5a:dc:9f:fe:ec:9b:3b:ed:83:b6:95:98:f4:26:
                    45:ab:63:1b:76:a3:9b:bb:f0:a3:aa:1f:7d:53:72:
                    05:bb:ac:ff:c0:58:f6:47:8b:ef:fe:4f:e5:01:cb:
                    3c:10:51:52:78:ec:ec:8f:5b:df:c8:f0:d3:96:f0:
                    84:d9:5a:88:81:9c:fb:c9:09:b2:18:1d:d8:55:97:
                    ab:77:8a:b9:26:07:c6:f7:13:47:37:20:6b:78:f8:
                    f5:40:3b:0d:5f:b8:1d:b3:7b:a1:3e:19:bd:31:01:
                    0d:09:69:d7:16:dc:3e:7c:37
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Extended Key Usage:
                TLS Web Client Authentication
    Signature Algorithm: sha1WithRSAEncryption
        5d:36:31:22:5a:4b:ca:cf:de:26:72:8b:e9:5c:b7:01:97:53:
        02:c7:02:70:cc:39:a5:f0:2e:96:8a:0c:53:99:bf:f8:2d:c9:
        d2:f3:4f:31:fa:0d:87:b0:85:4b:03:fa:1e:09:34:7e:80:60:
        59:f5:24:4b:75:ba:c2:ed:df:d6:b2:85:c3:e3:69:df:b9:66:
        de:09:83:3c:36:82:ad:96:47:0c:26:d6:af:ad:74:c6:95:2b:
        48:76:2f:6b:49:4f:50:f5:28:ac:50:00:e5:cf:01:74:a8:01:
        71:ba:c8:69:41:11:62:5a:b3:e4:ac:45:cf:aa:9e:9a:0c:e3:
        aa:8f
-----BEGIN CERTIFICATE-----
MIICrzCCAhigAwIBAgIBATANBgkqhkiG9w0BAQUFADCBjDELMAkGA1UEBhMCVVMx
EzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCFNhbiBKb3NlMREwDwYDVQQK
Ewh0ZXN0LmNvbTEMMAoGA1UECxMDZW5nMRQwEgYDVQQDEwtlbmcgcm9vdCBDQTEe
MBwGCSqGSIb3DQEJARYPZW5nX2NhQHRlc3QuY29tMB4XDTA4MDgwNzE5NTE1OFoX
DTE4MDgwNTE5NTE1OFowgZQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y
bmlhMREwDwYDVQQHEwhTYW4gSm9zZTERMA8GA1UEChMIdGVzdC5jb20xDDAKBgNV
BAsTA2VuZzEYMBYGA1UEAxMPZW5nIHRlc3QgY2xpZW50MSIwIAYJKoZIhvcNAQkB
FhNlbmdfY2xpZW50QHRlc3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQCRlo1piG2jgLRr0Ac8Gy5a3J/+7Js77YO2lZj0JkWrYxt2o5u78KOqH31TcgW7
rP/AWPZHi+/+T+UByzwQUVJ47OyPW9/I8NOW8ITZWoiBnPvJCbIYHdhVl6t3irkm
B8b3E0c3IGt4+PVAOw1fuB2ze6E+Gb0xAQ0JadcW3D58NwIDAQABoxcwFTATBgNV
HSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQUFAAOBgQBdNjEiWkvKz94mcovp
XLcBl1MCxwJwzDml8C6WigxTmb/4LcnS808x+g2HsIVLA/oeCTR+gGBZ9SRLdbrC
7d/WsoXD42nfuWbeCYM8NoKtlkcMJtavrXTGlStIdi9rSU9Q9SisUADlzwF0qAFx
ushpQRFiWrPkrEXPqp6aDOOqjw==
-----END CERTIFICATE-----
gcheng@gong-ubuntu:~/tmp/certs$ openssl x509 -text -in myservercert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 2 (0x2)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=US, ST=California, L=San Jose, O=test.com, OU=eng, CN=eng root CA/emailAddress=eng_ca@test.com
        Validity
            Not Before: Aug  7 19:53:17 2008 GMT
            Not After : Aug  5 19:53:17 2018 GMT
        Subject: C=US, ST=California, L=San Jose, O=test.com, OU=eng, CN=eng test server/emailAddress=eng_server@test.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:9e:fa:d9:76:96:ee:19:cf:e3:95:b5:3a:2c:bf:
                    eb:af:77:0b:f9:29:7a:87:d2:e6:8d:66:44:49:b7:
                    fd:de:2f:f1:21:75:9f:82:7b:01:70:c7:33:48:ec:
                    4b:fb:12:6c:01:b2:39:4d:7d:10:d4:0d:d2:a6:76:
                    b3:51:0b:e9:1e:d3:c6:2e:c3:0d:a8:f7:69:38:96:
                    79:72:ec:93:17:bc:25:f8:61:64:d7:26:3d:84:36:
                    b5:78:a9:9d:25:c9:73:3c:0e:22:21:90:d7:2f:21:
                    b0:ee:cf:c9:55:fb:d8:d7:87:9e:18:0d:ee:97:22:
                    ae:82:0c:d4:d3:e1:bd:53:4f
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
    Signature Algorithm: sha1WithRSAEncryption
        0b:0c:e7:71:3d:66:4a:d1:43:1f:a4:3f:84:a5:af:0d:7e:74:
        7e:24:d9:13:64:28:27:31:f1:bf:ff:ed:a7:f6:9a:65:01:88:
        f8:1f:58:cc:b1:ba:26:8a:6e:0a:12:8c:a8:b8:09:0a:37:c8:
        41:e0:38:a4:fa:13:2b:9c:61:03:c3:3e:6e:e9:38:8b:f4:43:
        5a:8c:2c:54:87:ab:cc:96:71:b0:25:cd:75:fd:65:bc:7c:da:
        1b:df:db:60:6d:f6:73:5c:54:2e:46:85:bc:ed:d8:7d:cc:ed:
        6b:af:82:fc:45:01:4c:e1:c1:25:15:c2:c3:52:b5:0f:dd:df:
        5e:f0
-----BEGIN CERTIFICATE-----
MIICrzCCAhigAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBjDELMAkGA1UEBhMCVVMx
EzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCFNhbiBKb3NlMREwDwYDVQQK
Ewh0ZXN0LmNvbTEMMAoGA1UECxMDZW5nMRQwEgYDVQQDEwtlbmcgcm9vdCBDQTEe
MBwGCSqGSIb3DQEJARYPZW5nX2NhQHRlc3QuY29tMB4XDTA4MDgwNzE5NTMxN1oX
DTE4MDgwNTE5NTMxN1owgZQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y
bmlhMREwDwYDVQQHEwhTYW4gSm9zZTERMA8GA1UEChMIdGVzdC5jb20xDDAKBgNV
BAsTA2VuZzEYMBYGA1UEAxMPZW5nIHRlc3Qgc2VydmVyMSIwIAYJKoZIhvcNAQkB
FhNlbmdfc2VydmVyQHRlc3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQCe+tl2lu4Zz+OVtTosv+uvdwv5KXqH0uaNZkRJt/3eL/EhdZ+CewFwxzNI7Ev7
EmwBsjlNfRDUDdKmdrNRC+ke08Yuww2o92k4lnly7JMXvCX4YWTXJj2ENrV4qZ0l
yXM8DiIhkNcvIbDuz8lV+9jXh54YDe6XIq6CDNTT4b1TTwIDAQABoxcwFTATBgNV
HSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQALDOdxPWZK0UMfpD+E
pa8NfnR+JNkTZCgnMfG//+2n9pplAYj4H1jMsbomim4KEoyouAkKN8hB4Dik+hMr
nGEDwz5u6TiL9ENajCxUh6vMlnGwJc11/WW8fNob39tgbfZzXFQuRoW87dh9zO1r
r4L8RQFM4cElFcLDUrUP3d9e8A==
-----END CERTIFICATE-----

Explanation about client/server certificate

In theory, a certificate is a certificate, then why the difference between client and server certificate? Apparently, windows clients need that distinction. There is a extension called XP extension that does different things for "client" and "sever". Your windows laptop's EAP supplicant must use the "client" version of it (if it needs a certificate like in EAP-TLS) and its EAP peer/RADIUS server should use the server version of it. Otherwise, things might break. I know it will before but I haven't tried any lately.

Some Restrictions

To avoid bloating the command line syntax, I made a few restrictions:

  • The key-guard passphrase for root CA is hardcoded to "whatever" in the script
  • Due to the above hardcoded pass phrase, you can only use certgen to create client
  • Instead of asking the user how long should the certificates be valid, I hardcoded the expiration time to be 3650 days. Search for that number and you can change it.

Testing

I must admit that the script is still fresh. I haven't done extensive testing, but I have tried it on a few ubuntu and fc8 systems of mine and it worked fine. I also tried it using the eapol_test/freeradius interaction (see my post about this ) with EAP-TLS and the certs passed.

Category: 

Comments

Gong Cheng's picture
Submitted by Gong Cheng on

In the original script, even though it is asking for challenge password for client and server keys, it is not really encrypting the keys. It is ok just for testing purposes.

I have the following patch actually just to remove the redundant prompt part:

diff -upN certgen.saved certgen
--- certgen.saved 2008-08-27 16:02:47.000000000 -0700
+++ certgen 2008-08-27 16:43:00.000000000 -0700
@@ -62,7 +62,6 @@ default_bits = 1024
default_md = sha1
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
-attributes = req_attributes
x509_extensions = v3_ca
string_mask = MASK:0x2002
[ req_distinguished_name ]
@@ -81,11 +80,6 @@ commonName = Common Name (eg, your nam
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
-[ req_attributes ]
-challengePassword = A challenge password
-challengePassword_min = 4
-challengePassword_max = 20
-unstructuredName = An optional company name
[ usr_cert ]
basicConstraints=CA:FALSE
nsComment = "OpenSSL Generated Certificate"
@@ -195,7 +189,10 @@ client)
fi
if [ $client_cert_file != `cat serial.old`.pem ]
then
- rm `cat serial.old`.pem
+ if [ -f `cat serial.old`.pem ]
+ then
+ rm `cat serial.old`.pem
+ fi
fi
;;
server)
@@ -230,7 +227,10 @@ server)
fi
if [ $server_cert_file != `cat serial.old`.pem ]
then
- rm `cat serial.old`.pem
+ if [ -f `cat serial.old`.pem ]
+ then
+ rm `cat serial.old`.pem
+ fi
fi
;;
*) usage; exit 1;;

Author information

Gong Cheng's picture

Biography

I am a software developer in computer networking areas, living in California, United States. I worked on routers, switches and Wi-Fi access-points. I am a father of one baby boy. In the limited spare time I have, I like jogging and reading non-fiction books.