0

While running the following command on Ubuntu 19.10, with OpenSSl 1.1.1c 28 May 2019:

openssl req -config ${CNF_FILE} -key ${PRIVATE_FILE} -new -x509 -days 10950 -sha384 -extensions v3_ca -out ${CERT_FILE}

I receive the following output:

Error Loading extension section v3_ca

140710502360256:error:22097082:X509 V3 routines:do_ext_nconf:unknown extension name:../crypto/x509v3/v3_conf.c:78:

140710502360256:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:../crypto/x509v3/v3_conf.c:47:name=copy_extensions, value=copy

With the following config file:

[ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               = /home/ca
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
RANDFILE          = $dir/private/.rand

# The root key and root certificate.
private_key       = $dir/private/ca_ecc.key.pem
certificate       = $dir/certs/ca_ecc.cert.pem

# For certificate revocation lists.
crlnumber         = $dir/crlnumber
crl               = $dir/crl/ca.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md        = sha256

name_opt          = ca_default
cert_opt          = ca_default
default_days      = 375
preserve          = no
policy            = policy_strict

[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
# Options for the `req` tool (`man req`).
default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only

# SHA-1 is deprecated, so use SHA-2 instead.
default_md          = sha256

# Extension to add when the -x509 option is used.
x509_extensions     = v3_ca

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name
emailAddress                    = Email Address

# Optionally, specify some defaults.
countryName_default             = US
stateOrProvinceName_default     = My State
localityName_default            = My City
0.organizationName_default      = My Company
organizationalUnitName_default  = My Office
emailAddress_default            = certificates@certificates.com

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
copy_extensions = copy
preserve = yes

The error eludes me, and to give some background, my attempt to is use copy_extensions so that when I pass in a subjectAltName via -addext (or via any means) to the CSR, the subjectAltName will pass into the signed cert when executing the following (the following are openssl commands for the Intermediate Cert to sign and create a client or server based cert, and it all functions fine, except for what I just stated):

openssl ${algo_GEN} -out $PRIVATE_FILE

openssl req -config $CNF_FILE -key $PRIVATE_FILE -new -addext "subjectAltName = ${SAN_LIST}" -sha384 -out $CSR_FILE << EOF





${CERT_ID}

EOF

openssl ca -batch -config $CNF_FILE -extensions ${EXTENSION} -days 375 -notext -md sha384 -in 
jj_inno
  • 33
  • 1
  • 5

1 Answers1

3

You're not far off - copy_extensions is not an extension, it needs to be in the CA_Default section to instruct the CA to copy extensions from the CSR to the signed certificate.

Example below, see the last line:

[ CA_default ]
# Directory and file locations.
dir               = /home/ca
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
RANDFILE          = $dir/private/.rand
copy_extensions   = copy

Some useful resources on openssl can be found at the links below:

Openssl config file

X509 extensions

Creating a CA with Openssl

Managing a CA with Openssl

(These links all point to www.phildev.net - I am not associated with this site in anyway, but have found the content informative and easy to understand.)

To quote one part:

The "ca" section defines the way the CA acts when using the ca command to sign certificates.

In your case, the default CA's section is CA_default (your actual "ca" section points to this).

Your best resource for specific commands is the Openssl docs themselves. On the linked page, you'll find the explanation for how to use -addext. As far as I can tell your usage is accurate, but it is possible the issue is in the variable. There's also a good answer on this here: Provide subjectAltName to openssl directly on the command line.

If your extensions are consistent, you can simply add them into the config file under whichever section ${EXTENSION} refers to. You can of course specify multiple sections in the config file and select the correct section in each command using the -extensions flag.

Unencoded
  • 201
  • 1
  • 7
  • Oh! Excellent! Thank you for your response! That resolved my error, but not my overall goal (attempting to pass in SANs via -addext into a CSR, and have that SAN carry over into the signed cert). Could you explain to me why the value must go in default, or point me to a source that can explain that (and maybe many more things)? – jj_inno Jun 29 '20 at 20:04
  • Sure! Hopefully the edits help :) – Unencoded Jun 29 '20 at 21:48
  • Similarly `preserve` is not an extension but instead a CA option. – dave_thompson_085 Jun 30 '20 at 07:18
  • @Unencoded Those extra links you added in were amazing, and following them helped me to reach my ultimate goal! Thank you again! I wish I could give you extra checks or kudos some how. – jj_inno Jun 30 '20 at 18:30
  • Great to hear, thanks very much for the feedback! You could always upvote my comments if you felt so inclined ;) – Unencoded Jun 30 '20 at 18:35
  • @jj_inno I'm trying to achieve the same setup having a config file as default and then pass in SAN when creating a CSR and have them carried over to the certificate when signed. How did you achieve this? Can't figure it out by reading the docs. – joacar Mar 08 '21 at 09:55
  • @joacar So, currently I have SAN as in input from the user, and then it is passed into the cert during the CSR generation process, like the following: [ openssl req -config $cnfFile -key $privateFile -new -addext "subjectAltName = ${sanList}" -sha384 -out $csrFile -subj "$subj" ] – jj_inno Mar 10 '21 at 13:17
  • @joacar During the CSR Generation, I check if the sanList variable exists/is empty, and if it is either of those, I run a different commond: [ openssl req -config $cnfFile -key $privateFile -new -sha384 -out $csrFile -subj "$subj" ] – jj_inno Mar 10 '21 at 13:19
  • @joacar Ultimately, if you want to pass in your SANs like this, and you don't want a user to define them, it is possible to define the sanList yourself inside your code as a static variable, or a static addition to your CSR generation line – jj_inno Mar 10 '21 at 13:21
  • @joacar Also, within the the Config File, within the "Server," "Device," "etc," blocks, you can specify a static SAN list, similar to the following: { [ server ] \ basicConstraints = CA:false \ variableName = variable \ etcName = etc... \ subjectAltName = DNS:address.com } (I hope this makes sense in this format) – jj_inno Mar 10 '21 at 13:49