Search code examples
c++sslopensslqpidnss

QPID C++ Broker and QPID-CPP SSL Certificates


I am trying to set up SSL with QPID and I'm having trouble figuring out how to set up the certificates. I have made a certificate database and added a self signed certificate to it like so:

mkdir ${CERT_DIR}
certutil -N -d ${CERT_DIR} -f ${CERT_PW_FILE}
certutil -S -d ${CERT_DIR} -n ${NICKNAME} -s "CN=${NICKNAME}" -t "CT,," -x -f ${CERT_PW_FILE} -z /usr/bin/certutil

I then started the QPID C++ Broker, passing it the ${CERT_DIR}, the ${NICKNAME} and the ${CERT_PW_FILE}. The broker log tells me that the SSL listener is running on my port of choice.

However, I'm not sure what directory/certificate name I should give as environment variables when starting the QPID-CPP C++ client? I have tried passing the directory as ${CERT_DIR} and the certificate name as ${NICKNAME} but this doesn't seem to work; the QPID log prints the message:

**[System] error Error reading socket: SSL peer cannot verify your certificate [-12271].**

What is the correct procedure to set up a server and client certificate to use with QPID? It says it must be done using certutil.

Thanks


Solution

  • This works with QPID Proton 0.23.0 for the API and QPID CPP 1.38.0 for the C++ Broker.

    Text included in italics is for those who desire client authentication.

    I figured out how to do it with self signed certificates:

    1. Generate certificate database: certutil -N -d [db-directory].
    2. Generate CA certificate: certutil -S -s "CN=[ca-name]" -n [ca-name] -x -t "CTu,CTu,CTu" -1 -2 -5 -k rsa -d [db-directory].
    3. Generate server certificate: certutil -S -s "CN=[server-cert-name]" -n [server-cert-name] -c "[ca-name]" -t "u,u,u" -m [unique-serial-no] -d [db-directory].
    4. Similarly, generate client certificate: certutil -S -s "CN=[client-cert-name]" -n [client-cert-name] -c "[ca-name]" -t "u,u,u" -m [unique-serial-no] -d [db-directory].

    This generates the certificate database with the required certificates. Store the password used to create the certificate database in a file [password-file]. The QPID C++ Broker can then be started like so:

    [path-to-qpidd] --ssl-cert-password-file [password-file] --ssl-cert-db [db-directory] --ssl-cert-name [server-cert-name]
    

    If you also require client authentication, pass the flag --ssl-require-client-authentication.

    In order to use the QPID Proton C++ client to connect via SSL, we must export our server certificate as a .pem file and our client certificate as a cert.pem and a key.pem file:

    1. Export our server and client certificates as .p12 files: pk12util -o [client/server].p12 -d [db-directory] -n [client-cert-name/server-cert-name].
    2. Export the server certificate as a .pem file: openssl pkcs12 -in server.p12 -out server.pem -nodes.
    3. Export the client certificate as a certificate and a key .pem file:
      • Certificate: openssl pkcs12 -in client.p12 -clcerts -nokeys -out clientcert.pem.
      • Key: openssl pkcs12 -in client.p12 -nocerts -out clientkey.pem.

    These files can then be passed to the QPID Proton C++ API which will then be able to instantiate an SSL connection with the QPID broker.