Certificate is considered as invalid if trust store contains CA cert with duplicating extensions
Description of problem:
gnutls treats certificates as invalid if trust store contains a cert with duplicating extensions. It looks like in a such case when gnutls loads certs from trust store and meets one with duplicating extensions it aborts the whole load and finally has zero trusted CA certs for verification procedure.
I hit this problem after the recent update of Homebrew on my macOS 11.4 when openconnect which uses gnutls stopped connecting to VPN server. Digging deeper showed that trust store was rebuilt with System keychain which contains "com.apple.kerberos.kdc" certificate with two "Extended Key Usage" extensions on my system.
Version of gnutls used:
3.6.16
Distributor of gnutls (e.g., Ubuntu, Fedora, RHEL)
Homebrew (macOS 11.4)
How reproducible:
Here I'm using gnutls repository as a source of certificates. And gnutls-certtool binary from Homebrew installation.
Steps to Reproduce:
- Checkout gnutls repo
$ git clone https://github.com/gnutls/gnutls.git && cd gnutls
- Generate test certificate
$ gnutls-certtool --generate-privkey --bits 4096 --outfile test.key ** Note: You may use '--sec-param High' instead of '--bits 4096' Generating a 4096 bit RSA private key... $ gnutls-certtool --generate-certificate --load-ca-certificate tests/ocsp-tests/certs/ca.pem --load-ca-privkey tests/ocsp-tests/certs/ca.key --load-privkey test.key --outfile test.pem Generating a signed certificate... Please enter the details of the certificate's distinguished name. Just press enter to ignore a field. Common name: test UID: Organizational unit name: test Organization name: test Locality name: State or province name: Country name (2 chars): Enter the subject's domain component (DC): This field should not be used in new certificates. E-mail: Enter the certificate's serial number in decimal (123) or hex (0xabcd) (default is 0x0410fb0070d12440dfb74d2b867ac95584006b7d) value: Activation/Expiration time. The certificate will expire in (days): 1 Extensions. Does the certificate belong to an authority? (y/N): N Is this a TLS web client certificate? (y/N): N Will the certificate be used for IPsec IKE operations? (y/N): N Is this a TLS web server certificate? (y/N): y Enter a dnsName of the subject of the certificate: test Enter an additional dnsName of the subject of the certificate: Enter a URI of the subject of the certificate: Enter the IP address of the subject of the certificate: Will the certificate be used for signing (DHE ciphersuites)? (Y/n): n Will the certificate be used for encryption (RSA ciphersuites)? (Y/n): n Will the certificate be used for data encryption? (y/N): N Will the certificate be used to sign OCSP requests? (y/N): N Will the certificate be used to sign code? (y/N): Will the certificate be used for time stamping? (y/N): N Will the certificate be used for email protection? (y/N): N <...skipped...> Signing certificate...
- Test new cert is ok:
$ cp tests/ocsp-tests/certs/ca.pem trust-store.pem $ gnutls-certtool --load-ca-certificate trust-store.pem --verify --infile test.pem Loaded CAs (1 available) Subject: O=test,OU=test,CN=test Issuer: CN=Testing Authority Checked against: CN=Testing Authority Signature algorithm: RSA-SHA256 Output: Verified. The certificate is trusted. Chain verification output: Verified. The certificate is trusted.
- Add certificate with duplicating extensions to trust store and check our cert:
$ cat tests/cert-tests/data/dup-exts.pem >>trust-store.pem $ gnutls-certtool --load-ca-certificate trust-store.pem --verify --infile test.pem
Actual results:
Test certificate is considered invalid:
Note that no verification profile was selected. In the future the medium profile will be enabled by default.
Use --verify-profile low to apply the default verification of NORMAL priority string.
gnutls_x509_trust_add_trust_file: Duplicate extension in X.509 certificate.
Expected results:
Test certificate is considered valid because trust store does contain proper valid CA certificate.