[Bug 1926254] Re: x509 Certificate verification fails when basicConstraints=CA:FALSE, pathlen:0 on self-signed leaf certs
Matthew Ruffell
1926254 at bugs.launchpad.net
Wed May 12 00:58:01 UTC 2021
Performing verification for Focal
Generating the ssl certificates, and reproducing the problem with version
1.1.1f-1ubuntu2.3 from -updates.
ubuntu at select-lobster:~$ sudo apt-cache policy openssl | grep Installed
Installed: 1.1.1f-1ubuntu2.3
ubuntu at select-lobster:~$ mkdir reproducer
ubuntu at select-lobster:~$ cd reproducer
ubuntu at select-lobster:~/reproducer$ mkdir CA
ubuntu at select-lobster:~/reproducer$ cat << EOF >> rootCA.cnf
> [ req ]
> prompt = no
> distinguished_name = req_distinguished_name
> x509_extensions = usr_cert
>
> [ req_distinguished_name ]
> C = DE
> O = Test Org
> CN = Test RSA PSS Root-CA
>
> [ usr_cert ]
> basicConstraints = critical,CA:TRUE
> keyUsage = critical,keyCertSign,cRLSign
> subjectKeyIdentifier = hash
> authorityKeyIdentifier = keyid:always
> EOF
ubuntu at select-lobster:~/reproducer$ cat << EOF >> subCA.cnf
> [ req ]
> prompt = no
> distinguished_name = req_distinguished_name
> x509_extensions = usr_cert
>
> [ req_distinguished_name ]
> C = DE
> O = Test Org
> CN = Test RSA PSS Sub-CA
>
> [ usr_cert ]
> basicConstraints = critical,CA:TRUE,pathlen:0
> keyUsage = critical,keyCertSign,cRLSign
> subjectKeyIdentifier = hash
> authorityKeyIdentifier = keyid:always
> EOF
ubuntu at select-lobster:~/reproducer$ cat << EOF >> user.cnf
> [ req ]
> prompt = no
> distinguished_name = req_distinguished_name
> x509_extensions = usr_cert
>
> [ req_distinguished_name ]
> C = DE
> O = Test Org
> CN = Test User
>
> [ usr_cert ]
> basicConstraints = critical,CA:FALSE,pathlen:0
> keyUsage = critical,digitalSignature,keyAgreement
> extendedKeyUsage = clientAuth,serverAuth
> subjectKeyIdentifier = hash
> authorityKeyIdentifier = keyid:always
> EOF
ubuntu at select-lobster:~/reproducer$ openssl genpkey -algorithm RSA-PSS -out rootCA_key.pem -pkeyopt rsa_keygen_bits:2048
......................+++++
............+++++
ubuntu at select-lobster:~/reproducer$ openssl req -config rootCA.cnf -set_serial 01 -new -batch -sha256 -nodes -x509 -days 9125 -out CA/rootCA_cert.pem -key rootCA_key.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1
ubuntu at select-lobster:~/reproducer$ openssl genpkey -algorithm RSA-PSS -out subCA_key.pem -pkeyopt rsa_keygen_bits:2048
........+++++
....+++++
ubuntu at select-lobster:~/reproducer$ openssl req -config subCA.cnf -new -out subCA_req.pem -key subCA_key.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1
ubuntu at select-lobster:~/reproducer$ openssl x509 -req -sha256 -in subCA_req.pem -CA CA/rootCA_cert.pem -CAkey rootCA_key.pem -out CA/subCA_cert.pem -CAserial rootCA_serial.txt -CAcreateserial -extfile subCA.cnf -extensions usr_cert -days 4380 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1
Signature ok
subject=C = DE, O = Test Org, CN = Test RSA PSS Sub-CA
Getting CA Private Key
ubuntu at select-lobster:~/reproducer$ c_rehash CA
Doing CA
ubuntu at select-lobster:~/reproducer$ openssl genpkey -algorithm RSA-PSS -out user1_key.pem -pkeyopt rsa_keygen_bits:2048
...................+++++
.........................+++++
ubuntu at select-lobster:~/reproducer$ openssl req -config user.cnf -new -out user1_req.pem -key user1_key.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1
ubuntu at select-lobster:~/reproducer$ openssl x509 -req -sha256 -in user1_req.pem -CA CA/subCA_cert.pem -CAkey subCA_key.pem -out user1_cert.pem -CAserial subCA_serial.txt -CAcreateserial -extfile user.cnf -extensions usr_cert -days 1825 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1
Signature ok
subject=C = DE, O = Test Org, CN = Test User
Getting CA Private Key
Now, we verify the certificates:
ubuntu at select-lobster:~/reproducer$ openssl verify -CAfile CA/rootCA_cert.pem -untrusted CA/subCA_cert.pem user1_cert.pem
C = DE, O = Test Org, CN = Test User
error 20 at 0 depth lookup: unable to get local issuer certificate
error user1_cert.pem: verification failed
We see verification fail, due to CA:FALSE,pathlen:0 basicConstraints.
I then enabled -proposed, and installed openssl and libssl1.1 version
1.1.1f-1ubuntu2.4
If we then repeat the certificate validation:
ubuntu at select-lobster:~/reproducer$ openssl verify -CAfile CA/rootCA_cert.pem -untrusted CA/subCA_cert.pem user1_cert.pem
user1_cert.pem: OK
The certificates validate properly.
Additionally, if we examine the new unit tests added to openssl's testsuite in
the buildlog for focal:
https://launchpadlibrarian.net/537505620/buildlog_ubuntu-focal-
amd64.openssl_1.1.1f-1ubuntu2.4_BUILDING.txt.gz
we see:
../../../test/certs/ee-pathlen.pem: OK
../../util/shlib_wrap.sh ../../apps/openssl verify -auth_level 1 -purpose sslserver -trusted ../../../test/certs/root-cert.pem -untrusted ../../../test/certs/ca-cert.pem ../../../test/certs/ee-pathlen.pem => 0
ok 84 - accept non-ca with pathlen:0 by default
CN = server.example
error 41 at 0 depth lookup: invalid or inconsistent certificate extension
error ../../../test/certs/ee-pathlen.pem: verification failed
../../util/shlib_wrap.sh ../../apps/openssl verify -auth_level 1 -purpose sslserver -x509_strict -trusted ../../../test/certs/root-cert.pem -untrusted ../../../test/certs/ca-cert.pem ../../../test/certs/ee-pathlen.pem => 2
ok 85 - reject non-ca with pathlen:0 with strict flag
Both tests pass with "ok", so the feature is working as intended in both
standard and strict mode.
Since everything is in order, I am happy to mark verified for Focal.
** Tags removed: verification-needed-focal
** Tags added: verification-done-focal
--
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to openssl in Ubuntu.
https://bugs.launchpad.net/bugs/1926254
Title:
x509 Certificate verification fails when
basicConstraints=CA:FALSE,pathlen:0 on self-signed leaf certs
Status in openssl package in Ubuntu:
Fix Released
Status in openssl source package in Focal:
Fix Committed
Status in openssl source package in Groovy:
Fix Committed
Status in openssl source package in Hirsute:
Fix Released
Bug description:
[Impact]
In openssl 1.1.1f, the below commit was merged:
commit ba4356ae4002a04e28642da60c551877eea804f7
Author: Bernd Edlinger <bernd.edlinger at hotmail.de>
Date: Sat Jan 4 15:54:53 2020 +0100
Subject: Fix error handling in x509v3_cache_extensions and related functions
Link: https://github.com/openssl/openssl/commit/ba4356ae4002a04e28642da60c551877eea804f7
This introduced a regression which caused certificate validation to
fail when certificates violate RFC 5280 [1], namely, when a
certificate has "basicConstraints=CA:FALSE,pathlen:0". This
combination is commonly seen by self-signed leaf certificates with an
intermediate CA before the root CA.
Because of this, openssl 1.1.1f rejects these certificates and they
cannot be used in the system certificate store, and ssl connections
fail when you try to use them to connect to a ssl endpoint.
The error you see when you try verify is:
$ openssl verify -CAfile CA/rootCA_cert.pem -untrusted CA/subCA_cert.pem user1_cert.pem
error 20 at 0 depth lookup: unable to get local issuer certificate
error user1_cert.pem: verification failed
The exact same certificates work fine on Xenial, Bionic and Hirsute.
[1] https://tools.ietf.org/html/rfc5280.html
[Testcase]
We will create our own root CA, intermediate CA and leaf server
certificate.
Create necessary directories:
$ mkdir reproducer
$ cd reproducer
$ mkdir CA
Write openssl configuration files to disk for each CA and cert:
$ cat << EOF >> rootCA.cnf
[ req ]
prompt = no
distinguished_name = req_distinguished_name
x509_extensions = usr_cert
[ req_distinguished_name ]
C = DE
O = Test Org
CN = Test RSA PSS Root-CA
[ usr_cert ]
basicConstraints = critical,CA:TRUE
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
EOF
$ cat << EOF >> subCA.cnf
[ req ]
prompt = no
distinguished_name = req_distinguished_name
x509_extensions = usr_cert
[ req_distinguished_name ]
C = DE
O = Test Org
CN = Test RSA PSS Sub-CA
[ usr_cert ]
basicConstraints = critical,CA:TRUE,pathlen:0
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
EOF
$ cat << EOF >> user.cnf
[ req ]
prompt = no
distinguished_name = req_distinguished_name
x509_extensions = usr_cert
[ req_distinguished_name ]
C = DE
O = Test Org
CN = Test User
[ usr_cert ]
basicConstraints = critical,CA:FALSE,pathlen:0
keyUsage = critical,digitalSignature,keyAgreement
extendedKeyUsage = clientAuth,serverAuth
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
EOF
Then generate the necessary RSA keys and form certificates:
$ openssl genpkey -algorithm RSA-PSS -out rootCA_key.pem -pkeyopt rsa_keygen_bits:2048
$ openssl req -config rootCA.cnf -set_serial 01 -new -batch -sha256 -nodes -x509 -days 9125 -out CA/rootCA_cert.pem -key rootCA_key.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1
$ openssl genpkey -algorithm RSA-PSS -out subCA_key.pem -pkeyopt rsa_keygen_bits:2048
$ openssl req -config subCA.cnf -new -out subCA_req.pem -key subCA_key.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1
$ openssl x509 -req -sha256 -in subCA_req.pem -CA CA/rootCA_cert.pem -CAkey rootCA_key.pem -out CA/subCA_cert.pem -CAserial rootCA_serial.txt -CAcreateserial -extfile subCA.cnf -extensions usr_cert -days 4380 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1
$ c_rehash CA
$ openssl genpkey -algorithm RSA-PSS -out user1_key.pem -pkeyopt rsa_keygen_bits:2048
$ openssl req -config user.cnf -new -out user1_req.pem -key user1_key.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1
$ openssl x509 -req -sha256 -in user1_req.pem -CA CA/subCA_cert.pem -CAkey subCA_key.pem -out user1_cert.pem -CAserial subCA_serial.txt -CAcreateserial -extfile user.cnf -extensions usr_cert -days 1825 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1
Now, let's try verify the generated certificates:
$ openssl version
OpenSSL 1.1.1f 31 Mar 2020
$ openssl verify -CAfile CA/rootCA_cert.pem -untrusted CA/subCA_cert.pem user1_cert.pem
error 20 at 0 depth lookup: unable to get local issuer certificate
error user1_cert.pem: verification failed
There are test packages available in the following ppa:
https://launchpad.net/~mruffell/+archive/ubuntu/sf308725-test
If you install these test packages, and attempt to verify, things work
as planned.
$ openssl verify -CAfile CA/rootCA_cert.pem -untrusted CA/subCA_cert.pem user1_cert.pem
user1_cert.pem: OK
[Where problems could occur]
If a regression were to occur, it would occur around x509 certificate
parsing and validation. It may cause certificates which had previously
passed to fail, or certificates which failed to pass. It could
potentially cause all certificates to fail or pass.
Since this is the openssl package and the package is security-
critical, this will need a lot of validation, testing, and likely a
review by the security team.
One of the commits which fixes the issue adds two testcases to the
openssl testsuite, which tests the "CA:FALSE, pathlen:0" certificates
with and without -x509_strict, and tests to see if it passes without,
and fails with.
[Other info]
This was reported in the upstream issue #11456 [2]:
[2] https://github.com/openssl/openssl/issues/11456
I believe these three commits fix the issue:
commit 00a0da2f021e6a0bc9519a6a9e5be66d45e6fc91
Author: Tomas Mraz <tmraz at fedoraproject.org>
Date: Thu Apr 2 15:56:12 2020 +0200
Subject: Allow certificates with Basic Constraints CA:false, pathlen:0
Link: https://github.com/openssl/openssl/commit/00a0da2f021e6a0bc9519a6a9e5be66d45e6fc91
commit 29e94f285f7f05b1aec6fa275e320bc5fa37ab1e
Author: Tomas Mraz <tmraz at fedoraproject.org>
Date: Thu Apr 2 17:31:21 2020 +0200
Subject: Set X509_V_ERR_INVALID_EXTENSION error for invalid basic constraints
Link: https://github.com/openssl/openssl/commit/29e94f285f7f05b1aec6fa275e320bc5fa37ab1e
commit e78f2a8f269a4dcf820ca994e2b89b77972d79e1
Author: Tomas Mraz <tmraz at fedoraproject.org>
Date: Fri Apr 3 10:24:40 2020 +0200
Subject: Add test cases for the non CA certificate with pathlen:0
Link: https://github.com/openssl/openssl/commit/e78f2a8f269a4dcf820ca994e2b89b77972d79e1
These landed in openssl 1.1.1g, and hirsute already has these fixes.
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/1926254/+subscriptions
More information about the foundations-bugs
mailing list