blog.dornea.nu

Hack, code and drink some țuică. Personal blog of Victor Dorneanu.

Manage PKI using OpenSSL

In the previous X.509 related post I've had a look at the internals of a X.509 certficate. This time I want to setup my own PKI using some open source software. This post is a preparation for setting up a VPN using OpenVPN.

Before implementing the PKI let's have a look what a PKI should definitely include (make sure you have a look at the Wikipedia entry):

The level of security is increased because you separate the root CA from the issuing CAs. The root CA is mostly offline so the private key to sign the certificates should be thus protected from compromise. If one of the issuing CAs is being compromised, you can revoke the certificate issued for that specific CA and create another one using the root CA. You can also have multiple issuing CAs distributed geographically and with different security levels. This increases flexibility and scalability.

We'll have a root CA bound to the domain dornea.nu followed by 2 intermediate CAs: dev.dornea.nu CA and vpn.dornea.nu CA. The CAs will be used to issue certificates to users and networks.

The TLS Server CA will be used by a web server like Apache or Nginx to server content over a SSL/TLS connection. The server will only accept connection from clients with a valid TLS Client CA which has been signed (and generated) from dev.dornea.nu CA.

The vpn.dornea.nu CA will then issue certificates for a VPN Server CA and a VPN Client CA.

In this post the creation of the VPN Server CA and VPN Client CA will be ommitted. I'll cover this in a related post.

OpenSSL is probably the most known cryptography software and SSL/TLS toolkit. Let's have look how things are done using OpenSSL. First of all I'll setup a directory structure to represent each of the PKI component in a clean way.

We will specify multiple domains with one certificate by using SANs (Subject Alternatve Name). Those are a X.509 V3 extension to allow a SSL certificate to specify multiple names that the certificate should match. They can contain:

.bash
$ cd /tmp/pki
$ openssl req -new \
-config ca/conf/dev-server-ca.conf \
-out ca/dev-server-ca/certs/dev.dornea.nu.csr \
-keyout ca/dev-server-ca/certs/dev.dornea.nu.key
Generating a 4096 bit RSA private key
......................................................................................................................................................++
...........................................++
writing new private key to 'ca/dev-server-ca/private/dev-server-ca.key'
-----
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.
-----
1. Country Name (2 letters) (eg, US) []:DE
2. State or Province Name (eg, region) []:Berlin
3. Locality Name (eg, city) []:Berlin
4. Organization Name (eg, company) []:dornea.nu
5. Organizational Unit Name (eg, section) []:dev.dornea.nu
6. Common Name (eg, FQDN) []:dev.dornea.nu

Now we create a PKCS#12 bundle including the private key, the certificate and the CA chain.

PKCS#12 defines an archive file format to store crypto stuff inside a single file. It is usually used to store a
private key along with the X.509 certificate. The PKCS#12 file may be encrypted and signed.

.bash
$ openssl req -new \
-config ca/conf/dev-client-ca.conf \
-out ca/dev-client-ca/certs/victor.csr \
-keyout ca/dev-client-ca/certs/victor.key
Generating a 4096 bit RSA private key
.......................................................................................++
..........................................................................................................................................................................................++
writing new private key to 'ca/dev-client-ca/certs/victor.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
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.
-----
1. Country Name (2 letters) (eg, US) []:NU
2. State or Province Name (eg, region) []:Germany
3. Locality Name (eg, city) []:Berlin
4. Organization Name (eg, company) []:dornea.nu
5. Organizational Unit Name (eg, section) []:dev dornea.nu
6. Common Name (eg, full name) []:Victor Dorneanu
7. Email Address (eg, [email protected]) []:[email protected]

.bash
$ openssl req -new \
-config ca/conf/vpn-server-cert.conf \
-out ca/vpn-ca/certs/vpn-server/raspberry_pi.csr \
-keyout ca/vpn-ca/certs/vpn-server/raspberry_pi.key
Generating a 4096 bit RSA private key
............................................................................................................................................................++
.....................................++
writing new private key to 'ca/vpn-ca/certs/vpn-server/raspberry_pi.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
Verify failure
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
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.
-----
1. Country Name (2 letters) (eg, US) []:NU
2. State or Province Name (eg, region) []:/dev/null
3. Locality Name (eg, city) []:/dev/random
4. Organization Name (eg, company) []:dornea.nu
5. Organizational Unit Name (eg, section) []:VPN
6. Common Name (eg, full name) []:vpn.dornea.nu

.bash
$ openssl req -new \
-config ca/conf/vpn-client-cert.conf \
-out ca/vpn-ca/certs/vpn-client/victor.csr \
-keyout ca/vpn-ca/certs/vpn-client/victor.key
Generating a 4096 bit RSA private key
...............................................................++
................................................................................++
writing new private key to 'ca/vpn-ca/certs/vpn-client/victor.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
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.
-----
1. Country Name (2 letters) (eg, US) []:NU
2. State or Province Name (eg, region) []:/dev/null
3. Locality Name (eg, city) []:/dev/random
4. Organization Name (eg, company) []:dornea.nu
5. Organizational Unit Name (eg, section) []:vpn.dornea.nu
6. Common Name (eg, full name) []:Victor Dorneanu
7. Email Address (eg, [email protected]) []:[email protected]