Minimal openssl.cnf
Summary: Need to create X.509 certificate chain? This post explains how to do it with OpenSSL commands and gives minimal working examples of the configuration for typical test/demo cases.
A config file is needed
OpenSSL commands (that is, the ones invoked from the command line) are mostly
controlled by their options. But in order to issue X.509 certificates or CSRs
OpenSSL needs a configuration file.
This file may contain no useful information, but is still required.
This post gives and explains minimal configuration files for OpenSSL commands
used for certificate generation: x509
, req
and ca
.
OpenSSL installation should supply a default configuration file,
often called openssl.cnf
.
Below, we'll use expressions openssl.cnf
and "OpenSSL configuration file"
interchangeably.
The topic of this post is the minimal configuration file. Sometimes the command will need more parameters than such minimum contains; in these cases they will be provided via command-line options. These options are kept at minimum too, so in real applications you'd likely need to pass more parameters - either via the config file or through the options.
Let's proceed to creating the certificate chain, i.e. one CA certificate and one "leaf" certificate issued by the CA.
Generate the private key
Generation of the private key can be included in some of the commands below,
but for clarity let's create a private key with a separate command.
To sound modern, pick an elliptic curve
from openssl ecparam -list_curves
with the name which sounds cute,
such as secp521r1
(on a serious note - selection of the elliptic curve is out of scope
of this post):
$ openssl ecparam -genkey -name secp521r1 -out privkey.pem
We'll use this same key for all certificates which appear later; of course such practice is acceptable only for demonstration or testing.
Create a self-signed CA certificate
This command needs a config file. Unless one is provided, OpenSSL will use the default, which may not contain what you want. There are two ways to provide a custom config:
-
-config
option -
OPENSSL_CONF
environment variable
We'll use the first way to show the config file in a more explicit manner.
There are two OpenSSL subcommands which can be used to create a self-signed
CA certificate: req -x509
and ca
. Examples of both are below.
Using "req -x509" command
The minimum config file for this command is:
[ req ] distinguished_name = req_dn [ req_dn ]
Call this file openssl-min-req.cnf
.
With it, you can issue self-signed certificates:
$ openssl req -new -x509 -nodes -key privkey.pem -config openssl-min-req.cnf -subj "/CN=My self-signed CA certificate" -out ca.pem
If we do not specify the version explicitly or request any of X.509v3 extensions, then OpenSSL sets the version the certificate to 1.
Check with openssl x509 -purpose -in ca.pem
and
observe that various "CA" purposes come with Yes (WARNING code=3)
.
Surprisingly, for a V3 certificate, there seems to be no clear indication
whether it is a CA certificate or not. Two extensions claim properties
related to CA functionality. OpenSSL's C API function X509_check_ca
returns non-zero when the certificate either has CA:TRUE
in
basicConstraints
extension, or keyCertSign
in keyUsage
extension.
Other software may follow other rules (for example, require CA:TRUE
).
To satisfy OpenSSL's interpretation, the minimal openssl.cnf
can be
like this:
[ req ] distinguished_name = req_dn x509_extensions = v3_ext [ req_dn ] [ v3_ext ] basicConstraints = CA:true
Using "ca -selfsign" command
Below is the minimal openssl-ca.cnf
which would do the job.
[ ca ] default_ca = CA_default [ CA_default ] database = index.txt serial = serial.txt policy = policy_default [ policy_default ]
For this command to succeed, three files referenced above must be created:
$ touch index.txt index.txt.attr $ echo '01' > serial.txt
When done, self-signed CA certificate is created with this command:
$ openssl ca -config openssl-ca.cnf -selfsign -in csr.pem -keyfile privkey.pem -md default -out ca.pem -outdir . -days 365 -batch
Now we have the CA certificate. Next, create leaf certificates signed by it.
Create a certificate signed by your new CA
Create a CSR
A CSR (Certificate Signing Request) is made with req
command.
For it, the "minimum request openssl.cnf" is sufficient:
$ openssl req -new -config openssl-min-req.cnf -key privkey.pem -nodes -subj "/CN=Non-CA example certificate" -out csr.pem
Inspect the CSR with openssl req -text -noout -in csr.pem
.
Having a CSR, the corresponding certificate can be issued using either x509
or ca
commands. Below are examples for both.
Sign the CSR using "x509 -req" command
$ openssl x509 -req -in csr.pem -CA ca.pem -CAkey privkey.pem -CAcreateserial -out cert.pem
The x509
command seems to have no option -config
, but it honors the
environment variable OPENSSL_CONF
. If the file is not readable, OpenSSL prints
WARNING: can't open config file: /usr/lib/ssl/openssl.cnf
and continues. For the example above, config file is not needed;
and if it is not needed, you should not use it, because it may bring in
items which you do not want. It looks like the way to "disable" config file
processing is to set OPENSSL_CONF=some_nonexisting_file
.
Sign the CSR using "ca" command
Previously mentioned openssl-ca.cnf
works also for this case, and cannot
be reduced.
$ openssl ca -config openssl-ca.cnf -cert ca.pem -keyfile privkey.pem -in csr.pem -out cert.pem -outdir . -md default -days 365 -batch
By default the ca
command does not copy the X.509v3 extensions from the
CSR (the ones specified in x509_extensions
section of the [ req ]
part
in our example openssl-min-req.cnf
) to the signed certificate.
To do so, add copy_extensions = copy
line to the CA section
([ CA_default ]
in our example openssl-ca.cnf
).
Alternatively, the CA may add own extensions when signing a CSR -
for example, set CA:FALSE
.
These should be listed in the section with the name given by the variable
x509_extensions
in the [ CA_default ]
section.
Conclusion
- To create certificate chains with OpenSSL, a configuration file is needed.
- OpenSSL will use the default config file unless you provide another one
via command-line option or an environment variable.
- Except that
x509 -req
is missing the option.
- Except that
- While the default may work for some cases, if you need any control over your certificates, you'll need to create the config file.
- You get more control over the content of your certificates when starting with the bare minimum than with the default. The minimal examples are provided in this post.