diff options
author | Nikos Mavrogiannopoulos <nmav@crystal.(none)> | 2009-02-15 19:54:30 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@crystal.(none)> | 2009-02-15 19:54:30 +0200 |
commit | f98cc05f59d081f8abd8d1607d88aa608429e373 (patch) | |
tree | 71567897cb4e9c219ae7fa245b6ed3214003a619 | |
parent | a97743f8e6c76652ca86a830e27be2ce46437e5b (diff) | |
parent | 6ad4299bec6d74493a6fadfa48dbc8e401688894 (diff) | |
download | gnutls_2_4_x.tar.gz |
Merge branch 'gnutls_2_4_x' of ssh://git.sv.gnu.org/srv/git/gnutls into gnutls_2_4_xgnutls_2_4_x
-rw-r--r-- | ChangeLog | 49 | ||||
-rw-r--r-- | NEWS | 54 | ||||
-rw-r--r-- | lib/x509/verify.c | 129 |
3 files changed, 200 insertions, 32 deletions
@@ -1,3 +1,52 @@ +2009-02-06 Simon Josefsson <simon@josefsson.org> + + * NEWS: Version 2.4.3. + +2009-02-06 Simon Josefsson <simon@josefsson.org> + + * ChangeLog: Generated. + +2009-02-06 Simon Josefsson <simon@josefsson.org> + + * lib/x509/verify.c: Move down revocation check to revert code to + how it looked before. The idea is that if you have marked a cert as + trusted, you may want to trust it even though some authority has + revoked it. This changes back how this code used to work. + +2009-02-02 Simon Josefsson <simon@josefsson.org> + + * NEWS, lib/x509/verify.c: Back-port chain verification fixes. + +2008-10-28 Simon Josefsson <simon@josefsson.org> + + * NEWS: Add. + +2008-09-16 Simon Josefsson <simon@josefsson.org> + + * lib/opencdk/main.c, lib/opencdk/opencdk.h: Remove cdk_strerror, + unused and uses non-thread safe strerror. + +2008-10-28 Simon Josefsson <simon@josefsson.org> + + * NEWS: Add. + +2008-09-25 Simon Josefsson <simon@josefsson.org> + + * NEWS, configure.in: Bump versions. + +2008-09-23 Nikos Mavrogiannopoulos <nmav@crystal.(none)> + + * lib/x509/x509.c: Corrected buffer overrun in crt_list_import. + Reported and patch by Jonathan Manktelow. + +2008-09-15 Simon Josefsson <simon@josefsson.org> + + * Makefile.am: Update release target. + +2008-09-15 Simon Josefsson <simon@josefsson.org> + + * ChangeLog: Generated. + 2008-09-15 Simon Josefsson <simon@josefsson.org> * NEWS: Version 2.4.2. @@ -1,9 +1,59 @@ GNU TLS NEWS -- History of user-visible changes. -*- outline -*- -Copyright (C) 2004, 2005, 2006, 2007, 2008 Simon Josefsson +Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Simon Josefsson Copyright (C) 2000, 2001, 2002, 2003, 2004 Nikos Mavrogiannopoulos See the end for copying conditions. -* Version 2.4.3 (unreleased) +* Version 2.4.3 (released 2009-02-06) + +** libgnutls: Accept chains where intermediary certs are trusted. +Before GnuTLS needed to validate the entire chain back to a +self-signed certificate. GnuTLS will now stop looking when it has +found an intermediary trusted certificate. The new behaviour is +useful when chains, for example, contains a top-level CA, an +intermediary CA signed using RSA-MD5, and an end-entity certificate. +To avoid chain validation errors due to the RSA-MD5 cert, you can +explicitly add the intermediary RSA-MD5 cert to your trusted certs. +The signature on trusted certificates are not checked, so the chain +has a chance to validate correctly. Reported by "Douglas E. Engert" +<deengert@anl.gov> in +<http://thread.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/3351>. + +** libgnutls: Permit V1 Certificate Authorities properly. +Before they were mistakenly rejected even though +GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT and/or +GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT were supplied. Reported by +"Douglas E. Engert" <deengert@anl.gov> in +<http://thread.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/3351>. + +** libgnutls: deprecate X.509 validation chains using MD5 and MD2 signatures. +This is a bugfix -- the previous attempt to do this from internal x509 +certificate verification procedures did not return the correct value +for certificates using a weak hash. Reported by Daniel Kahn Gillmor +<dkg@fifthhorseman.net> in +<http://thread.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/3332>, +debugged and patch by Tomas Mraz <tmraz@redhat.com> and Daniel Kahn +Gillmor <dkg@fifthhorseman.net>. + +** libgnutls: Fix chain verification for chains that ends with RSA-MD2 CAs. +Reported by Michael Kiefer <Michael-Kiefer@web.de> in +<http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=507633> forwarded by +Andreas Metzler <ametzler@downhill.at.eu.org> in +<http://thread.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/3309>. + +** libgnutls: Fix crash in X.509 validation code for self-signed certificates. +The patch to fix the security problem GNUTLS-SA-2008-3 introduced a +problem for certificate chains that contained just one self-signed +certificate. Reported by Michael Meskes <meskes@debian.org> in +<http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=505279>. + +** libgnutls: Fix X.509 certificate chain validation error. [GNUTLS-SA-2008-3] +The flaw makes it possible for man in the middle attackers (i.e., +active attackers) to assume any name and trick GNU TLS clients into +trusting that name. Thanks for report and analysis from Martin von +Gagern <Martin.vGagern@gmx.net>. [CVE-2008-4989] + +Any updates with more details about this vulnerability will be added +to <http://www.gnu.org/software/gnutls/security.html> ** libgnutls: Fix buffer overrun in gnutls_x509_crt_list_import. Report and patch by Jonathan Manktelow. diff --git a/lib/x509/verify.c b/lib/x509/verify.c index 0c02c470ad..b0ea3722b3 100644 --- a/lib/x509/verify.c +++ b/lib/x509/verify.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation * * Author: Nikos Mavrogiannopoulos * @@ -42,17 +42,47 @@ static int _gnutls_verify_certificate2 (gnutls_x509_crt_t cert, const gnutls_x509_crt_t * trusted_cas, int tcas_size, unsigned int flags, unsigned int *output); -int _gnutls_x509_verify_signature (const gnutls_datum_t * signed_data, - const gnutls_datum_t * signature, - gnutls_x509_crt_t issuer); -static - int is_crl_issuer (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer_cert); +static int is_crl_issuer (gnutls_x509_crl_t crl, + gnutls_x509_crt_t issuer_cert); + static int _gnutls_verify_crl2 (gnutls_x509_crl_t crl, const gnutls_x509_crt_t * trusted_cas, int tcas_size, unsigned int flags, unsigned int *output); +/* Checks if two certs are identical. Return 0 onn match. */ +static int +check_if_same_cert (gnutls_x509_crt_t cert1, gnutls_x509_crt_t cert2) +{ + gnutls_datum_t cert1bin = { NULL, 0 }, cert2bin = { NULL, 0 }; + int result; + + result = _gnutls_x509_der_encode (cert1->cert, "", &cert1bin, 0); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_x509_der_encode (cert2->cert, "", &cert2bin, 0); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + if ((cert1bin.size == cert2bin.size) && + (memcmp (cert1bin.data, cert2bin.data, cert1bin.size) == 0)) + result = 0; + else + result = 1; + + cleanup: + _gnutls_free_datum (&cert1bin); + _gnutls_free_datum (&cert2bin); + return result; +} /* Checks if the issuer of a certificate is a * Certificate Authority, or if the certificate is the same @@ -127,11 +157,23 @@ check_if_ca (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer, } } - 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; } + /* Handle V1 CAs that do not have a basicConstraint, but accept + these certs only if the appropriate flags are set. */ + else if ((result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) && + ((flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT) || + ((flags & GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT) && + (gnutls_x509_crt_check_issuer (issuer, issuer) == 1)))) + { + gnutls_assert (); + result = 1; + goto cleanup; + } else gnutls_assert (); @@ -322,6 +364,7 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert, { if (output) *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID; + ret = 0; } } @@ -354,16 +397,12 @@ gnutls_x509_crt_check_issuer (gnutls_x509_crt_t cert, } -/* The algorithm used is: - * 1. Check last certificate in the chain. If it is not verified return. - * 2. Check if any certificates in the chain are revoked. If yes return. - * 3. Try to verify the rest of certificates in the chain. If not verified return. - * 4. Return 0. +/* Verify X.509 certificate chain. * * Note that the return value is an OR of GNUTLS_CERT_* elements. * - * This function verifies a X.509 certificate list. The certificate list should - * lead to a trusted CA in order to be trusted. + * This function verifies a X.509 certificate list. The certificate + * list should lead to a trusted certificate in order to be trusted. */ static unsigned int _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list, @@ -376,16 +415,56 @@ _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 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--; + } + } + + /* We want to shorten the chain by removing the cert that matches + * one of the certs we trust and all the certs after that i.e. if + * cert chain is A signed-by B signed-by C signed-by D (signed-by + * self-signed E but already removed above), and we trust B, remove + * B, C and D. We must leave the first cert on chain. */ + if (clist_size > 1 && !(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME)) + { + for (i = 1; i < clist_size; i++) + { + int j; + + for (j = 0; j < tcas_size; j++) + { + if (check_if_same_cert (certificate_list[i], + trusted_cas[j]) == 0) + { + clist_size = i; + break; + } + } + /* clist_size may have been changed which gets out of loop */ + } + } + /* Verify the last certificate in the certificate path * against the trusted CA certificate list. * * If no CAs are present returns CERT_INVALID. Thus works * in self signed etc certificates. */ - ret = - _gnutls_verify_certificate2 (certificate_list[clist_size - 1], - trusted_cas, tcas_size, flags, &output); - + ret = _gnutls_verify_certificate2 (certificate_list[clist_size - 1], + trusted_cas, tcas_size, flags, &output); if (ret == 0) { /* if the last certificate in the certificate @@ -414,18 +493,7 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list, } #endif - /* 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). - */ - if (gnutls_x509_crt_check_issuer (certificate_list[clist_size - 1], - certificate_list[clist_size - 1]) > 0 - && clist_size > 0) - { - clist_size--; - } - - /* Verify the certificate path (chain) + /* Verify the certificate path (chain) */ for (i = clist_size - 1; i > 0; i--) { @@ -1031,6 +1099,7 @@ _gnutls_verify_crl2 (gnutls_x509_crl_t crl, { if (output) *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID; + ret = 0; } } |