OpenSSL

From Segfault
Jump to: navigation, search

Installation

From a tarball:

wget https://www.openssl.org/source/openssl-1.1.0.tar.gz{,.sha256,.asc}
sha256sum openssl*.tar.gz | grep --color `cat openssl*.tar.gz.sha256`
gpg --verify openssl*.tar.gz.asc                                                                     # → PGP Key IDs

tar -xzvf openssl*.tar.gz

From the Git repository:

git clone git://git.openssl.org/openssl.git openssl-git

Install prerequisites:

apt-get install zlib1g-dev                                                                           # Debian, Ubuntu
dnf install zlib-devel                                                                               # Fedora, CentOS

Build and install:[1]

./Configure --prefix=/opt/openssl no-idea no-mdc2 no-rc5 no-zlib no-ssl3 no-ssl3-method shared linux-$(uname -m)
make depend && make && sudo make install

Note: we're using the shared option to install libssl.so. You may have to utilize LD_LIBRARY_PATH[2] later on though :-\

You man want to run some tests afterwards:

make test

Usage

Private key

Certificates need a private key to be generated from[3][4]. To generate an RSA key:

openssl genrsa -out privkey.pem 4096                                                                 # Add -aes128 to encrypt the private key.

For a DSA key:

openssl dsaparam -out dsaparam.pem 4096
openssl gendsa -out privkey.pem dsaparam.pem                                                         # Add -aes128 to encrypt the private key.

Or, for an ECC key:

openssl ecparam -name prime256v1 -genkey -noout -out privkey.pem                                     # Encrypt with: openssl ec -in privkey.pem -aes128 -out privkey_enc.pem

Newer versions of OpenSSL support[5] support X25519, but we cannot sign certificates with that key[6] and we'll have to use an even newer version[7] to use Ed25519 for our key:

openssl genpkey -algorithm Ed25519 -out privkey.pem

Notes:

  • Use the -noout option to omit the EC parameters![8]
  • In lieu of a SafeCurves OpenSSL implementation[9][10], we shall choose P-256 (or P-384)[11] for now.
  • Add -param_enc explicit to EC key generation[12] to include the curve's parameters into the key.

Public key

To get the public key from the private' key we just generated, use:

openssl  rsa -in privkey.pem -pubout
openssl  dsa -in privkey.pem -pubout
openssl   ec -in privkey.pem -pubout
openssl pkey -in privkey.pem -pubout

Self-signed certificate

Self-signed certificates can be created without a Certificate Authority (CA):

SUBJECT='/C=US/ST=CA/L=SF/O=None/OU=None/CN=localhost/emailAddress=root@localhost'
openssl req -new -x509 -sha512 -days 3650 -key privkey.pem -out cert.pem -subj "$SUBJECT"            # For DSA keys, use -sha256 instead.

The generated certificate can now be used, for example for a webserver:

openssl dhparam -out dhparam.pem 2048                                                                # This may take a long time to complete.
openssl s_server -accept 8443 -key privkey.pem -cert cert.pem -dhparam dhparam.pem -tls1_2 -www

Notes:

  • We use custom DH parameters in this example.[13]
  • If an intermediate certificate was appended to cert.pem, we would add the -chain option.

Connect via:

curl -k https://localhost:8443                                                                       # Using -insecure because it's a self-signed certificate
openssl s_client -connect localhost:8443

PKCS12

PKCS 12 is a file format used to store a privat key along with its certificate, protected with a password-based symmetric key. Sometimes it's necessary to remove the password[14] from the pkcs12 file.

openssl pkcs12 -in file.p12 -nodes -out file.pem
openssl pkcs12 -export -in file.pem -out file_plain.p12
rm file.pem

Root CAs

Let's Encrypt

TBD

CAcert

Since Debian does no longer[15][16][17] ship the CAcert Root Certificate, we have to install it ourselves:

wget https://www.cacert.org/certs/root.crt                          # Find the predicament! :-)
sudo mkdir /usr/local/share/ca-certificates/cacert/
sudo mv root.crt /usr/local/share/ca-certificates/cacert/
sudo update-ca-certificates

Now the CAcert certificate should be usable.

Self-Signed

This will explain[18], in short, how to be our own self-signed certificate authority (CA).

SUBJECT='/C=US/ST=CA/L=SF/O=Foobar CA/OU=None/CN=Foobar CA/emailAddress=ca@example.org'
openssl req -new -x509 -sha512 -days 3650 -extensions v3_ca -keyout cakey.pem -newkey rsa:4096 -sha512 -nodes -out cacert.pem -subj "$SUBJECT"

Or, for EC[19] keys:

openssl ecparam -genkey -name prime256v1 -out cakey.pem
openssl req -new -x509 -sha512 -days 3650 -key cakey.pem -nodes -out cacert.pem -subj "$SUBJECT_CA"

Notes:

  • With -nodes, the resulting ca-key.pem will not be encrypted.
  • The Organization Name (O) must match the one from the certificate request we're about to create.
  • The Organizational UnitName (ON) is optional, but we included it here for completeness.

Create the certificate request:

SUBJECT='/C=US/ST=CA/L=SF/O=Foobar CA/OU=None/CN=server.example.org/emailAddress=root@example.org'
openssl req -new -out server-req.pem -keyout server-key.pem -newkey rsa:2048 -sha512 -nodes -subj "$SUBJECT"

Again, for EC keys:

openssl ecparam -genkey -name prime256v1 -out server-key.pem
openssl req -new -sha512 -key server-key.pem -nodes -out server-req.pem -subj "$SUBJECT"

Sign the request by our CA and generate the certificate:

openssl x509 -req -sha256 -days 730 -in server-req.pem -CA cacert.pem -CAkey cakey.pem -CAcreateserial -out server-cert.pem

OCSP

OCSP is used to check the revocation status of certificates. Firefox uses OCSP since version 3[20], Google Chrome stopped using OCSP in 2012 [21], citing latency and privacy issues.

In Firefox, OCSP is enabled with:

security.OCSP.enabled = 1                         # Default
security.OCSP.require = false                     # Assume that the certificate is not revoked as a fallback mechanism
security.OCSP.GET.enabled = false                 # Use POST requests to the OCSP responder by default

OCSP stapling can be used as an alternative to OCSP: the server will append a previously received signed OCSP response to the client, thus eliminating the need for the client to contact the CA. OCSP stapling needs to be supported by both the server and the client.[22][23]

On the client side, OCSP stapling seems to be enabled by default in Google Chrome[24] and in Firefox with version 26[25]:

security.ssl.enable_ocsp_stapling = true          # Default

Let's try to check the revocation status of a certificate[26][27], using the CA's OCSP responder:

openssl s_client -CApath /etc/ssl -connect example.net:443 -showcerts < /dev/null > showcerts

If more than one certificat has been received, we need to extract them and then chain them together[28]:

i=1; while [ $i -le $(grep -c BEGIN showcerts) ]; do
       awk "/-----BEGIN/,/-----END/ {if(++m==1)n++;if(n=="$i") print;if(/-----END/)m=0}" showcerts > showcerts_${i}
       i=$((i+1))
done
cat showcerts_[0-9] > showcerts_chained

Get the OCSP responder URI:

$ openssl x509 -in showcerts_1 -noout -ocsp_uri
http://ocsp.startssl.com/sub/class1/server/ca

Send a request to the responder.

  • Use -noverify to skip verification on the response. This is sometimes needed.
  • Use -no_nonce to not send a nonce to the responder, as some might not support it.
  • We use the (undocumented) -header option[29][30], otherwise responders might answer with "Code=400,Reason=Bad Request"
$ openssl ocsp -issuer showcerts_chained -cert showcerts_1 \
          -url http://ocsp.startssl.com/sub/class1/server/ca -header HOST ocsp.startssl.com -text

OCSP Request Data:
   Version: 1 (0x0)
   Requestor List:
       Certificate ID:
         Hash Algorithm: sha1
         Issuer Name Hash: 6568874F40750F016A3475625E1F5C93E5A26D58
         Issuer Key Hash: 607D48F437F0E4A850500BE9C2122FBEEC081235
         Serial Number: 05DA538DDBD6C2
   Request Extensions:
       OCSP Nonce:
           0410517917662E9B1DA2DE389DDDDE9527B7
OCSP Response Data:
   OCSP Response Status: successful (0x0)
   Response Type: Basic OCSP Response
   Version: 1 (0x0)
   Responder Id: C = IL, O = StartCom Ltd. (Start Commercial Limited), CN = StartCom Class 1 Server OCSP Signer
   Produced At: Aug 24 02:13:04 2015 GMT
   Responses:
   Certificate ID:
     Hash Algorithm: sha1
     Issuer Name Hash: 6568874F40750F016A3475625E1F5C93E5A26D58
     Issuer Key Hash: EB4234D098B0AB9FF41B6B08F7CC642EEF0E2C45
     Serial Number: 05DA538DDBD6C2
   Cert Status: good
   This Update: Aug 24 02:13:04 2015 GMT
   Next Update: Aug 26 02:13:04 2015 GMT
[...]
showcerts_1: ERROR: No Status found.

The OCSP responder replied with "successful" to our request - alas, OpenSSL thinks that no status has been found because the "Responses" field was empty[26] :-\

See also

TODO

  • Get all this into a foolproof script
  • Provide server and client configuration details
    • apache, lighttpd, dovecot, courier, exim, stunnel
    • mozilla clients, pine/alpine, fetchmail
  • Advanced topics like
    • changing passphrase of CA
    • renew certificates/CA
    • wildcard certs
    • revoking certs
    • client cert authentication

Links

Bookmarks



References

  1. Compilation and Installation
  2. $LD_LIBRARY_PATH oder doch nicht?!
  3. HOWTO certificates (Archive)
  4. OpenSSL generate different types of self signed certificate
  5. OpenSSL 1.1.0 Series Release Notes
  6. (no subject) - "It is not possible to "self-sign" an X25519 certificate because X25519 is a key-exchange algorithm only, not a digital signature algorithm."
  7. OpenSSL 1.1.1 Series Release Notes
  8. Why does openssl writes EC parameters when generating private key?
  9. SafeCurves: choosing safe curves for elliptic-curve cryptography
  10. Safe ECC curves (2014-01-01)
  11. Which elliptic curve should I use?
  12. Command Line Elliptic Curve Operations
  13. OpenVPN dhparam
  14. remove the passphrase from a pkcs12 certificate
  15. Debian #213086 - ca-certificates: Please include CAcert.org certificate
  16. Debian #718434 - ca-certificates: should CAcert.org be included?
  17. Debian and CAcert
  18. OpenSSL Certificate Authority
  19. ECDSA Certificate Authorities and Certificates With OpenSSL
  20. Bug 110161 - (ocspdefault) enable OCSP by default
  21. Revocation checking and Chrome's CRL (2012-02-05)
  22. SSLUseStapling (Apache 2.4)
  23. nginx-announce: nginx-1.3.7
  24. Check For Server Certificate Revocation checkbox is confusing
  25. OCSP Stapling in Firefox
  26. 26.0 26.1 OpenSSL: Manually verify a certificate against an OCSP
  27. Checking OCSP revocation using OpenSSL
  28. OCSP unknown status when passing cert, good status when passing serial
  29. ocsp - Online Certificate Status Protocol utility
  30. OCSP stapling with certificate servers behind CloudFlare