HOWTO: Using NSS with libreswan

From Libreswan
Jump to navigation Jump to search

The libreswan IKE daemon uses the Mozilla Network Security Services ("NSS") crypto library for all cryptographic functions during the IKE negotiation.

Introduction

NSS is a userspace library utilized by the libreswan IKE daemon 'pluto' for cryptographic operations. NSS does not handle the IPsec crypto operations inside of the kernel; these are handled seperately by NETKEY or the KLIPS kernel module.

The NSS library exports a PKCS#11 API for the application to communicate to a cryptographic device. The cryptographic device is usually the "soft token" but can also be a Hardware Security Module (HSM).

The advantage of using NSS is that pluto does not need to know in detail how the cryptographic device works. Pluto does not access any private keys or data itself. Instead, it uses the PK11 wrapper API of NSS irrespective of the cryptographic device used. Pluto hands over work using the PK11 interface to NSS and never has direct access to the private key material itself. Both IKEv1 and IKEv2 operations are performed using NSS. Private RSA keys (raw RSA as well as X.509 based private RSA keys) are stored inside NSS. RSA keys are still referenced in /etc/ipsec.secrets. X.509 keys and certificates are referenced using their "nickname" instead of their filename in /etc/ipsec.conf.

While PreShared Key (PSK) calculations are done using NSS, the actual preshared key ("secret") is still stored in /etc/ipsec.secrets.

NSS as shipped by Red Hat is a FIPS certified library. Libreswan is currently in the process of obtaining a FIPS certification for http://www.redhat.com/products/enterprise-linux/ [RHEL7].

NSS command line tools

  • certutil: Look and modify the NSS db. "ipsec initnss" and "ipsec look" use certutil under the hood.
  • pk12util: import and export certificates and keys from and to the NSS db. The "ipsec import" command is a simple wrapper around this utility.

Creating the NSS db for use with libreswan

If you are not using a packaged libreswan version, you might need to create a new NSS db before you can start libreswan. This can be done using:

ipsec initnss

By default the NSS db is created in /etc/ipsec.d/

When creating a database, you are prompted for a password. The default libreswan package install for RHEL/Fedora/CentOS uses an empty password. It is up to the administrator to decide on whether to use a password or not. However, a non-empty database password must be provided when running in FIPS mode.

To change the empty password, run:

certutil -W -d /etc/ipsec.d

Enter return for the "old password", then enter your new password twice.

If you create the database with a password, and want to run NSS in FIPS mode, you must create a password file with the name "nsspassword" in the /etc/ipsec.d direcotry before starting libreswan. The "nsspassword" file must contain the password you provided when creating NSS database.

If the NSS db is protected with a non-empty password, the "nsspassword" file must exist for pluto to start. The syntax of the "nsspassword" file is:

token_1_name:the_password
token_2_name:the_password

The name of NSS softtoken (the default software NSS db) when NOT running in FIPS mode is "NSS Certificate DB". If you wish to use software NSS db with password "secret", you would have the following entry in the nsspassword file:

NSS Certificate DB:secret

If running NSS in FIPS mode, the name of NSS softtoken is "NSS FIPS 140-2 Certificate DB". If there are smartcards in the system, the entries for passwords should be entered in this file as well.

Using raw RSA keys with NSS

The "ipsec newhostkey" and "ipsec rsasigkey" utilities are used for creating raw RSA keys. If a non-default NSS directory is used, this can be specified using the -d option.

ipsec newhostkey --configdir /etc/ipsec.d [--password password] \
        --output /etc/ipsec.secrets

The password is only required if the NSS database is protected with a non-empty password. All "private" compontents of the raw RSA key in /etc/ipsec.secrets such as the exponents and primes are filled in with the CKA ID, which serves as an identifier for NSS to look up the proper information in the NSS db during the IKE negotiation.

Public key information is directly available in /etc/ipsec.secrets and the "ipsec showhostkey" command can be used to generate left/rightrsasigkey= entries for /etc/ipsec.conf.

Using certificates with NSS

Any X.509 certificate management system can be used to generate Certificate Agencies, certificates, pkcs12 files and CRLs. Common tools people use are the openssl command, the GTK utility tinyca2, or the NSS certutil command.

An example using openssl can be found as part of the libreswan test suite at

Below, we will be using the nss tools to generate certificates

To create a certificate authority (CA certficate)

certutil -S -k rsa -n "ExampleCA" -s "CN=Example CA Inc" -v 12 \
        -t "C,C,C" -x -d /etc/ipsec.d

It creates a certificate with RSA keys (-k rsa) with the nick name "ExampleCA", and with common name "Example CA Inc". The option "-v" specifies the certificates validity period. "-t" specifies the attributes of the certificate. "C" is required for creating a CA certificate. "-x" means self signed. "-d" specifies the path of the database directory.

It is not a requirement to create the CA in NSS database. The CA certificate can be obtained from third parties

To create a user certificate signed by the above CA

certutil -S -k rsa -c "ExampleCA" -n "user1" -s "CN=User Common Name" \
        -w 12 -t "u,u,u" -d /etc/ipsec.d

This creates a user cert with nick name "user1" with attributes "u,u,u" signed by the CA cert "ExampleCA".

Configuring certificates in ipsec.conf and ipsec.secrets

In ipsec.conf, the leftcert= option takes a certificate nickname as argument. For example if the nickname of the user cert is "hugh", then it can be "leftcert=hugh".

If you are migrating from openswan without NSS, you were used to specify the filename for the certificate in the leftcert= option. Filenames are not valid in libreswan - only the nickname can be used.

leftcert=nickname

In ipsec.secrets, we need to list the certificate nickname to inform pluto there is a certificate within the NSS db. This is specified using:

: RSA nickname

In openswan and freeswan without NSS it was required to specify a file name or password. With libreswan, this is not required. Private keys were stored in /etc/ipsec.d/private/ This directory is also not used with libreswan.

The directories /etc/ipsec.d/cacerts/ and /etc/ipsec.d/crls/ can still be used.

NOTE: the freeswan and openswan directories /etc/ipsec.d/aacerts/ and /etc/ipsec.d/acerts/ are not used with libreswan.

If you use an external CA certificate, you can either import it into the NSS db or place it in the /etc/ipsec.d/cacerts/ directory. Note that the preferred method is to store it inside the NSS db.

Importing third-party certificates into NSS

If you do not have the third-party certificate in the PKCS#12 format, use openssl to create a PKCS#12 file:

openssl pkcs12 -export -in cert.pem -inkey key.pem \
        -certfile cacert.pem -out YourName.p12   [-name YourName]

Now you can import the file into the NSS db:

ipsec import YourName.p12

NOTE: the ipsec import command uses "pk12util -i YourName.p12 -d /etc/ipsec.d"

If you did not pick a name using the -name option, you can use certutil -L -d /etc/ipsec.d to figure out the name NSS picked durnig the import.

Add following to /etc/ipsec.secrets file:

: RSA "YourName"

To specify the certificate in ipsec.conf, use a line like:

leftcert=YourName

Exporting a CA(?) certificate to load on another libreswan machine

Paul: wouldn't this also include the private key which we don't want? Paul: add "ipsec export"?


To export the CA certificate:

pk12util -o cacert1.p12 -n cacert1 -d /etc/ipsec.d

Copy the file "cacert1.p12" to the new machine and import it using:

ipsec import cacert1.p12
certutil -M -n cacert1 -t "C,C,C" -d /etc/ipsec.d

An example connection for ipsec.conf would look like:

conn pluto-1-2
        left=1.2.3.4
        leftid="CN=usercert1"
        leftrsasigkey=%cert
        leftcert=usercert1
        right=5.6.7.8
        rightid="CN=usercert2"
        rightrsasigkey=%cert
        auto=add

Configuring a smartcard with NSS

Required library: libcoolkey

To make smartcard tokens visible through NSS

modutil -add <module_name> -libfile libcoolkeypk11.so \
        -dbdir <nss_database_dir_name> \
        -mechanisms <mechanisms_separted_by_colons>

An example of mechanisms can be: RC2:RC4:DES:DH:SHA1:MD5:MD2:SSL:TLS:AES:CAMELLIA.

To check whether the token is visible or not, run

modutil -list -dbdir <nss_database_dir_name>