[Pidgin] #17393: Failed to authenticate XMPP certificate when there is a name constraint

Pidgin 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:
----------------------+--------------------
 Hello,

 I'm using pidgin-2.13.0 from OpenSUSE Tumbleweed. We use an internal CA
 like this:

 * 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
 "2.5.29.37" extension and it assumes that certificate can be used by "any
 purpose".

 Well, my Intermediate CA has these key usage (2.5.29.15): "Certificate
 Sign, CRL Sign" and Basic Constraint CA:TRUE, but not Extended key usage
 (2.5.29.37).

 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>
Pidgin <https://pidgin.im>
Pidgin


More information about the Tracker mailing list