OpenSSL Certificates

OpenSSL Certificates

[Ref: OpenBSD 4.9, Postfix TLS Support ]

Table of Contents

OpenBSD ships with built in support for OpenSSL and OpenSSH in the base install for encrypted communication. Both systems use public key algorithms, where key-pairs are used with one half is public, and the other half private.

Warning: Remember I know less than you about this stuff, these are notations of something that worked. It doesn’t mean it works well. If you really want to know more about the tools, refer to the OpenSSL website, and madboa’s Command-Line HOWTO

The base install defaults to storing OpenSSL configuration files and keys/certificates in the directory /etc/ssl. OpenSSL will look in the sub-directory certs for trusted certificates.

Verify the path for OpenSSL files using

$ sudo openssl version -d
OPENSSLDIR: "/etc/ssl"

If the path for trusted certs does not exist, create it:

$ sudo mkdir -p /etc/ssl/certs

Certificate Authority (CA)

We want to be our own Certificate Authority (CA) so that we can sign multiple certificates with the same CA for multiple servers.

The long-form command-line req creates both a certificate and key:

$ sudo openssl req -days 365 -new -newkey rsa:4096 -sha1 -x509 \
	-keyout /path-to/private/ca.key.pem \
    -out    /path-to/certs/ca.crt.pem \
    -config /path-to/openssl.cnf
Generating a 4096 bit RSA private key
writing new private key to 'ca.key.pem'
Enter PEM pass phrase: **1234**
Verifying - Enter PEM pass phrase: **1234**
Country Name (2 letter code) []:
State or Province Name (full name) []:
Locality Name (eg, city) []:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []:
Email Address []:
$ sudo chmod 0600 /path-to/private/ca.key.pem

Validate the key creation by using OpenSSL.

$ openssl rsa -noout -text -in  /path-to/private/ca.key.pem
$ openssl x509 -noout -text -in /path-to/certs/ca.crt.pem

You can pre-fill the content for the CA by using the -subj option

$ sudo openssl req -days 365 -new -newkey rsa:4096 -sha1 -x509 \
    -keyout /path-to/private/ca.key.pem \
    -out    /path-to/certs/ca.crt.pem \
    -subj   '/ Games/C=TO/ST=Tongatapu/L=Nukualofa/' \
    -config /path-to/openssl.cnf

We could also have generated the CA Key by using OpenSSL’s genrsa

$ sudo /usr/sbin/openssl genrsa -des3 -out /path-to/private/ca.key.pem 4096

The generated key acts as our SSL private key to be used as our ‘internal’ CA (Certificate Authority.)

Refer/Monitor the documentation for the minimum recommended keysize.

-des|-des3|-idea You must specify the method to encrypt the private key or no encryption is used.

Certificate Request (csr)

A certificate combines data identifying your host, and the authority that accepts authentication of your identity. Create a certificate request (also known as a certificate signing request) to be signed by the certificate authority.

$ sudo /usr/sbin/openssl req -days 365 -nodes -new -newkey rsa:4096 \
    -keyout /path-to/private/server.key.pem \
    -out    /path-to/private/server.csr.pem
Enter pass phrase for server.key.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) []:
State or Province Name (full name) []:
Locality Name (eg, city) []:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Note that the -nodes option above creates the key and certificate request without requiring a password. The “password-less” nature of the key is required for Postfix to operate correctly (i.e. it needs to open the key at various stages)

The concept is that you send the above CSR for a trusted third party to sign, and record in their system, so users who recieve your key can validate from the trusted third party that you are who you are. But we don’t want no third party saying who we are (for now anyway.)

Verify that the Certificate Signing Request has been created.

$ sudo openssl req -noout -text -in /path-to/private/server.csr.pem
$ sudo openssl rsa -noout -text -in /path-to/private/server.key.pem

Self Signed certificate (X509 structure.)

[Ref: x509(1)]

$ sudo /usr/sbin/openssl x509 -req -days 365 \
    -in      /path-to/private/server.csr.pem \
    -CA      /path-to/certs/ca.crt.pem \
    -CAkey   /path-to/private/ca.key.pem \
    -CAcreateserial \
    -out    /path-to/certs/server.crt.pem
Signature ok
subject=/C=TO/ST=Nukualofa/L=Tongatapu/O=Coconut Farmers/OU=IT Department/
Getting Private key
Enter pass phrase for /path-to/private/ca.key.pem:

Verify your Keys

You can verify from you have created valid openssl keys through the following commands

$ sudo openssl rsa -noout -text -in /path-to/private/ca.key.pem
$ sudo openssl req -noout -text -in /path-to/private/server.csr.pem
$ sudo openssl x509 -noout -text -in /path-to/certs/server.crt.pem

To verify that the key is paired with the certificate you just created, compare modulus (they should be the same)

$ sudo openssl rsa -noout -text -in /path-to/private/server.key.pem -modulus \
    | grep ^Modulus | openssl md5
$ sudo openssl x509 -noout -text -in /path-to/certs/server.crt.pem -modulus \
    | grep ^Modulus | openssl md5

According to notes out there (?) The modulus and “public exponent” need to be the same on the certificate and key file. If you’ve created the KEY and self-signed the certificate correctly, then the above commands will return the same value.

Combined Certificates

Ref: Postfix HOWTO TLS/SSL

To enable a remote SMTP client to verify the Postfix SMTP server certificate,
the issuing CA certificates must be made available to the client.

A simple way of providing the CA certificates, is to bundle it together with your server certificate (such as in the sample below: bundle = server cert + ca cert) where the order of inclusion is significant.

# cat /path-to/certs/server.crt.pem /path-to/certs/ca.crt.pem > /path-to/server.pem

After which you should test the resulting PEM file to ensure that it will work for us, using ‘openssl verify’

# openssl verify -purpose sslserver /path-to/server.pem
server.pem: C=TO,ST=Tongatapu,L=Nukualofa,O=Coconut Games,,
error 18 at 0 depth lookup:self signed certificate

The test failed!! Kind-of?

From the manpage

The first line contains the name of the certificate being verified followed 
by the subject name of the certificate. The second line contains the error 
number and the depth. The depth is number of the certificate being verified 
when a problem was detected starting with zero for the certificate being verified 
itself then 1 for the CA that signed the certificate and so on. Finally a text 
version of the error number is presented. 

18 X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: self signed certificate

    the passed certificate is self signed and the same certificate cannot be found in the list of trusted certificates.

Review madboa’s Command-Line HOWTO to remove the error message, which is stripped from the sample code at the above page as below root level command-lines.

# cd /path-to/certs
# HASH=$(openssl x509 -noout -hash -in server.crt.pem)
# echo $HASH
# ln -s server.crt.pem ${HASH}.0

If we’ve understood madboa’s notes, and you’ve understood our mis-interpretation, then you should get the following response:

# openssl verify -purpose sslserver /path-to/server.pem
server.pem: OK

Wooo hoo, It works.

Diffie Helman

$ sudo openssl dhparam -out /path-to/dh_512.pem  -2 512
$ sudo openssl dhparam -out /path-to/dh_1024.pem -2 1024