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
-create_serial
option, as mentioned in our Creating a CA page.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