gnutls fails to use Verisign CA cert without a Basic Constraint
Simon Josefsson
simon at josefsson.org
Thu Jan 8 09:15:00 CET 2009
"Douglas E. Engert" <deengert at anl.gov> writes:
> This is also being submitted to https://bugs.launchpad.net/bugs
>
> Using the Ubuntu version of libgnutls13_2.0.4-1ubuntu2.3 on Hardy 8.04.1,
> ldaps: has stopped working. This looks like it is related to
> the December changes that are also in gnutls-2.6.3. See attached
> patch that should work in both.
>
> ldapsearch -d 1 -H ldaps://...
>
> TLS: peer cert untrusted or revoked (0x82)
> ldap_err2string
> ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
>
>
> The OpenLDAP ldap server certificate issued by Verisign is signed by:
>
> Verisign_Intermediate-Secure_Site_Managed_PKI_for_SSL_Standard_Certificates.pem
>
> which is signed by:
> Verisign_Class_3_Public_Primary_Certification_Authority.pem
>
> Both of these are in /etc/ssl/certs as 7651b327.0 and f0a38a80.0
>
> Verisign_Class_3_Public_Primary_Certification_Authority.pem
> is a self signed version 1 cert issued in 1996, with no extensions.
Do you have a complete chain that triggers this? It will help our
regression test suite.
I don't have f0a38a80.0 on my debian lenny system. Does it also lack a
basicConstraint? Does it use RSA-MDx? If yes, that would explain the
problem.
> In lib/x509/verify.c gnutls_x509_crt_get_ca_status is called
> but returns GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE as there is no
> Basic Constraint.
>
> The attached patch (to gnutls13_2.0.4-1ubuntu2.3) checks for
> this return and if it is a self signed cert, will treat it as a CA.
> The patch looks like it can be applied to 2.6.3 as well.
The patch seems too permissive to me: the intention is that V1 certs
should be rejected by GnuTLS unless GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT
and/or GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT are passed as flags.
Internally, GnuTLS by default enables the
GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT flag when called via
gnutls_certificate_verify_peers2. So I think GnuTLS should typically
accept this chain.
Indeed, looking at the code that invokes the function you patched:
if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) &&
!((flags & GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT) && issuer_version == 1))
{
if (check_if_ca (cert, issuer, flags) == 0)
{
gnutls_assert ();
if (output)
*output |= GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
return 0;
}
}
It seems that the code you patched should not have been invoked at all
if (flags & GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT) && issuer_version == 1
is true (if I understand the logic correctly..). Could you debug why
this isn't the case? Maybe issuer_version is wrong?
A complete chain to reproduce this will let me debug it too.
/Simon
> Clients on Solaris 9 and 10, and OpenLDAP using OpenSSL on any
> platform have no problems with this old cert.
>
>
>
>
> --
>
> Douglas E. Engert <DEEngert at anl.gov>
> Argonne National Laboratory
> 9700 South Cass Avenue
> Argonne, Illinois 60439
> (630) 252-5444
> --- ,verify.c 2009-01-06 14:02:41.000000000 -0600
> +++ verify.c 2009-01-07 17:07:27.000000000 -0600
> @@ -130,11 +130,20 @@
> }
> }
>
> - if (gnutls_x509_crt_get_ca_status (issuer, NULL) == 1)
> + result = gnutls_x509_crt_get_ca_status (issuer, NULL);
> + if (result == 1)
> {
> result = 1;
> goto cleanup;
> }
> + /* Old self signed CA certs may not have basic constrant */
> + else if ((result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) &&
> + (gnutls_x509_crt_check_issuer(issuer, issuer) == 1))
> + {
> + gnutls_assert ();
> + result = 1;
> + goto cleanup;
> + }
> else
> gnutls_assert ();
>
> _______________________________________________
> Gnutls-devel mailing list
> Gnutls-devel at gnu.org
> http://lists.gnu.org/mailman/listinfo/gnutls-devel
More information about the Gnutls-devel
mailing list