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