Dominique Quatravaux

NAME

make-cert-chain.pl - Make an RSA X509 certificate chain using Crypt::OpenSSL::CA

DESCRIPTION

This example code walks the reader through using Crypt::OpenSSL::CA to create X509 certificates. We demonstrate creating a self-signed Certification Authority (CA) certificate, and a user certificate signed by that CA. Both are printed to standard output as text strings in "PEM" in Crypt::OpenSSL::CA::AlphabetSoup format.

CA SELF-SIGNATURE

Private Key

Crypt::OpenSSL::CA doesn't create private keys by itself, but the openssl command-line tool can whip them up presto. For additional style points, let's say the CA's key is to be password-protected.

Certificate

The CA certificate is filled out field after field, starting with the RSA public key.

"DN" in Crypt::OpenSSL::CA::AlphabetSoups can be provided literally; simply be careful to the DN order.

Note that we need to set some extensions for that CA certificate in order for it to be standards-compliant; see Crypt::OpenSSL::CA::Resources if you are new to that whole shebang.

Okay, we don't really need key identifiers for standards compliance; they're just here because it's fun to copy them over to the client certificate later on.

Sign it, and the certificate is ready!

USER CERTIFICATE SIGNING REQUEST

We are going to play by the rules, and generate the user's certificate from public data only; here, using a PKCS#10 Certificate Signing Request ("CSR" in Crypt::OpenSSL::CA::AlphabetSoup; "SPKAC" in Crypt::OpenSSL::CA::AlphabetSoup is also supported). Again Crypt::OpenSSL::CA cannot fabricate PKCS#10's directly, but you could create one with something like

  openssl req -nodes -batch -newkey rsa:1024 -keyout userkey.pem -out user.p10

Standards-savvy readers know that PKCS#10 requests can contain other fields than the public key. However, Crypt::OpenSSL::CA ignores them entirely.

USER CERTIFICATE CREATION

In a real PKI this would probably not take place in the same process as the "CA SELF-SIGNATURE" step. So let's pretend that we are reloading from serialized state (ie PEM strings) instead of re-using the objects created above. (To keep ourselves honest, we used curly braces in the Perl script to segregate both signing operations into different lexical scopes.)

In order for the user certificate and the CA certificate to chain properly, certain fields in the latter must match those in the former. Crypt::OpenSSL::CA supports enough of X509 parsing that we are able to extract those from an existing PEM certificate.

Certificate Fields and Extensions

This time, let'use a Christmas-treeish set of extensions to demonstrate the possibilities of the API. For the X509-savvy, here is some babble about what Crypt::OpenSSL::CA can do: the X509 version is always X509v3. Long serial numbers are supported. DNs enjoy full UTF-8 support. The validity period (notBefore and notAfter) can be of arbitrary size, and transition from utcTime to generalizedTime is handled properly. SubjectAltNames are fully supported regardless of type and multiplicity; ditto for certificate policies. The signature algorithm is RSA and the hash can be set to any of OpenSSL's supported hashes. OpenSSL's algorithm for RSA key fingerprints (also known as X509 KeyIDs) is available (but not mandatory) for the subject and authority key identifiers.