[Pidgin] #17393: Failed to authenticate XMPP certificate when there is a name constraint
trac at pidgin.im
Wed May 29 18:48:54 EDT 2019
#17393: Failed to authenticate XMPP certificate when there is a name constraint
Reporter: luizluca | Owner: deryni
Type: defect | Status: new
Milestone: | Component: XMPP
Version: 2.13.0 | Keywords:
I'm using pidgin-2.13.0 from OpenSUSE Tumbleweed. We use an internal CA
* Root CA
* Intermediate CA
* Servers certificates
Root CA has some name constraints that restrict valid certificates to only
certain DNS domains that are under our control.
Since a long time, pidgin (and not all other SSL apps) fails to validate
our server certificate. We are manually importing certificate to allow
user to connect.
I debugged pidgin until I found the problem. pidgin has
x509_certificate_signed_by to test a certificate validity. It will be
called twice in my case:
* x509_certificate_signed_by("server_certificate", "Intermediate CA")
* x509_certificate_signed_by("Intermediate CA", "Root CA")
In that pidgin function, it calls gnutls_x509_crt_verify (a
_gnutls_verify_crt_status wrapper) passing the certificate being tested
and only the issuer as the "list of ca certificates"
_gnutls_verify_crt_status eventually calls "verify_crt()". It only
checks name constrainst against the certificate and not against CA
certificates. However, at the second call of x509_certificate_signed_by,
"Intermediate CA" is considered the "server certificate".
verify_crt() calls gnutls_x509_name_constraints_check_crt(vparams->nc,
GNUTLS_SAN_DNSNAME, cert), which will test name constraints agains DNSNAME
(subjetAltName). However, if no subjetAltName was found, it will also test
against CN but only "verify the name constraints against the CN, if the
certificate is not a CA. We do this check only on certificates marked as
WWW server, because that's where the CN check is only performed.".
It checks if it is a "server certificate" and not a CA using
_gnutls_check_key_purpose that calls gnutls_x509_crt_get_key_purpose_oid.
gnutls_x509_crt_get_key_purpose_oid simply bails out if there is no
"18.104.22.168" extension and it assumes that certificate can be used by "any
Well, my Intermediate CA has these key usage (22.214.171.124): "Certificate
Sign, CRL Sign" and Basic Constraint CA:TRUE, but not Extended key usage
My Intermediate CA is considered as a "Web Server". As it normally
happens, my Intermediate CA CN will not be a valid DNS name that satisfy
Root CA DNS Name constraint. "Intermediate CA" certificate is rejected and
also "Server certificate".
The problem is that x509_certificate_signed_by should not exist. While
testing certs two-by-two, it introduces two major problems:
1) intermediate CA are treated as server certificate. gnutls wouldn't
check name constraints if it knew it was a CA certificate
2) while testing server certificate, gnutls does not know any name
constraints from anything but the issuer. If the chain was longer, any
intermediate CA constraint and specially Root CA constraint will never be
checked against server name.
I also debugged gnutls-cli to see what it does correctly (it works there).
It uses gnutls_certificate_verify_peers, that calls
gnutls_x509_trust_list_verify_crt2 which will use _gnutls_x509_crt_verify.
_gnutls_x509_crt_verify is used passing the server certificate and the
"list of CA certificates" while piding uses it (actually its wapper
gnutls_x509_crt_verify) passing each time only the issuer certificate as
the "list of CA certificates".
I hope this issue gets finally fixed.
Ticket URL: <https://developer.pidgin.im/ticket/17393>
More information about the Tracker