diff options
author | 2010-11-19 03:00:15 +0000 | |
---|---|---|
committer | 2010-11-19 03:00:15 +0000 | |
commit | 764e1a8db6f9dad6fb0c2361177a92f72820c621 (patch) | |
tree | 5197ab95d858e347e0aa3be148c45b481c69686b | |
parent | do not run makedev for a uid; ok krw (diff) | |
download | wireguard-openbsd-764e1a8db6f9dad6fb0c2361177a92f72820c621.tar.xz wireguard-openbsd-764e1a8db6f9dad6fb0c2361177a92f72820c621.zip |
Fix the "SSL error:host(blah)!=cert(*.blah)-Continue? (y)" error when going
to sites using wildcard certs (i.e. github.com). Adapted from lynx 2.8.7.
deraadt@ ok.
-rw-r--r-- | gnu/usr.bin/lynx/WWW/Library/Implementation/HTTP.c | 73 |
1 files changed, 69 insertions, 4 deletions
diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTP.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTP.c index e1a5bf538ad..072231d3789 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTP.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTP.c @@ -42,6 +42,10 @@ #include <LYrcFile.h> #include <LYLeaks.h> +#ifdef USE_SSL +#include <openssl/x509v3.h> +#endif + struct _HTStream { HTStreamClass *isa; }; @@ -481,6 +485,7 @@ static int HTLoadHTTP(const char *arg, const char *connect_url = NULL; /* The URL being proxied */ char *connect_host = NULL; /* The host being proxied */ SSL *handle = NULL; /* The SSL handle */ + X509 *peer_cert; /* The peer certificate */ char ssl_dn[1024]; char *cert_host; char *ssl_host; @@ -691,7 +696,8 @@ static int HTLoadHTTP(const char *arg, } #endif - X509_NAME_oneline(X509_get_subject_name(SSL_get_peer_certificate(handle)), + peer_cert = SSL_get_peer_certificate(handle); + X509_NAME_oneline(X509_get_subject_name(peer_cert), #ifndef USE_GNUTLS_INCL ssl_dn, sizeof(ssl_dn)); #else @@ -755,11 +761,12 @@ static int HTLoadHTTP(const char *arg, } /* add this CN to list of failed CNs */ if (ssl_all_cns == NULL) { - StrAllocCopy(ssl_all_cns, cert_host); + StrAllocCopy(ssl_all_cns, "CN<"); } else { - StrAllocCat(ssl_all_cns, ":"); - StrAllocCat(ssl_all_cns, cert_host); + StrAllocCat(ssl_all_cns, ":CN<"); } + StrAllocCat(ssl_all_cns, cert_host); + StrAllocCat(ssl_all_cns, ">"); /* if we cannot retry, don't try it */ if (ssl_dn_start == NULL) break; @@ -767,6 +774,64 @@ static int HTLoadHTTP(const char *arg, *ssl_dn_start = '/'; /* formerly NUL byte */ } + /* check the X.509v3 Subject Alternative Name */ + if (status_sslcertcheck < 2) { + STACK_OF(GENERAL_NAME) * gens; + int i, numalts; + const GENERAL_NAME *gn; + + gens = (STACK_OF(GENERAL_NAME) *) + X509_get_ext_d2i(peer_cert, NID_subject_alt_name, NULL, NULL); + + if (gens != NULL) { + numalts = sk_GENERAL_NAME_num(gens); + for (i = 0; i < numalts; ++i) { + gn = sk_GENERAL_NAME_value(gens, i); + if (gn->type == GEN_DNS) + cert_host = (char *) ASN1_STRING_data(gn->d.ia5); + else if (gn->type == GEN_IPADD) { + /* XXX untested -TG */ + size_t j = (size_t) ASN1_STRING_length(gn->d.ia5); + + cert_host = (char *) malloc(j + 1); + memcpy(cert_host, ASN1_STRING_data(gn->d.ia5), j); + cert_host[j] = '\0'; + } else + continue; + status_sslcertcheck = 1; /* got at least one */ + /* verify this SubjectAltName (see above) */ + if ((p = strchr(cert_host, ':')) != NULL) + *p = '\0'; + if (!(gn->type == GEN_IPADD ? strcasecomp : + strcasecomp_asterisk) (ssl_host, cert_host)) { + status_sslcertcheck = 2; + HTSprintf0(&msg, + gettext("Verified connection to %s (subj=%s)"), + ssl_host, cert_host); + _HTProgress(msg); + FREE(msg); + if (gn->type == GEN_IPADD) + free(cert_host); + break; + } + /* add to list of failed CNs */ + if (ssl_all_cns == NULL) + StrAllocCopy(ssl_all_cns, "SAN<"); + else + StrAllocCat(ssl_all_cns, ":SAN<"); + if (gn->type == GEN_DNS) + StrAllocCat(ssl_all_cns, "DNS="); + else if (gn->type == GEN_IPADD) + StrAllocCat(ssl_all_cns, "IP="); + StrAllocCat(ssl_all_cns, cert_host); + StrAllocCat(ssl_all_cns, ">"); + if (gn->type == GEN_IPADD) + free(cert_host); + } + sk_GENERAL_NAME_free(gens); + } + } + /* if an error occurred, format the appropriate message */ if (status_sslcertcheck == 0) { HTSprintf0(&msg, SSL_FORCED_PROMPT, |