Reputation: 71
I am running into an odd verification error for a generated certificate chain between OpenSSL 1.1.1 (on Ubuntu 18.04) vs. OpenSSL 1.1.1f (on Ubuntu 20.04).
Here are my test environments (both Docker images):
The scenario involves generating a self-signed root CA, then one or more issued certificates. On the Ubuntu 18.04 instance, the results look fine:
root@temp-ubuntu-0:/tmp/cert# openssl version
OpenSSL 1.1.1 11 Sep 2018
root@temp-ubuntu-0:/tmp/cert# openssl verify -CAfile root.cer client.cer
client.cer: OK
On Ubuntu 20.04, an "error 20 at 0 depth lookup: unable to get local issuer certificate" error occurs:
root@temp-ubuntu-20-0:/tmp/cert# openssl version
OpenSSL 1.1.1f 31 Mar 2020
root@temp-ubuntu-20-0:/tmp/cert# openssl verify -CAfile root-ca.cer client.cer
C = CA, ST = State, L = City, OU = POC, CN = client
error 20 at 0 depth lookup: unable to get local issuer certificate
error client.cer: verification failed
# Observed the same behaviour with OpenSSL 1.1.1g and 1.1.1i (from NGINX Docker images)
Here are the steps taken:
mkdir -p /tmp/cert
cd /tmp/cert
# Create a ".rnd" file to avoid warnings
openssl rand -writerand ~/.rnd
# Create the root CA private key and certificate
openssl req \
-new \
-x509 \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout root-ca.key \
-out root-ca.cer \
-days 3650 \
-subj '/C=CA/ST=State/L=City/OU=POC/OU=Certificate Authorities/CN=POC Root CA' \
-addext "basicConstraints = CA:TRUE" \
-addext "subjectKeyIdentifier = hash" \
-addext "authorityKeyIdentifier = keyid:always, issuer:always" \
-addext "subjectAltName = DNS:POC Root CA" \
-addext "keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly"
# Create the CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout server.key \
-out server.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/CN=server"
# Confirm the contents of the CSR
openssl req -in server.csr -text -noout
# Create the .conf file
cat > /tmp/cert/server_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:FALSE
subjectAltName = DNS:server
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly
extendedKeyUsage = serverAuth
EOF
# Create the certificate
openssl x509 \
-req \
-sha256 \
-CA root-ca.cer \
-CAkey root-ca.key \
-in server.csr \
-out server.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/server_openssl.conf \
-extensions v3_attributes
# Confirm the contents of the new certificate
openssl x509 -in server.cer -text -noout
# Create the CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout client.key \
-out client.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/CN=client"
# Confirm the contents of the CSR
openssl req -in client.csr -text -noout
# Create the .conf file
cat > /tmp/cert/client_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:FALSE
subjectAltName = DNS:client
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly
extendedKeyUsage = clientAuth
EOF
# Create the certificate
openssl x509 \
-req \
-sha256 \
-CA root-ca.cer \
-CAkey root-ca.key \
-in client.csr \
-out client.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/client_openssl.conf \
-extensions v3_attributes
# Confirm the contents of the new certificate
openssl x509 -in client.cer -text -noout
The same issue occurs with server.cer
; works in one, but not the other.
The ultimate goal is to configure mTLS on NGINX. The server TLS portion seems to be working, but the client certification authentication is running into unresolved issues, which led to discovering this situation. Hopefully it's not just a red herring.
Any insight into this behaviour is greatly appreciated!
Thanks!
Upvotes: 2
Views: 2187
Reputation: 71
It seems to work if the root CA is split into openssl req
/openssl x509
commands instead of one single openssl req
command for the root CA. Feels like a defect, but it works. Tested on Ubuntu 20.04 with OpenSSL 1.1.1f.
Here is the new set of commands:
# Create the root CA CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout root.key \
-out root.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/OU=Certificate Authorities/CN=POC Root CA"
# Create the root CA .conf file
cat > /tmp/cert/root_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly
EOF
# Create the root CA certificate
openssl x509 \
-req \
-sha256 \
-signkey root.key \
-in root.csr \
-out root.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/root_openssl.conf \
-extensions v3_attributes
# Use the AKS namespace name for the server certificate
export SERVER_NAME=echo-namespace-1
# Create the server CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout server.key \
-out server.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/CN=server"
# Confirm the contents of the server CSR
openssl req -in server.csr -text -noout
# Create the server .conf file
cat > /tmp/cert/server_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:FALSE
subjectAltName = DNS:server
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
EOF
# Create the server certificate
openssl x509 \
-req \
-sha256 \
-CA root.cer \
-CAkey root.key \
-in server.csr \
-out server.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/server_openssl.conf \
-extensions v3_attributes
# Confirm the contents of the new server certificate
openssl x509 -in server.cer -text -noout
# Verify the new server certificate against the root CA
openssl verify -CAfile root.cer server.cer
# Create the client CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout client.key \
-out client.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/CN=client"
# Confirm the contents of the client CSR
openssl req -in client.csr -text -noout
# Create the client .conf file
cat > /tmp/cert/client_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:FALSE
subjectAltName = DNS:client
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
EOF
# Create the client certificate
openssl x509 \
-req \
-sha256 \
-CA root.cer \
-CAkey root.key \
-in client.csr \
-out client.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/client_openssl.conf \
-extensions v3_attributes
# Confirm the contents of the new client certificate
openssl x509 -in client.cer -text -noout
# Verify the new client certificate against the root CA
openssl verify -CAfile root.cer client.cer
Thanks everyone!
Upvotes: 1