简体   繁体   中英

OpenSSL verify: “error 20 at 0 depth lookup: unable to get local issuer certificate” between different OpenSSL versions

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):

  • docker run -it ubuntu:18.04 /bin/bash
  • docker run -it ubuntu:20.04 /bin/bash

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!

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM