How to create a certification authority (CA) with openssl ================================================================== Author: Momchil Ivanov Date : 2013.04.17, 2018.10.29 Introduction ------------ This document explains how to create a certification authority (CA) using the software package OpenSSL. I will also explain how to issue and sign certificates. Creating CA using CA.pl ----------------------- The helper script CA.pl which is part of the openssl distribution is used here as well as the configuration file openssl.cnf. Both can be found in: /usr/src/crypto/openssl/apps/CA.pl /etc/ssl/openssl.cnf on FreeBSD. We copy these for convenience. The CA and all signed certificates will be saved under the directory demoCA. The directory demoCA-certs will hold the issued certificates and their keys. $ mkdir demoCA demoCA-certs $ cp /usr/src/crypto/openssl/apps/CA.pl . $ cp /etc/ssl/openssl.cnf demoCA/ Edit openssl.cnf to set default values for the fields there (Country, State, Email address, etc). Set the path to the openssl.cnf file in the OPENSSL_CONF variable. $ export OPENSSL_CONF=`pwd`/demoCA/openssl.cnf Create the certificate authority. $ ./CA.pl -newca Creating and signing a new certificate -------------------------------------- Set the domain name for the certificate: $ export DOMAIN=mail.xaxo.eu Create and sign the certificate: $ ./CA.pl -newreq $ ./CA.pl -sign Remove the password from the key file in order to use it with automated services, otherwise one has to type in the password every the the service is restarted: $ openssl rsa -in newkey.pem -out newkey2.pem Move the certificate and the key in demoCA-certs: $ mv newkey2.pem demoCA-certs/${DOMAIN}-key.pem $ mv newreq.pem demoCA-certs/${DOMAIN}-req.pem $ mv newcert.pem demoCA-certs/${DOMAIN}-cert.pem $ rm newkey.pem Creating and signing a new certificate for the web -------------------------------------------------- Some web browsers require the subjectAltName field instead of the commmonName. Edit openssl.cnf and add: [ san_env ] subjectAltName=${ENV::SAN} Then to load the san_env extension in openssl when using the CA.pl execute: $ export SSLEAY_CONFIG=-extensions san_env Set the domain name in the SAN environment variable: $ export SAN="DNS:mail.xaxo.eu" And follow the instructions in the section "Creating and signing a new certificate". Import the root certificate in a web browser -------------------------------------------- I found that the easiest way to import the root certificate of the CA is to convert it to a .der file and then use the import function of the web browser. This has been tested with both Opera and Firefox and worked well. $ openssl x509 -outform der -in demoCA/cacert.pem -out demoCA/cacert.der Converting a certificate to a human readable format --------------------------------------------------- The certificate is saved as file.crt and has the following format: -----BEGIN CERTIFICATE----- MIICxDCCAi2gAwIBAgIJAIHL9LDMK9HEMA0GCSqGSIb3DQEBBQUAMGMxCzAJBgNV BAYTAkJHMRAwDgYDVQQIEwdQbG92ZGl2MRAwDgYDVQQKEwd4YXhvLmV1MRAwDgYD VQQDEwd4YXhvLmV1MR4wHAYJKoZIhvcNAQkBFg9tb21jaGlsQHhheG8uZXUwHhcN MTMwNDE2MTIyNDU3WhcNMTQwNDE2MTIyNDU3WjBoMQswCQYDVQQGEwJCRzEQMA4G A1UECBMHUGxvdmRpdjEQMA4GA1UEChMHeGF4by5ldTEVMBMGA1UEAxMMbWFpbC54 YXhvLmV1MR4wHAYJKoZIhvcNAQkBFg9tb21jaGlsQHhheG8uZXUwgZ8wDQYJKoZI hvcNAQEBBQADgY0AMIGJAoGBAMZVwqZZSMRil555XGDKk52+TAmmqSbWakDTIMo6 LnxYo+8JFwjcgMKOfl4jcf8Kd/T6Poa+EdegO9vKqompYfkEf0ivalDNMAhcXSdU P6+weNUZUrJheFGD94SEDbKRfcAxCMD0N68OuZHsRxEiy/Owl6sO0+x3PaW8Yq8S dm01AgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wg R2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBQsOft1j2L9fuStQdhagiNh zXk00TAfBgNVHSMEGDAWgBQHQHQR4NS7cdPDiI/UqZtMP8/jqjANBgkqhkiG9w0B AQUFAAOBgQAB2e3LHlgOSY9VmA6O7ln2vr/uplhvlyoqrSyMXSzWYn1NEibF7Raf iwiszA8y6O+e3Q0evUzn7HhcXTLe/Dxeba6Z41zMdmd5oIvDgntqDT4Pqo7zQYtz g1GhP+XaOc0P4/We390GQ23eFWg/xd8cTX4Q6SczOgfUc77awln1JQ== -----END CERTIFICATE----- Convert it to a human readable format using: $ openssl x509 -in file.crt -noout -text -purpose Testing a TLS connection ------------------------ One can test a TLS connection directly using the OpenSSL package to check whether the proper certificate is being presented by the server. In this example we connect to the server server.example.local on port 9000 using the TLS protocol: $ openssl s_client -connect server.example.local:9000 -showcerts We can also also tell openssl to send a protocol-specific message to switch to TLS for communication (see man s_client(1)): $ openssl s_client -starttls imap -connect server.example.local:9001 -showcerts -state Remove the password from the key file ------------------------------------- $ openssl rsa -in newkey.pem -out newkey2.pem Managing demoCA-certs --------------------- When you create a new certificate you need to create a new symlink for it: $ FILE=file.pem ln -s $FILE `openssl x509 -hash -noout -in $FILE`.0 One can also process a whole directory using: $ for i in `ls *-cert.pem` do ln -s $i `openssl x509 -hash -noout -in $i`.0 done See also man c_rehash(1). Errors ------ failed to update database TXT_DB error number 2 To fix use: $ openssl ca -updatedb Additional information ---------------------- For additional information visit: http://sandbox.rulemaker.net/ngps/m2/howto.ca.html http://www.openldap.org/pub/ksoper/OpenLDAP_TLS.html#5.0