RFC2818 server identity check update
This commit is contained in:
		| @@ -1,3 +1,10 @@ | ||||
| 2001-12-26  Fumitoshi UKAI  <ukai@debian.or.jp> | ||||
|  | ||||
| 	* istream.h: #include <x509v3.h> deleted | ||||
| 	* istream.c: #include <x509v3.h> | ||||
| 	* istream.c (ssl_check_cert_ident): of subjectAltName dNSName found, | ||||
| 		don't try commonName | ||||
|  | ||||
| 2001-12-26  Fumitoshi UKAI  <ukai@debian.or.jp> | ||||
|  | ||||
| 	* [w3m-dev 02743] RFC2818 server identity check | ||||
| @@ -1613,4 +1620,4 @@ | ||||
| 	* release-0-2-1 | ||||
| 	* import w3m-0.2.1 | ||||
|  | ||||
| $Id: ChangeLog,v 1.179 2001/12/26 12:18:06 ukai Exp $ | ||||
| $Id: ChangeLog,v 1.180 2001/12/26 12:58:49 ukai Exp $ | ||||
|   | ||||
							
								
								
									
										103
									
								
								istream.c
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								istream.c
									
									
									
									
									
								
							| @@ -1,7 +1,10 @@ | ||||
| /* $Id: istream.c,v 1.7 2001/12/26 12:18:06 ukai Exp $ */ | ||||
| /* $Id: istream.c,v 1.8 2001/12/26 12:58:49 ukai Exp $ */ | ||||
| #include "fm.h" | ||||
| #include "istream.h" | ||||
| #include <signal.h> | ||||
| #ifdef USE_SSL | ||||
| #include <x509v3.h> | ||||
| #endif | ||||
|  | ||||
| #define	uchar		unsigned char | ||||
|  | ||||
| @@ -380,11 +383,12 @@ ssl_get_certificate(InputStream stream) | ||||
| } | ||||
|  | ||||
| Str | ||||
| ssl_check_cert_ident(SSL *handle, char *hostname) | ||||
| ssl_check_cert_ident(SSL * handle, char *hostname) | ||||
| { | ||||
|     X509 *x; | ||||
|     int i; | ||||
|     Str ret = Strnew_charp("SSL error: failed to check certificate chain"); | ||||
|     Str ret = NULL; | ||||
|     int match_ident = FALSE; | ||||
|     /* | ||||
|      * All we need to do here is check that the CN matches. | ||||
|      * | ||||
| @@ -396,67 +400,72 @@ ssl_check_cert_ident(SSL *handle, char *hostname) | ||||
|      * Certification Authorities are encouraged to use the dNSName instead. | ||||
|      */ | ||||
|     x = SSL_get_peer_certificate(handle); | ||||
|     if (!x) {    | ||||
|     if (!x) { | ||||
| 	ret = Strnew_charp("Unable to get peer certificate"); | ||||
| 	return ret; | ||||
|     } | ||||
|  | ||||
|     i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1); | ||||
|     if (i >= 0) {    | ||||
|         X509_EXTENSION *ex; | ||||
|         STACK_OF(GENERAL_NAME) *alt; | ||||
|     if (i >= 0) { | ||||
| 	X509_EXTENSION *ex; | ||||
| 	STACK_OF(GENERAL_NAME) * alt; | ||||
|  | ||||
|         ex = X509_get_ext(x, i); | ||||
|         alt = X509V3_EXT_d2i(ex); | ||||
|         if (alt) {    | ||||
|             int n, len1, len2 = 0; | ||||
|             char *domain; | ||||
|             GENERAL_NAME *gn; | ||||
|             X509V3_EXT_METHOD *method; | ||||
| 	ex = X509_get_ext(x, i); | ||||
| 	alt = X509V3_EXT_d2i(ex); | ||||
| 	if (alt) { | ||||
| 	    int n, len1, len2 = 0; | ||||
| 	    char *domain; | ||||
| 	    GENERAL_NAME *gn; | ||||
| 	    X509V3_EXT_METHOD *method; | ||||
| 	    Str seen_dnsname = NULL; | ||||
|  | ||||
|             len1 = strlen(hostname); | ||||
|             n = sk_GENERAL_NAME_num(alt); | ||||
|             domain = strchr(hostname, '.'); | ||||
|             if (domain) | ||||
|                 len2 = len1 - (domain - hostname); | ||||
|             for (i = 0; i < n; i++) { | ||||
|                 gn = sk_GENERAL_NAME_value(alt, i); | ||||
|                 if (gn->type == GEN_DNS) { | ||||
|                     char *sn = ASN1_STRING_data(gn->d.ia5); | ||||
|                     int sl = ASN1_STRING_length(gn->d.ia5); | ||||
| 	    len1 = strlen(hostname); | ||||
| 	    n = sk_GENERAL_NAME_num(alt); | ||||
| 	    domain = strchr(hostname, '.'); | ||||
| 	    if (domain) | ||||
| 		len2 = len1 - (domain - hostname); | ||||
| 	    for (i = 0; i < n; i++) { | ||||
| 		gn = sk_GENERAL_NAME_value(alt, i); | ||||
| 		if (gn->type == GEN_DNS) { | ||||
| 		    char *sn = ASN1_STRING_data(gn->d.ia5); | ||||
| 		    int sl = ASN1_STRING_length(gn->d.ia5); | ||||
|  | ||||
|                     /* Is this an exact match? */ | ||||
|                     if ((len1 == sl) && !strncasecmp(hostname, sn, len1)) | ||||
|                         break; | ||||
| 		    if (!seen_dnsname) | ||||
| 			seen_dnsname = Strnew(); | ||||
| 		    Strcat_m_charp(seen_dnsname, sn, " "); | ||||
| 		    /* Is this an exact match? */ | ||||
| 		    if ((len1 == sl) && !strncasecmp(hostname, sn, len1)) | ||||
| 			break; | ||||
|  | ||||
|                     /* Is this a wildcard match? */ | ||||
|                     if ((*sn == '*') && domain && (len2 == sl-1) && | ||||
|                         !strncasecmp(domain, sn+1, len2)) | ||||
|                         break; | ||||
|                 } | ||||
|             } | ||||
|             method = X509V3_EXT_get(ex); | ||||
|             method->ext_free(alt); | ||||
|             if (i < n)  /* Found a match */ | ||||
|                 ret = NULL; | ||||
|         } | ||||
| 		    /* Is this a wildcard match? */ | ||||
| 		    if ((*sn == '*') && domain && (len2 == sl - 1) && | ||||
| 			!strncasecmp(domain, sn + 1, len2)) | ||||
| 			break; | ||||
| 		} | ||||
| 	    } | ||||
| 	    method = X509V3_EXT_get(ex); | ||||
| 	    method->ext_free(alt); | ||||
| 	    if (i < n)		/* Found a match */ | ||||
| 		match_ident = TRUE; | ||||
| 	    else if (seen_dnsname) | ||||
| 		ret = Sprintf("Bad cert ident from %s: dNSName=%s", hostname, | ||||
| 			      seen_dnsname->ptr); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|     if (ret != NULL) { | ||||
|         X509_NAME *xn; | ||||
|         char buf[2048]; | ||||
|     if (match_ident == FALSE && ret == NULL) { | ||||
| 	X509_NAME *xn; | ||||
| 	char buf[2048]; | ||||
|  | ||||
|         xn = X509_get_subject_name(x); | ||||
| 	xn = X509_get_subject_name(x); | ||||
|  | ||||
|         if (X509_NAME_get_text_by_NID(xn, NID_commonName,  | ||||
| 				      buf, sizeof(buf)) == -1) { | ||||
| 	if (X509_NAME_get_text_by_NID(xn, NID_commonName, | ||||
| 				      buf, sizeof(buf)) == -1) | ||||
| 	    ret = Strnew_charp("Unable to get common name from peer cert"); | ||||
| 	    return ret; | ||||
|         } | ||||
| 	else if (strcasecmp(hostname, buf)) | ||||
| 	    ret = Sprintf("Bad cert ident %s from %s", buf, hostname); | ||||
| 	else | ||||
| 	    ret = NULL; | ||||
| 	    match_ident = TRUE; | ||||
|     } | ||||
|     X509_free(x); | ||||
|     return ret; | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| /* $Id: istream.h,v 1.5 2001/12/26 12:18:06 ukai Exp $ */ | ||||
| /* $Id: istream.h,v 1.6 2001/12/26 12:58:49 ukai Exp $ */ | ||||
| #ifndef IO_STREAM_H | ||||
| #define IO_STREAM_H | ||||
|  | ||||
| @@ -6,7 +6,6 @@ | ||||
| #ifdef USE_SSL | ||||
| #include <bio.h> | ||||
| #include <x509.h> | ||||
| #include <x509v3.h> | ||||
| #include <ssl.h> | ||||
| #endif | ||||
| #include "Str.h" | ||||
| @@ -127,7 +126,7 @@ extern int ISfileno(InputStream stream); | ||||
| extern int ISeos(InputStream stream); | ||||
| #ifdef USE_SSL | ||||
| extern Str ssl_get_certificate(InputStream stream); | ||||
| extern Str ssl_check_cert_ident(SSL *handle, char *hostname); | ||||
| extern Str ssl_check_cert_ident(SSL * handle, char *hostname); | ||||
| #endif | ||||
|  | ||||
| #define IST_BASIC	0 | ||||
|   | ||||
							
								
								
									
										12
									
								
								url.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								url.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| /* $Id: url.c,v 1.23 2001/12/26 12:18:06 ukai Exp $ */ | ||||
| /* $Id: url.c,v 1.24 2001/12/26 12:58:49 ukai Exp $ */ | ||||
| #include "fm.h" | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| @@ -372,7 +372,8 @@ openSSLHandle(int sock, char *hostname) | ||||
| 	if (tolower(*ans) == 'y') { | ||||
| 	    amsg = Strnew_charp("Accept unsecure SSL session: " | ||||
| 				"unverified certificate"); | ||||
| 	} else { | ||||
| 	} | ||||
| 	else { | ||||
| 	    char *e = "This SSL session was rejected " | ||||
| 		"to prevent security violation"; | ||||
| 	    disp_err_message(e, FALSE); | ||||
| @@ -381,7 +382,7 @@ openSSLHandle(int sock, char *hostname) | ||||
| 	} | ||||
|     } | ||||
| #endif | ||||
|      | ||||
|  | ||||
|     emsg = ssl_check_cert_ident(handle, hostname); | ||||
|     if (emsg != NULL) { | ||||
| 	if (emsg->length > COLS - 16) | ||||
| @@ -391,8 +392,9 @@ openSSLHandle(int sock, char *hostname) | ||||
| 	ans = inputChar(emsg->ptr); | ||||
| 	if (tolower(*ans) == 'y') { | ||||
| 	    amsg = Strnew_charp("Accept unsecure SSL session:" | ||||
| 		"certificate ident mismatch"); | ||||
| 	} else { | ||||
| 				"certificate ident mismatch"); | ||||
| 	} | ||||
| 	else { | ||||
| 	    char *e = "This SSL session was rejected " | ||||
| 		"to prevent security violation"; | ||||
| 	    disp_err_message(e, FALSE); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user