X-Git-Url: http://sjero.net/git/?a=blobdiff_plain;f=src%2Fopenssl.c;h=b85a042253de982f653a39cbad285f28a4ed68b5;hb=4a08094db88011153adadbf995103770b20d2a31;hp=f5239ede6e8f0b478a81625261a805165e13403c;hpb=e72b57629bf49cdfd663002a8bb336a67b958979;p=wget diff --git a/src/openssl.c b/src/openssl.c index f5239ede..b85a0422 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -1,6 +1,6 @@ /* SSL support via OpenSSL library. - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + 2009 Free Software Foundation, Inc. Originally contributed by Christian Fraenkel. This file is part of GNU Wget. @@ -124,7 +124,7 @@ init_prng (void) /* Print errors in the OpenSSL error stack. */ static void -print_errors (void) +print_errors (void) { unsigned long err; while ((err = ERR_get_error ()) != 0) @@ -364,7 +364,7 @@ openssl_close (int fd, void *arg) xfree_null (ctx->last_error); xfree (ctx); -#if defined(WINDOWS) || defined(MSDOS) +#if defined(WINDOWS) || defined(USE_WATT32) closesocket (fd); #else close (fd); @@ -390,7 +390,7 @@ static struct transport_implementation openssl_transport = { Returns true on success, false on failure. */ bool -ssl_connect (int fd) +ssl_connect_wget (int fd) { SSL *conn; struct openssl_transport_context *ctx; @@ -473,7 +473,7 @@ pattern_match (const char *pattern, const char *string) its certificate, corresponds to HOST. (HOST typically comes from the URL and is what the user thinks he's connecting to.) - This assumes that ssl_connect has successfully finished, i.e. that + This assumes that ssl_connect_wget has successfully finished, i.e. that the SSL handshake has been performed and that FD is connected to an SSL handle. @@ -512,7 +512,7 @@ ssl_check_certificate (int fd, const char *host) char *subject = X509_NAME_oneline (X509_get_subject_name (cert), 0, 0); char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0); DEBUGP (("certificate:\n subject: %s\n issuer: %s\n", - quotearg_style (escape_quoting_style, subject), + quotearg_style (escape_quoting_style, subject), quotearg_style (escape_quoting_style, issuer))); OPENSSL_free (subject); OPENSSL_free (issuer); @@ -524,7 +524,7 @@ ssl_check_certificate (int fd, const char *host) char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0); logprintf (LOG_NOTQUIET, _("%s: cannot verify %s's certificate, issued by %s:\n"), - severity, quotearg_style (escape_quoting_style, host), + severity, quotearg_style (escape_quoting_style, host), quote (issuer)); /* Try to print more user-friendly (and translated) messages for the frequent verification errors. */ @@ -569,9 +569,11 @@ ssl_check_certificate (int fd, const char *host) - Ensure that ASN1 strings from the certificate are encoded as UTF-8 which can be meaningfully compared to HOST. */ + X509_NAME *xname = X509_get_subject_name(cert); common_name[0] = '\0'; - X509_NAME_get_text_by_NID (X509_get_subject_name (cert), - NID_commonName, common_name, sizeof (common_name)); + X509_NAME_get_text_by_NID (xname, NID_commonName, common_name, + sizeof (common_name)); + if (!pattern_match (common_name, host)) { logprintf (LOG_NOTQUIET, _("\ @@ -579,6 +581,41 @@ ssl_check_certificate (int fd, const char *host) severity, quote (common_name), quote (host)); success = false; } + else + { + /* We now determine the length of the ASN1 string. If it differs from + * common_name's length, then there is a \0 before the string terminates. + * This can be an instance of a null-prefix attack. + * + * https://www.blackhat.com/html/bh-usa-09/bh-usa-09-archives.html#Marlinspike + * */ + + int i = -1, j; + X509_NAME_ENTRY *xentry; + ASN1_STRING *sdata; + + if (xname) { + for (;;) + { + j = X509_NAME_get_index_by_NID (xname, NID_commonName, i); + if (j == -1) break; + i = j; + } + } + + xentry = X509_NAME_get_entry(xname,i); + sdata = X509_NAME_ENTRY_get_data(xentry); + if (strlen (common_name) != ASN1_STRING_length (sdata)) + { + logprintf (LOG_NOTQUIET, _("\ +%s: certificate common name is invalid (contains a NUL character).\n\ +This may be an indication that the host is not who it claims to be\n\ +(that is, it is not the real %s).\n"), + severity, quote (host)); + success = false; + } + } + if (success) DEBUGP (("X509 certificate successfully verified and matches host %s\n",