Openssl.conf Walkthru

The man page for openssl.conf covers syntax, and in some cases specifics. But most options are documented in in the man pages of the subcommands they relate to, and its hard to get a full picture of how the config file works. This page aims to provide that.

Let's start with how the file is structured. For starters, it's an INI-type file, which means sections begin with [section_name] and run until the next section begins. Anything within a section is a simple key=value pair.

There is one additional caveat. Sometimes a key's value is expected to be a section name. This means there is no finite list of possible sections that the parser understands.

So let's get started...

[ ca ]
default_ca      = CA_default

The "ca" section defines the way the CA acts when using the ca command to sign certificates. However, the only thing that should be in the CA section is the name of the default CA's section. This "default" section to use can be overridden by passing -name to ca.

[ CA_default ]
dir             = /var/ca

Here we start our CA_default section and defined a variable to hold our base directory. "dir" is not a key that openssl recognizes, so it's just a varible.

certs		= $dir/certsdb
new_certs_dir	= $certs
database	= $dir/index.txt
certificate	= $dir/cacert.pem
private_key	= $dir/private/cakey.pem
serial		= $dir/serial
crldir		= $dir/crl
crlnumber	= $dir/crlnumber
crl		= $crldir/crl.pem
RANDFILE	= $dir/private/.rand
certs / new_certs_dir
Depending on version, one or the other of these may be used, so we assign one a value and assign it to the other. This is, as you might expect, where certs go after we sign them.
database
This is the database of signed certificates. Openssl uses this internally to keep track of things.
certificate
CA certificate
private_key
CA private key
serial
The serial number which the CA is currently at. You should not initialize this with a number! instead, use the -create_serial option, as mentioned in our Creating a CA page.
crldir
This isn't a config option to openssl, so it's just defining a variable like $dir
crlnumber
This is the serial number, but for CRLs
crl
The current CRL
RANDFILE
This is a random file to read/write random data to/from.
x509_extensions = usr_cert

This defines the section in the file to find the x509v3 extensions to be added to signed certificates.

copy_extensions	= copy

When acting as a CA, we want to honor the extensions that are requested. Note that you do not want copyall here as it's a security risk and should only be used if you really know what you're doing.

name_opt        = ca_default
cert_opt        = ca_default

These simply define the way that the name and certificate information are displayed to you for "confirmation" before signing a certificate and should be left as-is.

default_days    = 365
default_crl_days= 30

The default life for a certificate and a CRL.

default_md      = sha1
preserve        = no

The default digest algorithm - this can be left alone unless you know what you're doing - and whether or not to preserve the DN. Preserving the DN is a site-specific thing: if you want all your certs to have the same DN order, than so "no" here and openssl will re-order the attributes in the DNs of CSRs to make them consistent. However, if you want to let people determind the order of their DN, set this to "yes."

policy          = policy_match

This is the default policy section to use if none is specified.

[ policy_match ]
countryName             = match
stateOrProvinceName     = match
localityName            = supplied
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

In the "policy_match" policy, all fields listed as "match" must contain the exact same contents as that field in the CA's DN. All fields listed as "supplied" must be present. All fields listed as "optional" are allowed, but not required to be there. Anything allowed must be listed! So this policy requires the same country, State, and Organization name as the CA for all certs it signs.

[ policy_anything ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

Here we define a "policy_anything" policy where we accept anything, and only require a CN. We can refer to this with a -policy policy_anything.

At this point, we officially leave the ca area, and move into req.

[ req ]
default_bits            = 2048
default_keyfile         = privkey.pem
distinguished_name      = req_distinguished_name
attributes              = req_attributes
x509_extensions		= v3_ca
req_extensions		= v3_req

Here we define the section for the req command. We define the default size, the name of the keyfile, the section that defines how to form the DN, what attributes to put in the request, and the section that defines what x509 extensions to request. Note there is a req_extensions where you can define a section that includes req extensions as well.

string_mask = nombstr

This defines what kind of strings to accept. nombstr is basically non-UTF, printable strings. See the man page for details.

We're now done with the req section and move onto req_distinguished_name, which as you'll recall is just value we assigned to the distinguished_name key in req. Again, this will define how to form the DN.

[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = US
countryName_min                 = 2
countryName_max                 = 2

stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = California

localityName                    = Locality Name (eg, city)
localityName_default            = Los Angeles

This says that countryName's description is "Country Name (2 letter code)", it's default is "US" and that it's min and max is 2 letters. We also provide a description and default for stateOrProvinceName and localityName, but define no size restrictions for them.

0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = ABCDEF Corporation

This works similar to the above, except that starting with a "0." denotes that this is the first entry for organizationName. Since it can be a multi-valued field, you have to define which one you're referring to. Here we'll only allow one.

organizationalUnitName          = Organizational Unit Name (eg, section)

commonName                      = Common Name (eg, YOUR name)
commonName_max                  = 64

emailAddress                    = Email Address
emailAddress_max                = 64

Here we specify a description (but no default) for organizationalUnitName and a description and max size for commonName, and emailAddress. This ends the req_distinguished_name section, and thus what we can put in the DN.

[ req_attributes ]

This would define extra attributes for our requests such as Challenge Passwords. I keep this section empty, but it must exist!

[ usr_cert ]
basicConstraints = CA:false
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer

The usr_cert, like req_distinguished_name was simply defined above. We previously did, x509_extensions = usr_cert, denoting the place to find the x509 extensions to put in certificates we'll be signing is usr_cert. You should refer to Extensions page for details on these extensions.

The first x509 extension we set is basicConstraints, and we provide it a value of CA:false which, as you might have guessed, says the certificate cannot be used as a CA. Next we set subjectKeyIdentifier to hash - this means the method for finding the SKI is to hash the public key. We then define authorityKeyIdentifier as both the SKI of the CA that signed us, and the issuer of the CA that signed us (keyid and issue respectively).

[ v3_req ]
subjectAltName = email:move

This section defines x509v3 extensions to request in our requests. We always want to put email addresses here instead of the DN, as it's PKIX compliant. If you want a PKIX complaint CA, be sure to see the Creating a CA page

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = CA:true

This section is used to define what extensions to use when signing a CA, and you would use this sectin (instead of the usr_cert, the previously defined default), by specifying -extensions v3_ca on the ca command line.

Here, we define the same extensions as we did in usr_cert, but with some different values. First, we specifically require our AKI settings (if we can't get access to the required information, we'll fail) and our basicConstraints sets CA to true instead of false.

That's it! Now, here's a sample openssl.conf with comments:

HOME                    = .
RANDFILE                = $ENV::HOME/.rnd

####################################################################
# CA Definition
[ ca ]
default_ca      = CA_default            # The default ca section

####################################################################
# Per the above, this is where we define CA values
[ CA_default ]

dir             = .                     # Where everything is kept
certs           = $dir/certsdb          # Where the issued certs are kept
new_certs_dir   = $certs                # default place for new certs.
database        = $dir/index.txt        # database index file.
certificate     = $dir/cacert.pem       # The CA certificate
private_key     = $dir/private/cakey.pem# The private key
serial          = $dir/serial           # The current serial number
RANDFILE        = $dir/private/.rand    # private random number file

crldir          = $dir/crl
crlnumber       = $dir/crlnumber        # the current crl number
crl             = $crldir/crl.pem       # The current CRL

# By default we use "user certificate" extensions when signing
x509_extensions = usr_cert              # The extentions to add to the cert

# Honor extensions requested of us
copy_extensions	= copy

# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt        = ca_default            # Subject Name options
cert_opt        = ca_default            # Certificate field options

# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
#crl_extensions        = crl_ext
default_days    = 365                   # how long to certify for
default_crl_days= 30                    # how long before next CRL
default_md      = sha1                  # which md to use.
preserve        = no                    # keep passed DN ordering

# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy          = policy_match

####################################################################
# The default policy for the CA when signing requests, requires some
# resemblence to the CA cert
#
[ policy_match ]
countryName             = match         # Must be the same as the CA
stateOrProvinceName     = match         # Must be the same as the CA
organizationName        = match         # Must be the same as the CA
organizationalUnitName  = optional      # not required
commonName              = supplied      # must be there, whatever it is
emailAddress            = optional      # not required

####################################################################
# An alternative policy not referred to anywhere in this file. Can
# be used by specifying '-policy policy_anything' to ca(8).
#
[ policy_anything ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

####################################################################
# This is where we define how to generate CSRs
[ req ]
default_bits            = 2048
default_keyfile         = privkey.pem
distinguished_name      = req_distinguished_name # where to get DN for reqs
attributes              = req_attributes         # req attributes
x509_extensions		= v3_ca  # The extentions to add to self signed certs
req_extensions		= v3_req # The extensions to add to req's

# This sets a mask for permitted string types. There are several options. 
# default: PrintableString, T61String, BMPString.
# pkix   : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
string_mask = nombstr


####################################################################
# Per "req" section, this is where we define DN info
[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = US
countryName_min                 = 2
countryName_max                 = 2

stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = California

localityName                    = Locality Name (eg, city)
localityName_default            = Hawthorne

0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = PhilNet

organizationalUnitName          = Organizational Unit Name (eg, section)

commonName                      = Common Name (eg, YOUR name)
commonName_max                  = 64

emailAddress                    = Email Address
emailAddress_max                = 64


####################################################################
# We don't want these, but the section must exist
[ req_attributes ]
#challengePassword              = A challenge password
#challengePassword_min          = 4
#challengePassword_max          = 20
#unstructuredName               = An optional company name


####################################################################
# Extensions for when we sign normal certs (specified as default)
[ usr_cert ]

# User certs aren't CAs, by definition
basicConstraints=CA:false

# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
#nsCertType = server
# For an object signing certificate this would be used.
#nsCertType = objsign
# For normal client use this is typical
#nsCertType = client, email
# and for everything including object signing:
#nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
#keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer

# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
#subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
#subjectAltName=email:move


####################################################################
# Extension for requests
[ v3_req ]
# Lets at least make our requests PKIX complaint
subjectAltName=email:move


####################################################################
# An alternative section of extensions, not referred to anywhere
# else in the config. We'll use this via '-extensions v3_ca' when
# using ca(8) to sign another CA.
#
[ v3_ca ]

# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always

# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true

# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign

# Some might want this also
# nsCertType = sslCA, emailCA

# Include email address in subject alt name: another PKIX recommendation
#subjectAltName=email:move
# Copy issuer details
#issuerAltName=issuer:copy