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