77
88#include "config.h"
99
10+ #include <arpa/inet.h>
1011#include <sys/types.h>
1112#include <sys/socket.h>
1213#include <sys/time.h>
@@ -106,27 +107,47 @@ _SSL_check_server_cert(SSL *ssl, const char *hostname)
106107{
107108 X509 * cert ;
108109 X509_NAME * subject ;
109- const GENERAL_NAME * altname ;
110110 STACK_OF (GENERAL_NAME ) * altnames ;
111111 ASN1_STRING * tmp ;
112112 int i , n , match = -1 ;
113- const char * p ;
113+ struct in6_addr addr ;
114+ int hostnametype = GEN_DNS ;
115+ size_t addrsize = 0 ;
114116
115117 if (SSL_get_verify_mode (ssl ) == SSL_VERIFY_NONE ||
116118 (cert = SSL_get_peer_certificate (ssl )) == NULL ) {
117119 return (1 );
118120 }
121+
122+ /* Check if hostname is an IP address */
123+ if (inet_pton (AF_INET6 , hostname , & addr ) == 1 ) {
124+ hostnametype = GEN_IPADD ;
125+ addrsize = sizeof (struct in6_addr );
126+ } else if (inet_pton (AF_INET , hostname , & addr ) == 1 ) {
127+ hostnametype = GEN_IPADD ;
128+ addrsize = sizeof (struct in_addr );
129+ }
130+
119131 /* Check subjectAltName */
120132 if ((altnames = X509_get_ext_d2i (cert , NID_subject_alt_name ,
121133 NULL , NULL )) != NULL ) {
122134 n = sk_GENERAL_NAME_num (altnames );
123135
124136 for (i = 0 ; i < n && match != 1 ; i ++ ) {
125- altname = sk_GENERAL_NAME_value (altnames , i );
126- p = (char * )ASN1_STRING_get0_data (altname -> d .ia5 );
127- if (altname -> type == GEN_DNS ) {
128- match = (ASN1_STRING_length (altname -> d .ia5 ) ==
129- strlen (p ) && match_pattern (hostname , p ));
137+ const GENERAL_NAME * altname = sk_GENERAL_NAME_value (altnames , i );
138+ if (hostnametype == altname -> type ) {
139+ char * altptr = (char * )ASN1_STRING_get0_data (altname -> d .ia5 );
140+ size_t altsize = (size_t )ASN1_STRING_length (altname -> d .ia5 );
141+
142+ if (altname -> type == GEN_DNS ) {
143+ match = (altsize == strlen (altptr ) && match_pattern (hostname , altptr ));
144+ } else if (altname -> type == GEN_IPADD ) {
145+ if ((altsize == addrsize ) && !memcmp (altptr , & addr , altsize )) {
146+ match = 1 ;
147+ } else {
148+ match = 0 ;
149+ }
150+ }
130151 }
131152 }
132153 GENERAL_NAMES_free (altnames );
@@ -142,9 +163,15 @@ _SSL_check_server_cert(SSL *ssl, const char *hostname)
142163 if ((tmp = X509_NAME_ENTRY_get_data (
143164 X509_NAME_get_entry (subject , i ))) != NULL &&
144165 ASN1_STRING_type (tmp ) == V_ASN1_UTF8STRING ) {
145- p = (char * )ASN1_STRING_get0_data (tmp );
146- match = (ASN1_STRING_length (tmp ) ==
147- strlen (p ) && match_pattern (hostname , p ));
166+ const char * pattern = (char * )ASN1_STRING_get0_data (tmp );
167+ size_t patternsize = (size_t )ASN1_STRING_length (tmp );
168+ if (patternsize == strlen (pattern )) {
169+ if (!strchr (pattern , '*' )) {
170+ match = strcasecmp (hostname , pattern ) == 0 ;
171+ } else if (hostnametype == GEN_DNS ) {
172+ match = match_pattern (hostname , pattern );
173+ }
174+ }
148175 }
149176 }
150177 }
0 commit comments