Bug#507633: libgnutls26: GnuTLS does not know VeriSign any more

Simon Josefsson simon at josefsson.org
Wed Dec 10 13:00:23 CET 2008


Nikos Mavrogiannopoulos <nmav at gnutls.org> writes:

> Simon Josefsson wrote:
>
>>>> gnutls-cli  -p 443 hbci-pintan-rp.s-hbci.de --x509cafile \
>>>> /etc/ssl/certs/ca-certificates.crt
>>> It seems to me that MD2 is missing from newer gnutls and this is the
>>> reason why it fails. libgcrypt has the MD2 enumeration but not the
>>> actual implementation and this tricked me into removing the included
>>> md2. I will try to revert the old behavior of using an included version
>>> of md2.
>> 
>> I don't think MD2 should be required here: chain verification should not
>> need to verify the RSA-MD2 self-signature in the CA cert, because that
>> cert is marked as trusted.
>> 
>> If there were other MD2 signatures involved, verification should
>> definitely fail, but that doesn't seem to be the case with this chain.
>> 
>> It seems this problem is caused by the chain validation algorithm now
>> also look at the CA cert, but it didn't before the GNUTLS-SA-2008-3
>> patch.
>
> I've added again the GNUTLS-SA-2008-3 patch this time with some checks
> to avoid the crashes.

I believe that is wrong: with your patch it will fail when the CA is
self-signed using RSA-MD2.  Reproduce using the new self-test
chainverify.c which (I believe) includes all the example chains that
have been mentioned in bug reports so far.

I believe the patch in 2.6.2 is the right thing to solve the
GNUTLS-SA_2008-3 problem.

The problem we are discussing now is that chains that end with an
trusted anchor using RSA-MD2 incorrectly fails verification.  So we need
to fix that problem.

The patch below (against master) does:

1) Revert your patch.
2) In _gnutls_verify_certificate2 it now skips further tests when the
   certificate is already trusted.

This passed both 'chainverify.c' and 'cve-2008-4989.c'.  Please test
further iterations (if any) against those self-tests.

/Simon

>From 071beb6e8038bf5ffc1d63eb0b249a37ffa80ed3 Mon Sep 17 00:00:00 2001
From: Simon Josefsson <simon at josefsson.org>
Date: Wed, 10 Dec 2008 12:57:19 +0100
Subject: [PATCH] Revert Nikos revert, and fix verification hopefully better.
 The new logic is to include the CA cert in validation,
 but short-cut full validation of trusted certificates.

---
 NEWS              |    6 ++++++
 lib/x509/verify.c |   49 ++++++++++++++-----------------------------------
 2 files changed, 20 insertions(+), 35 deletions(-)

diff --git a/NEWS b/NEWS
index 0b93c8d..021af4e 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,12 @@ See the end for copying conditions.
 
 * Version 2.7.3 (unreleased)
 
+** gnutls: Fix chain verification for chains that ends with RSA-MD2 CAs.
+Reported by Michael Kiefer <Michael-Kiefer at web.de> in
+<http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=507633> forwarded by
+Andreas Metzler <ametzler at downhill.at.eu.org> in
+<http://thread.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/3309>.
+
 ** gnutls: Libgcrypt initialization changed.
 If libgcrypt has not already been initialized, GnuTLS will now
 initialize libgcrypt with disabled secure memory.  Initialize
diff --git a/lib/x509/verify.c b/lib/x509/verify.c
index 00e2422..6fc635a 100644
--- a/lib/x509/verify.c
+++ b/lib/x509/verify.c
@@ -226,6 +226,7 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
   gnutls_datum_t cert_signature = { NULL, 0 };
   gnutls_x509_crt_t issuer;
   int ret, issuer_version, result;
+  int sigalg;
 
   if (output)
     *output = 0;
@@ -251,6 +252,11 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
       return 0;
     }
 
+  /* If self-issued, it is one of our trusted certs.  Don't bother
+     testing an explicitly trusted cert further. */
+  if (is_issuer (cert, cert))
+    return 1;
+
   issuer_version = gnutls_x509_crt_get_version (issuer);
   if (issuer_version < 0)
     {
@@ -303,24 +309,15 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
       ret = 0;
     }
 
-  /* If the certificate is not self signed check if the algorithms
-   * used are secure. If the certificate is self signed it doesn't
-   * really matter.
-   */
-  if (is_issuer (cert, cert) == 0)
-    {
-      int sigalg;
-
-      sigalg = gnutls_x509_crt_get_signature_algorithm (cert);
+  sigalg = gnutls_x509_crt_get_signature_algorithm (cert);
 
-      if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
-	   !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
-	  ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
-	   !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
-	{
-	  if (output)
-	    *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
-	}
+  if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
+       !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
+      ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
+       !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
+    {
+      if (output)
+	*output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
     }
 
   result = ret;
@@ -374,24 +371,6 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list,
   int i = 0, ret;
   unsigned int status = 0, output;
 
-  if (clist_size > 1) 
-    {
-      /* Check if the last certificate in the path is self signed.
-       * In that case ignore it (a certificate is trusted only if it
-       * leads to a trusted party by us, not the server's).
-       *
-       * This in addition prevents from verifying self signed certificates
-       * against themselves. This although not bad caused verification
-       * failures on some root self signed certificates that use the MD2
-       * algorithm.
-       */
-      if (gnutls_x509_crt_check_issuer (certificate_list[clist_size - 1],
-  				    certificate_list[clist_size - 1]) > 0)
-        {
-          clist_size--;
-        }
-    }
-
   /* Verify the last certificate in the certificate path
    * against the trusted CA certificate list.
    *
-- 
1.5.6.5







More information about the Gnutls-devel mailing list