Comment 66 for bug 305264

Revision history for this message
Doug Engert (deengert) wrote : Re: [Bug 305264] Re: gnutls regression: failure in certificate chain validation

Copy of note sent on 1/8/2009:

Attached are the server cert (auth2.it.anl.gov), the intermediate cert (f0a38a80.0)
and the CA self signed cert (7651b327.0) a debug version of verify.c
and partial output of an ldapsearch using the debug.c

My patch has been #if 0'ed out at line 151.

   Lets refer to the cert chain as A, B and C. The OpenLDAP server (using OpenSSL)
sends server cert A, intermediate cert B, and CA cert C.

The TLS_CACERT file has B and C.

The clist_size is then 3, and the code in _gnutls_x509_verify_certificate
around lines 443 drop it to 2, leaving the chain as A, B.

The tcase_size is 2.

_gnutls_verify_certificate2 at line 452 is called with cert B and
tcas with B and C and flags 0.

At line 265, find_issuer is called with B. It returns C.
check_is_ca is called at line 297, which fails
because there is no BasicConstraint. The if at 293 looks correct too.

*BUT* if one trusts both B and C, do we need to verify C?
Why does the code arount line 265 not stop after finding that B is in the tcas,
rather then looking for C, and then verifying it?

If I try it again with the TLS_CACERT file with only B,
it also fails because it can not find the issuer of B.
If the code around line 265 was modified if B was found in the tcas,
this shopuld also work.

Simon Josefsson wrote:
> "Douglas E. Engert" <email address hidden> 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 <email address hidden>
>> 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
>> <email address hidden>
>> http://lists.gnu.org/mailman/listinfo/gnutls-devel
>
>

--

   Douglas E. Engert <email address hidden>
   Argonne National Laboratory
   9700 South Cass Avenue
   Argonne, Illinois 60439
   (630) 252-5444