Notes on openssl:

Title:Notes on openssl:
Author:Douglas O’Leary <dkoleary@olearycomputers.com>
Description:Notes on openssl:
Date created:09/29/2015
Date updated:09/29/2015
Disclaimer:Standard: Use the information that follows at your own risk. If you screw up a system, don’t blame it on me...


Overview:

Primarily notes on chapters 11 and 12 of the Bulletproof ssl and tls book from Ivan Ristic, isbn: 978-1907117046.

I’ve skimmed through the majority of the chapters... The book is meticulously documented and referenced. Outstanding effort. My main goal, initially, was familiarization with good handle of the openssl chapters.. Now, we’re there.

Commands:

openssl version [-a]
Provides version information. Add the -a argument for more detail such as the OPENSSLDIR
openssl help
Displays list of commands available. Help isn’t actually a command. You’ll get an error; however, it’ll display the help text.
openssl genrsa -aes128 -out ${key} 2048
Generates a 2048 bit RSA private key encrypted with AES128. Apparently, a reasonably good private key. A passphrase will be required.
openssl rsa -in ${key} -out ${new_key}
Remove a passphrase from a private key. The line above requires that a passphrase be used.
openssl rsa -text -in ${key}
Displays detailed information about the private key.
openssl rsa -in ${key} -pubout [ -out ${outputfile} ]
Displays [ or stores ] the public key generated from the private key.
openssl req -new -key ${key} -out fqdn.csr
Create a certificate signing request from a key.
openssl req -text -in fqdn.csr -noout
Displays information about the cert signing request. Useful for validating correct information was entered.
openssl x509 -text -in fqdn.crt -noout
Displays information about the certificate.
openssl [x509|rsa] inform [PEM|DER] in ${key_in_proper_form} -outform [DER|PEM] -out ${key}
Converts between PEM and DER forms. rsa converts keys; x509 converts certs.
openssl ciphers -v 'ALL:COMPLEMENTOFALL'
Results in 111 ciphers for version 1.0.1p and only 46 for 0.9.8e

Installation:

Normally, you’ll be using the OS installed version; however, for the practice and to follow the book (output snipped):

yum -y install gcc
wget http://www.openssl.org/source/openssl-1.0.1p.tar.gz
tar -xzvf ./openssl-1.0.1p.tar.gz
cd openssl-1.0.1p
./config --prefix=/opt/openssl --openssldir=/opt/openssl \
enable-ec_nistp_64_gcc_128
make depend
make
make install

Openssl is also available via github:

git clone https://github.com/openssl/openssl
cd openssl
./config --prefix=/opt/openssl_git --openssldir=/opt/openssl_git \
enable-ec_nistp_64_gcc_128
make depend
make
make install

As is my norm, I’m doing a bad thing and compiling as root. It’s a kvm so I’m not overly worried. That being said, it’s an incredibly bad idea and I really should stop it.

I’ve compiled and installed both versions. The wget one is in /opt/openssl and will be the primary test bed.. the github version is installed at /opt/openssl_git. This results in three versions available:

# openssl version                         # system version
OpenSSL 1.0.1e-fips 11 Feb 2013
# /opt/openssl/bin/openssl version        # wget version
OpenSSL 1.0.1p 9 Jul 2015
# /opt/openssl_git/bin/openssl version    # github version
OpenSSL 1.1.0-dev xx XXX xxxx

Trust Store:

When compiled on its own, openssl doesn’t have a trust store. You can use the one the OS has or convert your own. Per the book, Mozilla maintains the best and most accurate one. The problem is that Mozilla uses a proprietary format. So, download a conversion utility and convert it:

wget https://raw.github.com/bagder/curl/master/lib/mk-ca-bundle.pl
# chmod 755 ./mk-ca-bundle.pl
# ./mk-ca-bundle.pl
Warning: Use of this script may pose some risk, -d risk for more details.
SHA1 of old file: 0
Downloading 'certdata.txt' ...
Get certdata over HTTPS with curl!
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 1674k  100 1674k    0     0   749k      0  0:00:02  0:00:02 --:--:--  969k
SHA1 of new file: ed3c0bbfb7912bcc00cd2033b0cb85c98d10559c
Processing  'certdata.txt' ...
Done (155 CA certs processed, 48 skipped).

The risks line was a bit frightening, so I checked:

# ./mk-ca-bundle.pl -d risk
Warning: Use of this script may pose some risk:

  1) Using http is subject to man in the middle attack of certdata content
  2) Default to 'release', but more recent updates may be found in other trees
  3) certdata.txt file format may change, lag time to update this script
  4) Generally unwise to blindly trust CAs without manual review & verification
  5) Mozilla apps use additional security checks aren't represented in certdata
  6) Use of this script will make a security engineer grind his teeth and
     swear at you.  ;)

The book doesn’t go into what to do with the newly created ca-bundle.crt. Presumably, copy it into /opt/openssl/certs.

Key and Certificate management:

This is where I’ll be hitting most often. Directly from the book:

Most uses turn to openssl because they wish to configure and run a web server
that supports SSL.

3 steps:

  1. Generate a strong private key
  2. Create a certificate signing request and send it to the CA.
  3. Install the CA provided certificate in your web server.

Key generation:

Decisions to be made:

Key algorithm:
Web servers, pretty much only RSA. DSA is limited to 1024 (insecure) and ECDSA isn’t widely supported yet.
Key size:
2048 RSA keys. If using ECDSA, use 256 bits.
Passphrase:
Book suggests protecting your keys for systems other than web servers. Discussion involves availability considerations. Also mentions that private keys are cached in the clear in application memory so the security enhancement can be easily circumvented.

Some examples:

  • Passphrase protected RSA key protected with AES:

    # openssl genrsa -aes128 -out fd.key 2048
    Generating RSA private key, 2048 bit long modulus
    ..............+++
    ...............................................................................................................................+++
    e is 65537 (0x10001)
    Enter pass phrase for fd.key: <<p-phrase>>
    Verifying - Enter pass phrase for fd.key: <<p-phrase>>
    
    • AES-128 is the key encryption algorithm.

    • e value e is 65537 (0x10001) is the public exponent. Can use -3 switch to further increase speed; but at an unacceptable security risk trade-off.

    • Display information on the private key:

      # openssl rsa -text -in ./fd.key | grep -v '^ '
      Enter pass phrase for ./fd.key: <<p-phrase>>
      Private-Key: (2048 bit)
      modulus:
      [[snip]]
      publicExponent: 65537 (0x10001)
      [[snip]]
      privateExponent:
      [[snip]]
      prime1:
      [[snip]]
      prime2:
      [[snip]]
      exponent1:
      [[snip]]
      exponent2:
      [[snip]]
      coefficient:
      [[snip]]
      -----BEGIN RSA PRIVATE KEY-----
      [[snip]]
      -----END RSA PRIVATE KEY-----
      
    • Generate the public key:

      # openssl rsa -in fd.key -pubout [ -out ${outputfile} ]
      Enter pass phrase for fd.key:
      writing RSA key
      -----BEGIN PUBLIC KEY-----
      MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApiudLn5TTWB8wg+T3aNt
      jfiwVMjEm/q7uXsIjsBl/dhcinV0H1jzRlfVva5wCSIkyGmrrN7P6AY7NJhsV9rz
      2n92zf7IRxz27vmiIqAPtIENY1jg87QnC+J/GoHaZuiFyLKqRhX7HWVZkd28BYEW
      mLPuHlXCfXL9jBTzpMgg7eJ4U+2TQsZAShfzyKF5rj5u0B2uF0KVS/OxgRbmK2OS
      MJchJfhsSjZfF5waPEQNhoYLzxVh+o+ShtkjBXJAsVvKM8POfGipP3JzybvX1Pz+
      8r18x4a0NLKPmx+v2HVLhhCe09fYmIuYChDSgsAva1tzzCBQZ75bB9hpSh+blfMR
      FwIDAQAB
      -----END PUBLIC KEY-----
      
  • Examples of DSA and ECDSA keys are available in the book.

CSR:

Notes:

  • Empty fields must be designated by a ‘.’; if you simply enter <return>, the tool will use the default which may be defined in various ways.
  • Challenge password was originally intended for cert revocation. Don’t enter anything.

Creating the CSR:

# openssl req -new -key fd.key -out fd.csr
Enter pass phrase for fd.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.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:IL
Locality Name (eg, city) []:Naperville
Organization Name (eg, company) [Internet Widgits Pty Ltd]:OCI
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:caauth.olearycomputers.com
Email Address []:dkoleary@olearycomputers.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Verify the information:

# openssl req -text -in fd.csr -noout
[[lotsa lines snipped]]

Can also create a CSR from an existing signed cert. This means you’re re-using the private key which is bad practice:

# openssl x509 -x509toreq -in fd.crt -out fd.csr -signkey fd.key

Can also create CSRs automatically. Script a config file that looks like:

[req]
prompt = no
distinguished_name = dn
req_extension = ext
input_password = <<p-phrase>>

[dn]
CN = caauth.olearycomputers.com
emailAddress = dkoleary@olearycomputers.com
O = OLeary Computers Inc
L = Naperville
C = US

[ext]
subjectAltName = DNS:caauth.olearycomputers.com,DNS:olearycomputers.com

Note that you can’t add extensions through the interactive process. Create the CSR w/o prompting via:

# openssl req -new -config ./fd.conf -key fd.key -out fd.csr

Adding extensions:

As noted, you can’t add extensions such as alt names through the interactive process. To add extensions, create a text file with the extensions:

# cat fd.ext
subjectAltName = DNS:*.olearycomputers.com,DNS:olearycomputers.com

The execute the certificate creation (demonstrated below) using the -extfile ${file} argument.

Self-signed certs:

Two options:

  • Create a self-signed cert from the CSR we generated previously:

    # openssl x509 -req -days 365 -in fd.csr -signkey fd.key -out fd.crt
    Signature ok
    subject=/CN=caauth.olearycomputers.com/emailAddress=dkoleary@olearycomputers.com/O=OLeary Computers Inc/L=Naperville/C=US
    Getting Private key
    Enter pass phrase for fd.key:
    
  • Create self-signed cert from private key:

    # openssl req -new -x509 -days 365 -key fd.key -out fd1.crt
    

    The process will request the same information as provided above. NOTE that you can’t interactively add alternate hostnames.

  • Create self-signed cert using the extensions file:

    # openssl x509 -req -days 365 -in fd.csr -signkey fd.key -out fd2.crt \
    > -extfile fd.ext
    Signature ok
    subject=/CN=caauth.olearycomputers.com/emailAddress=dkoleary@olearycomputers.com/O=OLeary Computers Inc/L=Naperville/C=US
    Getting Private key
    Enter pass phrase for fd.key:
    

Differences between self-signed and signed certs:

Need to be able to ID a cert that’s self signed vs one that’s CA signed.

Private key types:

Types:

  • Binary (DER) keys and certificates
  • ASCII (PEM) keys and certificate. base64-encoded DER key.
  • PKCS#7 cert: complext format for transport of signed/encrypted data. Extensions are usually .p7b or .p7c. Can include the entire cert chain. Java’s keytool supports this format - implying we won’t see it other than that?
  • PKCS#12 (PFX) keys and certs: stores and protects keys and, possibly, the entire cert chain. Seen wiht .p12 or .pfx extensions.

Conversion:

openssl [x509|rsa] inform [PEM|DER] in ${key_in_proper_form} -outform [DER|PEM] -out ${key}
Converts between PEM and DER forms of certificates (not keys)

Examples for converting between the other two forms are in the book.

Cipher Suite selection:

  • To obtain a list of ciphers that openssl supports:

    # openssl ciphers -v 'ALL:COMPLEMENTOFALL'
    Results in 111 ciphers for version 1.0.1p and only 46 for 0.9.8e
    
  • Group keywords described in table 11.1; not duplicated here. Will need this when I initiate the battle for increased web security. Per book, the documentation available via openssl (binary/web) is out of date.

  • Keyword modifiers: Characters prepended to keywords that affect the ordering:

    C Action
      Append to the list. If already there, leave it
    Delete from list; can be reintroduced later.
    ! Permanently delete; cannot be reintroduced later.
    Move to the end of the list
  • Selecting cipher suites: Starting at loc 8064 and continuing through 8321 (this is a kindle book), book goes into some depth on how to select suites using keywords initially followed up by examples using suite names directly.

  • Benchmarking: Some useful guidelines:

    • Benchmark on the host that’ll be doing the work
    • Benchmark a compiled updated version to get an idea of speed differential. Book’s benchmarks suggest that openssl 1.0.1h is 2x faster than 0.9.8k
    • Add multiple cores to benchmarking via -multi switch
    • Add hardware acceleration, if available, via -evp switch.

Private Certificate Authority:

Features & limitations:

  • One root CA; subordinate CAs can be created.
  • Revocation info provided via CRLs and OCSP responders (maybe not)
  • subordinate CAs will be technicall constrained - only able to issue certs for specific hostnames