[Ref: OpenBSD 5.2, madboa’s Command-Line HOWTO ]
Table of Contents
* <a href="#csr">Signing Request</a>
* <a href="#selfsigned">Self Signed</a>
<a href="#selfsigned.verify"Verify</a>
* <a href="#sancsr">Signing Request</a>
* <a href="#sanselfsigned">Self Signed</a>
OpenBSD (up to 5.5) ships with OpenSSL in the base.
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 OpenBSD base install defaults to storing OpenSSL configuration files and keys/certificates in the directory /etc/ssl.
Verify the path for OpenSSL files using
1$ sudo openssl version -d
OPENSSLDIR: "/etc/ssl"
If the path for trusted certs does not exist, create it:
1$ sudo mkdir -p /etc/ssl/certs
Normally, we use a 3rd party to provide some level of authentication/trust between your hosts and external users. In many cases, your external users are internal users and what you want is to provide the encryption of data transport, without the costs involved with using the above mentioned 3rd party.
What we want is:
The long-form command-line req creates both a certificate and key:
1$ sudo openssl req -days 365 -new -newkey rsa:4096 -sha1 -x509 \
2 -keyout /path-to/private/ca.key.pem \
3 -out /path-to/certs/ca.crt.pem \
4 -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 []:
Validate the key creation by using OpenSSL.
1$ openssl rsa -noout -text -in /path-to/private/ca.key.pem
2$ openssl x509 -noout -text -in /path-to/certs/ca.crt.pem
Put some security on the CA key.
1$ sudo chmod 0600 /path-to/private/ca.key.pem
The defaults for the above prompts, during the key generation, can be specified either in the configuration file (/etc/ssl/openssl.cnf) or on the command-line using the -subj option
1$ sudo openssl req -days 365 -new -newkey rsa:4096 -sha1 -x509 \
2 -keyout /path-to/private/ca.key.pem \
3 -out /path-to/certs/ca.crt.pem \
4 -subj '/CN=coco.nut.to/O=Coconut Games/C=TO/ST=Tongatapu/L=Nukualofa/emailAddress=samt@coco.nut.to' \
5 -config /path-to/openssl.cnf
We could also have generated the CA Key by using OpenSSL’s genrsa
1$ 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.
When you have a new host, for which we need to encrypt transit traffic we need to:
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.
1$ sudo /usr/sbin/openssl req -days 365 -nodes -new -newkey rsa:4096 \
2 -keyout /path-to/private/server.key.pem \
3 -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) []:mx.example.com 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.
1$ sudo openssl req -noout -text -in /path-to/private/server.csr.pem
2$ sudo openssl rsa -noout -text -in /path-to/private/server.key.pem
[Ref: x509(1)]
1$ sudo /usr/sbin/openssl x509 -req -days 365 \
2 -in /path-to/private/server.csr.pem \
3 -CA /path-to/certs/ca.crt.pem \
4 -CAkey /path-to/private/ca.key.pem \
5 -CAcreateserial \
6 -out /path-to/certs/server.crt.pem
Signature ok subject=/C=TO/ST=Nukualofa/L=Tongatapu/O=Coconut Farmers/OU=IT Department/CN=mx.coco.nut.to/emailAddress=spam@coco.nut.to Getting Private key Enter pass phrase for /path-to/private/ca.key.pem:
You can verify from you have created valid openssl keys through the following commands
1$ sudo openssl rsa -noout -text -in /path-to/private/ca.key.pem
2$ sudo openssl req -noout -text -in /path-to/private/server.csr.pem
3$ 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)
1$ sudo openssl rsa -noout -modulus -in /path-to/private/server.key.pem | openssl md5
2$ sudo openssl x509 -noout -modulus -in /path-to/certs/server.crt.pem | 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.
[Ref: x509v3_config(5), Creating an SSL Certificate with Multiple Hostnames, Add an Subject Alternative Name to SSL certificate, SSL Certificate request with subject alternative names(SAN) ]
In practise, we often have to use SSL certificates on a single host but we need to be using different domain names (for example my host email or web pages for multiple family domains such as http://samt.nomoa.com and http://john.nomoa.com etc.)
e.g. My Web Host will serve some subdomains, as well as a few domains from a friend
Host: my.nomoa.com
The simplest way forward is to specify your alternative domain names within a configuration file, because this information will be required twice:-
File: /etc/ssl/example.cnf
1[ req ]
2...
3req_extensions = req_ext
4x509_extensions = v3_ca
5
6...
7[req_ext]
8subjectAltName = @alt_names
9
10[ alt_names ]
11DNS.1 = www.nomoa.com
12DNS.2 = ofa.nomoa.com
13DNS.3 = www.example.com
14DNS.4 = www.example.net
15
16[v3_ca]
17basicConstraints = CA:FALSE
18keyUsage = digitalSignature, nonRepudiation, keyEncipherment
19extendedKeyUsage = serverAuth
@alt_names uses the @section syntax where we can use the [OID.nnn=value](“Object Identifier . nnn”) pair to simplify creating multiple domain names instead of using the comma separated solutions such as:
1subjectAltName = www.nomoa.com, ofa.nomoa.com, www.example.com, www.example.net
Choose your preferred mechanism, and below is a poor interpretation of the documentation for the short and long form configuration format.
[Ref: Multi-valued extensions]
Multi-valued extensions have a short form and a long form. The short form is a list of names and values separated by a comman “,”:
For example:
1 basicConstraints=critical,CA:true,pathlen:1
The long form allows the values to be placed in a separate section, and must be used when the field value includes a comma “,” which would be misinterpreted as a field separator. This is done by using the @section syntax instead of a literal field value:
For example:
1 basicConstraints=critical,@bs_section
2
3 [bs_section]
4 CA=true
5 pathlen=1
Both forms are equivalent.
For example:
1 subjectAltName=URI:ldap://somehost.com/CN=foo,OU=bar
will produce an error but the equivalent form:
1 subjectAltName=@subject_alt_section
2
3 [subject_alt_section]
4 subjectAltName=URI:ldap://somehost.com/CN=foo,OU=bar
is valid.
…
The same field name can only occur once in a section. This is worked around using the form:
1 OID.nnn=value
For Example:
1 subjectAltName=@alt_section
2
3 [alt_section]
4 email.1=samt@example.com
5 email.2=samt@example.net
Now, the signing request we’re going to make below presumes we haven’t created the server private key:
1sudo /usr/sbin/openssl req -days 365 -nodes -new -newkey rsa:4096 \
2 -config /path-to/example.cnf
3 -keyout /path-to/private/server.key.pem \
4 -out /path-to/private/server.csr.pem
You may already have an existing key that you need to use:
1sudo /usr/sbin/openssl req -days 365 -nodes -new \
2 -config /path-to/example.cnf
3 -key /path-to/private/server.key.pem \
4 -out /path-to/private/server.csr.pem
The key difference from the standard certificate request, is now we have explicit request for X509v3 Subject Alternative Name:
1$ sudo openssl req -noout -text -in /path-to/private/server.csr.pem
Certificate Request: Data: ... Attributes: Requested Extensions: X509v3 Subject Alternative Name: DNS:www.nomoa.com, DNS:ofa.nomoa.com, DNS:www.example.com, DNS:www.example.net Signature Algorithm: sha1WithRSAEncryption ...
1$ sudo /usr/sbin/openssl x509 -req -days 365 \
2 -in /path-to/private/server.csr.pem \
3 -extfile /path-to/example.cnf -extensions req_ext \
4 -CA /path-to/certs/ca.crt.pem \
5 -CAkey /path-to/private/ca.key.pem \
6 -CAcreateserial \
7 -out /path-to/certs/server.crt.pem
Verify the contents of your certificates with:
1$ sudo openssl x509 -noout -text -in /path-to/certs/server.crt.pem
Which should now successfully output the Subject Alternative names as we’ve requested in our above Certificate Request:
Certificate: Data: ... X509v3 extensions: X509v3 Subject Alternative Name: DNS:www.nomoa.com, DNS:ofa.nomoa.com, DNS:www.example.com, DNS:www.example.net Signature Algorithm: sha1WithRSAEncryption ...
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.
1# 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’
1# openssl verify -purpose sslserver /path-to/server.pem
server.pem: C=TO,ST=Tongatapu,L=Nukualofa,O=Coconut Games, CN=coco.nut.to, emailAddress=samt@coco.nut.to 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.
1# cd /path-to/certs
2# HASH=$(openssl x509 -noout -hash -in server.crt.pem)
3# echo $HASH
4# 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:
1# openssl verify -purpose sslserver /path-to/server.pem
server.pem: OK
Wooo hoo, It works.
1$ sudo openssl dhparam -out /path-to/dh_512.pem -2 512
2$ sudo openssl dhparam -out /path-to/dh_1024.pem -2 1024
[Ref: IE9 Help - Certificate File Formats, The Most Common OpenSSL Commands ]
Because we can’t agree on the “one-size-fits-all” file format for the SSL certificates, different applications/services use different formats for certificates. Thus, we need a brief overview of these formats, and hints for converting files between the different formats.
Personal Information Exchange (PKCS #12)
The Personal Information Exchange format (PFX, also called PKCS #12) supports secure storage of certificates, private keys, and all certificates in a certification path.
The PKCS #12 format is the only file format that can be used to export a certificate and its private key.
Cryptographic Message Syntax Standard (PKCS #7)
The PKCS #7 format supports storage of certificates and all certificates in the certification path.
DER-encoded binary X.509
The Distinguished Encoding Rules (DER) format supports storage of a single certificate. This format does not support storage of the private key or certification path.
Base64-encoded X.509
The Base64 format supports storage of a single certificate. This format does not support storage of the private key or certification path.
Conventions exist for the extensions, such as:-
Where PEM is used as container file containing potentially multiple certificates, certificate chains, and keys. Certificate file types | pem(3)
From / To | Command |
---|---|
DER to PEM |
|
PEM to PKCS#12 |
|
PEM to PKCS#12 |
May contain a private key.
|
PKCS#12 to PEM |
|
PKCS#12 to PEM |
pkcs12(1)
The pkcs12 command allows PKCS#12 files (sometimes referred to as PFX files) May contain a private key and certificates
We want to explictly extract the key and certificate into separate files.
|
[Ref: rsa(1)]
The rsa command processes RSA keys. They can be converted between various forms and their components printed out. Note this command uses the traditional SSLeay compatible format for private key encryption: newer applications should use the more secure PKCS#8 format using the pkcs8(1) utility.
From / To | Command |
---|---|
DER to PEM |
|
NET to PEM |
|