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):

  • certificate authority (CA)
    • has a public and a private key
    • used to digitally sign certificates
  • registration authority (RA)
    • verify identify of users requesting information from the CA
  • certificate management system
    • probably the most important component

Revision

Date Description
2015-10-02 First release
2015-11-17 Added creation of VPN-CA and related certificates.

CA types

There are several types of CAs:

  • root CA
    • the root of the PKI hierarchy
    • issues CA certificates
  • intermediate CA
    • the CA right below the root CA
    • issues CA certificates
  • signing CA
    • CA at the bottom of the PKI hierarchy
    • issues only user certificates

Certificates types

There are several types of certificates used in real-world:

  • root certificate
    • self-signed certificate at the root of the PKI hierarchy
    • has to be kept secret
  • CA certificate
    • used to sign other certificates and CRLs
  • user certificate
    • end-user certificate issues for one purpose: code signing, mail protection etc.
    • user certificates can not sign other certificates

PKI hierarchy

In most modern companies you'll find a 3-tier PKI hierarchy.

In [170]:
Expand Code

For my purposes I'll be using only a 2-tier hierarchy as shown below:

In [5]:
Expand Code

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.

Also checkout this awesome article for further details.

dornea.nu PKI hierarchy

And now let's make this whole hierarchy more personalized:

In [13]:
Expand Code

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

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.

In [1]:
%%bash

Initialize and create cert database:

In [2]:
%%bash
cd /tmp/pki
touch ca/root-ca/db/root-ca.db
touch ca/root-ca/db/root-ca.db.attr
echo 01 > ca/root-ca/db/root-ca.crt.srl
echo 01 > ca/root-ca/db/root-ca.crl.srl
In [3]:
%%bash
tree /tmp/pki
/tmp/pki
└── ca
    ├── conf
    └── root-ca
        ├── certs
        ├── crl
        ├── db
        │   ├── root-ca.crl.srl
        │   ├── root-ca.crt.srl
        │   ├── root-ca.db
        │   └── root-ca.db.attr
        └── private

7 directories, 4 files

In order to create the certificates I'll keep track of every CA using OpenSSL configuration files.

Sub-commands

Below there is an overview of the most used subcommands in openssl:

Subcommand Description Details
req PKCS#10 X.509 Certificate Signing Request (CSR) Management The req command primarily creates and processes certificate requests in PKCS#10 format. It can additionally create self signed certificates for use as root CAs for example.
ca Certificate Authority (CA) Management It can be used to sign certificate requests in a variety of forms and generate CRLs it also maintains a text database of issued certificates and their status.
pkcs12 PKCS#12 Data Management The pkcs12 command allows PKCS#12 files (sometimes referred to as PFX files) to be created and parsed. PKCS#12 files are used by several programs including Netscape, MSIE and MS Outlook.
x509 X.509 Certificate Data Management It can be used to display certificate information, convert certificates to various forms, sign certificate requests like a "mini CA" or edit certificate trust settings.

Create dornea.nu root CA

In [14]:
Expand Code

The configuration file can be shown here:

In [4]:
Expand Code
Writing /tmp/pki/ca/conf/root-ca.conf

Now let's create the CA request. The configuration for the creation of the CSR if found in the configuration file in the section [req]:

.bash
$ cd /tmp/pki
$ openssl req -new \
            -config ca/conf/root-ca.conf \
            -out ca/root-ca/root-ca.csr \
            -keyout ca/root-ca/private/root-ca.key

Generating a 4096 bit RSA private key
.......................................++
............................++
writing new private key to 'ca/root-ca/private/root-ca.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----

Now create the CA certificate (will be valid for 10 years):

.bash
$ cd /tmp/pki
$ openssl ca -selfsign \
           -config ca/conf/root-ca.conf \
           -in ca/root-ca/root-ca.csr \
           -out ca/root-ca/root-ca.crt \
           -extensions root_ca_ext \
           -days 3650

Using configuration from ca/conf/root-ca.conf
Enter pass phrase for ./ca/root-ca/private/root-ca.key:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Sep 28 17:37:10 2015 GMT
            Not After : Sep 25 17:37:10 2025 GMT
        Subject:
            countryName               = NU
            organizationName          = dornea.nu
            organizationalUnitName    = dornea.nu Root CA
            commonName                = dornea.nu Root CA
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Subject Key Identifier: 
                72:39:A1:56:5E:9D:09:ED:8D:DE:31:9E:80:9B:C4:5D:62:3B:64:66
            X509v3 Authority Key Identifier: 
                keyid:72:39:A1:56:5E:9D:09:ED:8D:DE:31:9E:80:9B:C4:5D:62:3B:64:66

Certificate is to be certified until Sep 25 17:37:10 2025 GMT (3650 days)
Sign the certificate? [y/n]:Y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Now you can check the status of the previously generated certificate (serial number = 1):

.bash
$ openssl -config ca/conf/root-ca.conf -status 01
Using configuration from ca/conf/root-ca.conf
01=Valid (V)

Create dev.dornea.nu CA

In [15]:
Expand Code

Create the directories:

In [5]:
%%bash

Initialize the database:

In [6]:
%%bash
cd /tmp/pki
touch ca/dev-ca/db/dev-ca.db
touch ca/dev-ca/db/dev-ca.db.attr
echo 01 > ca/dev-ca/db/dev-ca.crt.srl
echo 01 > ca/dev-ca/db/dev-ca.crl.srl

Configure the CA:

In [7]:
Expand Code
Writing /tmp/pki/ca/conf/dev-ca.conf

Create CA signing request (CSR):

.bash
$ cd /tmp/pki
$ openssl req -new \
            -config ca/conf/dev-ca.conf \
            -out ca/dev-ca/dev-ca.csr \
            -keyout ca/dev-ca/private/dev-ca.key

Generating a 4096 bit RSA private key
.............++
..........................................................................++
writing new private key to 'ca/dev-ca/private/dev-ca.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----

Now we use the root CA to create the dev-ca certificate:

.bash
$ cd /tmp/pki
$ openssl ca -config ca/conf/root-ca.conf \
           -in ca/dev-ca/dev-ca.csr \       
           -out ca/dev-ca/dev-ca.crt \
           -extensions signing_ca_ext

Using configuration from ca/conf/root-ca.conf
Enter pass phrase for ./ca/root-ca/private/root-ca.key:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Sep 28 18:13:56 2015 GMT
            Not After : Sep 27 18:13:56 2025 GMT
        Subject:
            countryName               = NU
            organizationName          = dornea.nu
            organizationalUnitName    = dornea.nu Root CA
            commonName                = dev.dornea.nu CA
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:0
            X509v3 Subject Key Identifier: 
                1A:42:33:7A:18:93:91:5F:B1:92:AA:37:39:76:31:92:3D:A6:2C:68
            X509v3 Authority Key Identifier: 
                keyid:B1:56:7C:FB:69:C7:77:CE:6C:7D:BA:CF:C7:7D:0C:6A:24:AF:8A:A1

            Authority Information Access: 
                CA Issuers - URI:http://pki.dornea.nu/root-ca.cer

            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://pki.dornea.nu/root-ca.crl

Certificate is to be certified until Sep 27 18:13:56 2025 GMT (3652 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Create vpn.dornea.nu CA

In [4]:
Expand Code

Create the directories:

In [8]:
%%bash
cd /tmp/pki
mkdir -p ca/vpn-ca/ ca/vpn-ca/private ca/vpn-ca/db ca/vpn-ca/certs

Initialize the database:

In [9]:
%%bash
cd /tmp/pki
touch ca/vpn-ca/db/vpn-ca.db
touch ca/vpn-ca/db/vpn-ca.db.attr
echo 01 > ca/vpn-ca/db/vpn-ca.crt.srl
echo 01 > ca/vpn-ca/db/vpn-ca.crl.srl

Configure CA:

In [18]:
Expand Code
Overwriting /tmp/pki/ca/conf/vpn-ca.conf

Create CA signing request (CSR):

.bash
$ cd /tmp/pki
$ openssl req -new \
            -config ca/conf/vpn-ca.conf \
            -out ca/vpn-ca/vpn-ca.csr \
            -keyout ca/vpn-ca/private/vpn-ca.key

Generating a 4096 bit RSA private key
...........................................++
.......++
writing new private key to 'ca/vpn-ca/private/vpn-ca.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----

Now we use the root CA to create the vpn-ca certificate:

.bash
$ cd /tmp/pki
$ openssl ca -config ca/conf/root-ca.conf \
           -in ca/vpn-ca/vpn-ca.csr \       
           -out ca/vpn-ca/vpn-ca.crt \
           -extensions signing_ca_ext

Using configuration from ca/conf/root-ca.conf
Enter pass phrase for ./ca/root-ca/private/root-ca.key:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 3 (0x3)
        Validity
            Not Before: Sep 29 18:28:45 2015 GMT
            Not After : Sep 28 18:28:45 2025 GMT
        Subject:
            countryName               = NU
            organizationName          = dornea.nu
            organizationalUnitName    = dornea.nu Root CA
            commonName                = vpn.dornea.nu CA
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:0
            X509v3 Subject Key Identifier: 
                52:53:49:45:12:D4:7B:A3:B7:8D:E0:14:00:81:4E:30:BC:A0:19:69
            X509v3 Authority Key Identifier: 
                keyid:F4:3B:44:1F:6D:02:26:06:C1:16:B9:1F:84:FC:41:48:5B:F6:0D:77

            Authority Information Access: 
                CA Issuers - URI:http://pki.dornea.nu/root-ca.cer

            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://pki.dornea.nu/root-ca.crl

Certificate is to be certified until Sep 28 18:28:45 2025 GMT (3652 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Create dev-ca CA chain

In [6]:
%%bash
cd /tmp/pki
cat ca/dev-ca/dev-ca.crt ca/root-ca/root-ca.crt > ca/dev-ca/dev-ca-chain.pem

Create vpn-ca CA chain

In [7]:
%%bash
cd /tmp/pki
cat ca/vpn-ca/vpn-ca.crt ca/root-ca/root-ca.crt > ca/vpn-ca/vpn-ca-chain.pem

Issue dev-CA certificates

We'll now create the TLS server and client certificates.

Create TLS server certificate

In [16]:
Expand Code

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:

  • mail addresses
  • IP addresses
  • DNS names
  • etc.

Let's have a look at the config file:

In [118]:
Expand Code
Overwriting /tmp/pki/ca/conf/dev-server-ca.conf

Create directories:

In [117]:
%%bash
cd /tmp/pki
mkdir -p ca/dev-server-ca/ ca/dev-server-ca/private ca/dev-server-ca/db ca/dev-server-ca/certs

Create a private key and CSR for the TLS server certificate:

.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 use the dev-ca certificate to issue the TLS server certificate:

.bash
$ cd /tmp/pki
$ openssl ca -config ca/conf/dev-ca.conf \
            -in ca/dev-server-ca/certs/dev.dornea.nu.csr \
            -out ca/dev-server-ca/certs/dev.dornea.nu.crt \
            -extensions server_ext

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
$ cd /tmp/pki
$ openssl pkcs12 -export \
                -name "dev.dornea.nu (Developer)" \
                -caname "dev.dornea.nu CA" \
                -caname "dornea.nu root CA" \
                -inkey certs/green.no.key \
                -in ca/dev-server-ca/certs/dev.dornea.nu.crt \
                -certfile ca/dev-server-ca/dev-ca-chain.pem \
                -out ca/dev-server-ca/certs/dev.dornea.nu.p12
Enter Export Password:
Verifying - Enter Export Password:

Verify PKCS#12 bundle

You can now verify the bundle:

.bash
$ openssl pkcs12 -in ca/dev-server-ca/certs/dev.dornea.nu.p12 -info | egrep -e "issuer" -e "subject"
Enter Import Password:
MAC Iteration 2048
MAC verified OK
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
Certificate bag
Certificate bag
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
subject=/C=NU/ST=Germany/L=Berlin/O=dornea.nu/OU=dev dornea.nu/CN=dev.dornea.nu
issuer=/C=NU/O=dornea.nu/OU=dornea.nu Root CA/CN=dev.dornea.nu CA
subject=/C=NU/O=dornea.nu/OU=dornea.nu Root CA/CN=dev.dornea.nu CA
issuer=/C=NU/O=dornea.nu/OU=dornea.nu Root CA/CN=dornea.nu Root CA
Enter PEM pass phrase:
subject=/C=NU/O=dornea.nu/OU=dornea.nu Root CA/CN=dornea.nu Root CA
issuer=/C=NU/O=dornea.nu/OU=dornea.nu Root CA/CN=dornea.nu Root CA

Create TLS client certificate

In [17]:
Expand Code

Create directories:

In [135]:
%%bash
cd /tmp/pki
mkdir -p ca/dev-client-ca/ ca/dev-client-ca/ ca/dev-client-ca/db ca/dev-client-ca/certs

Create config:

In [136]:
%%writefile /tmp/pki/ca/conf/dev-client-ca.conf↔
Overwriting /tmp/pki/ca/conf/dev-client-ca.conf

Now I'll create a new CSR for the user victor:

.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]

Now create the TLS client certificate:

.bash
$ openssl ca -config ca/conf/dev-ca.conf \
            -in ca/dev-client-ca/certs/victor.csr \
            -out ca/dev-client-ca/certs/victor.crt \
            -extensions client_ext

Using configuration from ca/conf/dev-ca.conf
Enter pass phrase for ./ca/dev-ca/private/dev-ca.key:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 3 (0x3)
        Validity
            Not Before: Sep 30 19:01:14 2015 GMT
            Not After : Sep 29 19:01:14 2016 GMT
        Subject:
            countryName               = NU
            stateOrProvinceName       = Germany
            localityName              = Berlin
            organizationName          = dornea.nu
            organizationalUnitName    = dev dornea.nu
            commonName                = Victor Dorneanu
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Extended Key Usage: 
                TLS Web Client Authentication
            X509v3 Subject Key Identifier: 
                21:E4:47:97:E8:90:39:B5:8C:8A:5B:DD:24:78:23:A9:17:DB:97:9E
            X509v3 Authority Key Identifier: 
                keyid:C5:7E:17:39:6F:CE:D2:40:B8:7E:B8:5D:0E:41:04:75:BB:0D:2B:98

            Authority Information Access: 
                CA Issuers - URI:http://dev.dornea.nu/ca/dev-ca.cer

            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://dev.dornea.nu/ca/dev-ca.crl

            X509v3 Subject Alternative Name: 
                email:[email protected]
Certificate is to be certified until Sep 29 19:01:14 2016 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Create PKCS#12 bundle

.bash
$ openssl pkcs12 -export \
                 -name "dev.dornea.nu (Developer)" \
                 -caname "dev.dornea.nu CA" \
                 -caname "dornea.nu Root CA" \
                 -inkey ca/dev-client-ca/certs/victor.key \ 
                 -in ca/dev-client-ca/certs/victor.crt \ 
                 -certfile ca/dev-ca/dev-ca-chain.pem \ 
                 -out ca/dev-client-ca/certs/victor.p12        
Enter pass phrase for ca/dev-client-ca/certs/victor.key:
Enter Export Password:
Verifying - Enter Export Password:

Now verify the bundle:

.bash
$ openssl pkcs12 -in ca/dev-client-ca/certs/victor.p12 -info | egrep -e "issuer" -e "subject"
Enter Import Password:
MAC Iteration 2048
MAC verified OK
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
Certificate bag
Certificate bag
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
subject=/C=NU/ST=Germany/L=Berlin/O=dornea.nu/OU=dev dornea.nu/CN=Victor Dorneanu
issuer=/C=NU/O=dornea.nu/OU=dornea.nu Root CA/CN=dev.dornea.nu CA
subject=/C=NU/O=dornea.nu/OU=dornea.nu Root CA/CN=dev.dornea.nu CA
issuer=/C=NU/O=dornea.nu/OU=dornea.nu Root CA/CN=dornea.nu Root CA
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
subject=/C=NU/O=dornea.nu/OU=dornea.nu Root CA/CN=dornea.nu Root CA
issuer=/C=NU/O=dornea.nu/OU=dornea.nu Root CA/CN=dornea.nu Root CA

Issue vpn-CA certificates

We'll now create VPN server and client certificates.

Create VPN server certificate

In [8]:
Expand Code
In [9]:
%%bash
cd /tmp/pki
mkdir -p ca/vpn-ca/certs/vpn-server
In [10]:
Expand Code
Overwriting /tmp/pki/ca/conf/vpn-server-cert.conf

Create CSR

And now create the CSR (Code Signing Request):

.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

Sign certificate

Now use the VPN-CA to issue the CRT (Code Signing Certificate):

.bash
$ openssl ca -config ca/conf/vpn-ca.conf \                                                               1 ↵
                -in ca/vpn-ca/certs/vpn-server/raspberry_pi.csr \
                -out ca/vpn-ca/certs/vpn-server/raspberry_pi.crt \
                -extensions server_ext

Using configuration from ca/conf/vpn-ca.conf
Enter pass phrase for ./ca/vpn-ca/private/vpn-ca.key:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Nov  9 19:39:48 2015 GMT
            Not After : Nov  8 19:39:48 2016 GMT
        Subject:
            countryName               = NU
            stateOrProvinceName       = /dev/null
            localityName              = /dev/random
            organizationName          = dornea.nu
            organizationalUnitName    = VPN
            commonName                = vpn.dornea.nu
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Subject Key Identifier: 
                80:CA:5B:3C:C7:8A:E4:76:FF:4B:DC:5D:17:F9:99:07:27:69:76:60
            X509v3 Authority Key Identifier: 
                keyid:E2:DB:62:AB:F4:5D:56:17:65:B2:FA:66:55:C9:04:1D:1C:9B:10:A3

            Authority Information Access: 
                CA Issuers - URI:http://vpn.dornea.nu/ca/vpn-ca.cer

            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://vpn.dornea.nu/ca/vpn-ca.crl

Certificate is to be certified until Nov  8 19:39:48 2016 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Create PKCS12 bundle

Now bundle the root CA, VPN ca and the VPN server cert into one file:

.bash
$ openssl pkcs12 -export \                                                    
    -name "VPN Server (Raspberry Pi)" \
    -caname "vpn.dornea.nu CA" \
    -caname "dornea.nu Root CA" \
    -inkey ca/vpn-ca/certs/vpn-server/raspberry_pi.key \
    -in ca/vpn-ca/certs/vpn-server/raspberry_pi.crt \
    -certfile ca/vpn-ca/vpn-ca-chain.pem \ 
    -out ca/vpn-ca/certs/vpn-server/raspberry_pi.p12

Enter pass phrase for ca/vpn-ca/certs/vpn-server/raspberry_pi.key:
Enter Export Password:
Verifying - Enter Export Password:

Create VPN client certificate

In [12]:
Expand Code
In [13]:
%%bash
cd /tmp/pki
mkdir -p ca/vpn-ca/certs/vpn-client
In [14]:
Expand Code
Overwriting /tmp/pki/ca/conf/vpn-client-cert.conf

Create CSR

Now create the CSR for the user victor:

.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]

Sign the CSR

Sign the CSR using VPN-CA:

.bash
$ openssl ca -config ca/conf/vpn-ca.conf \
                -in ca/vpn-ca/certs/vpn-client/victor.csr \      
                -out ca/vpn-ca/certs/vpn-client/victor.crt \      
                -extensions client_ext              

Using configuration from ca/conf/vpn-ca.conf
Enter pass phrase for ./ca/vpn-ca/private/vpn-ca.key:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Nov  9 19:49:16 2015 GMT
            Not After : Nov  8 19:49:16 2016 GMT
        Subject:
            countryName               = NU
            stateOrProvinceName       = /dev/null
            localityName              = /dev/random
            organizationName          = dornea.nu
            organizationalUnitName    = vpn.dornea.nu
            commonName                = Victor Dorneanu
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Extended Key Usage: 
                TLS Web Client Authentication
            X509v3 Subject Key Identifier: 
                12:3F:57:DF:1D:DB:73:BC:E0:A0:97:18:0D:B9:6C:C9:FF:53:8E:1B
            X509v3 Authority Key Identifier: 
                keyid:E2:DB:62:AB:F4:5D:56:17:65:B2:FA:66:55:C9:04:1D:1C:9B:10:A3

            Authority Information Access: 
                CA Issuers - URI:http://vpn.dornea.nu/ca/vpn-ca.cer

            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://vpn.dornea.nu/ca/vpn-ca.crl

            X509v3 Subject Alternative Name: 
                email:[email protected]
Certificate is to be certified until Nov  8 19:49:16 2016 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Create PKCS#12 bundle

Bundle the root CA, VPN CA and the VPN client cert into a single file:

.bash
$ openssl pkcs12 -export \
    -name "VPN Client (Victor)" \      
    -caname "vpn.dornea.nu CA" \
    -caname "dornea.nu Root CA" \
    -inkey ca/vpn-ca/certs/vpn-client/victor.key \ 
    -in ca/vpn-ca/certs/vpn-client/victor.crt \      
    -certfile ca/vpn-ca/vpn-ca-chain.pem \
    -out ca/vpn-ca/certs/vpn-client/victor.p12      

Enter pass phrase for ca/vpn-ca/certs/vpn-client/victor.key:
Enter Export Password:
Verifying - Enter Export Password:


Prev: Organizing and visualizing knowledge
Next: Basic Layer 2 Switching using Cisco Packet Tracer

comments powered by Disqus
Published:
2015-10-02 00:00
category:
Tag: