Setting up TLS certificates using openssl for use with MQ.

The IBM tool iKeyman is limited to the attributes you can create in a certificate.  Certificates can have Authority Information Access (AIA) information in them.  This is a URL so that the application using the certificate can check that the certificate is still valid, and has not been revoked.  The IBM iKeyman does not support this, or other, attributes.

You can create certificates using openssl, and import them into an iKeyman key store.

This page gives the commands I used to set this up for some testing.

This link  has a very good post of how to set up certificates.   I followed it to produce most of the instructions in this article.

Wikipedia link to openssl definition.

Background to openssl configuration files

Openssl command use a configuration file.   This file contains default information such as

  • the location of certificates
  • Distinguished name parameters (and defaults)
  • attributes to be used (including the AIA)

As the Certificate authority is usually on a different machine to the requestor and user of certificates, I used two configuration files. If you are doing this one one machine, you could just use one configuration file.

A configuration file is divided into sections.   There may be pointers to other sections in the file for example

[ ca ]
default_ca = CA_default # The default ca section

this looks for a section called CA_default

[ CA_default ]
default_days = 1000 # How long to certify for

Some sections are used depending on the command being used. The openssl command req uses a section called [ req ].
You can specify additional sections to be used during a command.  So specifying -extention server_ext would include the definitions in

[server_ext]
authorityInfoAccess = OCSP;URI:http://F2222ocsp.my.host/

For the CA work I used openssl-ca.cnf.   For the server work I used openssl-server.cnf.

Steps to create the CA and certificates

The steps are

  1. create a directory ssl, and cd to it
  2. Copy the openssl-ca.cnf and openssl-server.cnf to the ssl directory
  3. Create a self signed certificate to act as a Certificate Authority
  4. Create some files for the CA to use when signing certificate requests
  5. Create an end user certificate request
  6. Use the CA certificate to sign the certificate request.
  7. import the certificates into the iKeyman keystore
  8. Display the signed certificate
  9. Display just the OCSP information from the certificate
  10. Start an OCSP server – not for production!

Create a Certificate Authority certificate

openssl req -x509 -config openssl-ca.cnf -newkey rsa:4096 -sha256 nodes -out cacert.pem -outform PEM

Within openssl-ca.cnf it has

[ ca ]
default_ca = CA_default # This points to the default ca section below

[ CA_default ]
base_dir = .
certificate = $base_dir/cacert.pem # The CA certifcate
private_key = $base_dir/cakey.pem # The CA private key

This generates files in the current directory ( base_dir = . )

CA certificate -rw——- 1 colinpaice colinpaice 3272 Jun 11 14:43 cakey.pem
ca private key -rw-r–r– 1 colinpaice colinpaice 2256 Jun 11 14:44 cacert.pem

You can now send the cacert.pem to the systems which need the CA certificate to validate certificates.

Print the CA certificate

Print it using

openssl x509 -in cacert.pem -text -noout

and see what you can do with it using

openssl x509 -purpose -in cacert.pem -inform PEM -nocert

To be able to sign certificates you need to set up some files
touch index.txt
echo '01' > serial.txt

Create an end user request

On the “server machine”,

openssl req -config openssl-server.cnf -newkey rsa:2048 -sha256  -out servercert.csr -outform PEM -keyout serverkey.pem

This uses parameters in the [ req ] section of the openssl-server.cnf.
This has

[ req ]
default_bits = 2048

default_keyfile = serverkey.pem #use this if
#  -keyout not specified
distinguished_name = server_distinguished_name 

req_extensions = server_req_extensions 
string_mask = utf8only

...

[ server_req_extensions ] 
subjectKeyIdentifier = hash

basicConstraints = CA:FALSE
keyUsage = digitalSignature,
keyEncipherment

nsComment = "OpenSSL Generated Certificate - Colin"
authorityInfoAccess = OCSP;URI:http://F3333.my.host/

and produces

private key … -rw——- 1 colinpaice colinpaice 1704 Jun 11 14:51 serverkey.pem
request           -rw-r–r– 1 colinpaice colinpaice 1399 Jun 11 14:51 servercert.csr

Note the .csr is for certificate request

Display the request file

openssl req -text -noout -verify -in servercert.csr gives

Netscape Comment:
OpenSSL Generated Certificate – Colin
Authority Information Access:
OCSP – URI:http://F3333.my.host/

Use the CA command to sign the certificate request.

Send this  .csr file to the CA machine.

openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out servercert.pem -infiles servercert.csr

In openssl-ca.cnfg it has a specified section

[ signing_req ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
authorityInfoAccess = OCSP;URI:http://F55555ocsp.my.host/

Display the signed certificate

Send the servercert.pem  file back to the requestor on the “server” machine.

The commands

openssl x509 -in servercert.pem -text -noout

gives

Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = GB, ST = Orkney, L = Stromness,…..
X509v3 Key Usage:
Digital Signature, Key Encipherment
Authority Information Access:
OCSP – URI:http://F55555ocsp.my.host/

It has the URL from the signer – because the certificate is revoked at the signer level.

Display just the ocsp uri information

The command

openssl x509 -in servercert.pem -noout -ocsp_uri

gives just http://F55555ocsp.my.host/

Export the end user certificate so it can be imported into iKeyman.

Use the command

openssl pkcs12 -export -out cert.p12 -inkey serverkey.pem -in servercert.pem

it prompts to create a password.

It creates a file called cert.p12.

iKeyman gui.

  1. export/import → import key
  2. key field type PKCS12
  3. file name…
  4. Location…
  5. enter password
  6. Change label

or use

/opt/mqm/java/jre64/jre/bin/ikeycmd -cert -import -target ../key.kdb -file cert.p12 -type pkcs12 -label 1 -new_label colincert

You can display it from the GUI or a command like

/opt/mqm/bin/runmqckm -cert -details -db key.kdb -pw zpassword -label Fromopenssltest

which gave output including

Extensions:
– AuthorityInfoAccess: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
[accessMethod: ocsp
accessLocation: URIName: http://127.0.0.1:8888/
]]

This AIA information came from the openssl config file for the CA, and the -extensions signing_req in the command, which pointed to the section to be used within the config file.

Add the CA certificate to the iKeyman keystore

After the CA certificate has been created,  it needs to be sent to all systems that need it to validate certificates that it has signed. You can use the iKeyman GUI, signer certificates, add, or a command like

/opt/mqm/java/jre64/jre/bin/ikeycmd -cert -add -db key.kdb -file ~/ssltest/cacert.pem -label opensslCACert

Test out OCSP by using an OCSP server.

This has a good example of setting up a test OCSP server, and validating a certificate.  I used it as the basis for the following section.

Create a certificate

openssl req -config openssl-server.cnf -newkey rsa:2048 -sha256 -out ocsp.csr -keyout ocsp.key -outform PEM

Sign it

openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out ocsp.pem -infiles ocsp.csr

Start simple OCSP server

openssl has a simple OCSP server which you can use to test and demonstrate certificate checking and revoking.  It should not be used for production work.

Run this on the machine where the CA was defined, as it uses the files from the CA.

openssl ocsp -index index.txt -port 8888 -rsigner cacert.pem -rkey cakey.pem -CA cacert.pem -text -out log.txt

It uses local host 127.0.0.1 by default

Issue a request to the OCSP server

Openssl has a command to validate a certificate for example, on the server machine, check the certificate for servercert.pem.

openssl ocsp -CAfile cacert.pem -issuer cacert.pem -cert servercert.pem -url http://127.0.0.1:8888 -resp_text

Timing the requests

If you use the linux time command for example

time openssl ocsp -CAfile cacert.pem -issuer cacert.pem -cert servercert.pem -url http://127.0.0.1:8888 -resp_text.

I got

….
Response verify OK
servercert.pem: good
real 0m0.040s

showing the request took 40 milliseconds.

Revoke a certificate

As a general rule, once a certificate is revoked, it cannot be unrevoked.

 

On the CA machine, you need to identify the certificate to revoke.

openssl x509 -in servercert.pem -noout -serial -subject

gave
serial=01
subject=C = GB, ST = Orkeny, L = Stromness, O = “Test Server, Limited”, CN = Test Server

check it is the right one, then  revoke it, and refresh the crl lists
openssl ca -config openssl-ca.cnf -revoke 01.pem
openssl ca -gencrl -config openssl-ca.cnf -out crl.pem

Output after a certificate has been revoked – I had in tail -n100 /var/mqm/errors/*1*
AMQ9633E: Bad SSL certificate for channel ‘QMA’.

EXPLANATION:
A certificate encountered during SSL handshaking is regarded as bad for one of
the following reasons:
(a) it was formatted incorrectly and could not be validated
(b) it was formatted correctly but failed validation against the Certification
Authority (CA) root and other certificates held on the local system
(c) it was found in a Certification Revocation List (CRL) on an LDAP server
(d) a CRL was specified but the CRL could not be found on the LDAP server
(e) an OCSP responder has indicated that it is revoked

The channel is ‘QMA’; in some cases its name cannot be determined and so is
shown as ‘????’. The remote host is ‘localhost (127.0.0.1)(1414)’. The channel
did not start.

The details of the certificate which could not be validated are
‘[Class=]GSKVALMethod::X509[Issuer=]EMAIL=test@example.com,CN=SSSCA,OU=Server
Research Department,O=SSS,L=Stromness,ST=Orkney,C=GB[#=]01[Subject=]CN=Test
Server,O=Test Server\, Limited,L=Stromness,ST=Orkeny,C=GB’.

The certificate validation error was 575032.

The [#=]01 is the serial number matching the revoke command above.

See Diagnostic improvements to MQ SSL/TLS error AMQ9633 for information about this message.
The validation error 575032 is documented here. It means The certificate is revoked.

On the CA machine, I reused the certificate request by re-signing it. Afterwards the command

openssl x509 -in servercert.pem -noout -serial -subject

gave
serial=04
subject=C = GB, ST = Orkeny, L = Stromness, O = “Test Server, Limited”, CN = Test Server

which is a new certificate (serial was 01, now 04).  This needs to be sent back to the requestor, and imported to the iKeyman keystore.