summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@crystal.(none)>2009-02-15 19:54:30 +0200
committerNikos Mavrogiannopoulos <nmav@crystal.(none)>2009-02-15 19:54:30 +0200
commitf98cc05f59d081f8abd8d1607d88aa608429e373 (patch)
tree71567897cb4e9c219ae7fa245b6ed3214003a619
parenta97743f8e6c76652ca86a830e27be2ce46437e5b (diff)
parent6ad4299bec6d74493a6fadfa48dbc8e401688894 (diff)
downloadgnutls_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--ChangeLog49
-rw-r--r--NEWS54
-rw-r--r--lib/x509/verify.c129
3 files changed, 200 insertions, 32 deletions
diff --git a/ChangeLog b/ChangeLog
index aed6f3a5a9..8c7461ec43 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/NEWS b/NEWS
index 13975112bf..38f1b15ff3 100644
--- a/NEWS
+++ b/NEWS
@@ -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;
}
}