@@ -219,8 +219,14 @@ static int ssl_socket_connect(struct imap_socket *sock UNUSED,
219219
220220#else
221221
222- static int host_matches (const char * host , const char * pattern )
222+ static int host_matches (const char * host , const ASN1_STRING * asn1_str )
223223{
224+ const char * pattern = (const char * )ASN1_STRING_get0_data (asn1_str );
225+
226+ /* embedded NUL characters may open a security hole */
227+ if (memchr (pattern , '\0' , ASN1_STRING_length (asn1_str )))
228+ return 0 ;
229+
224230 if (pattern [0 ] == '*' && pattern [1 ] == '.' ) {
225231 pattern += 2 ;
226232 if (!(host = strchr (host , '.' )))
@@ -233,9 +239,13 @@ static int host_matches(const char *host, const char *pattern)
233239
234240static int verify_hostname (X509 * cert , const char * hostname )
235241{
236- int len ;
242+ #if (OPENSSL_VERSION_NUMBER >= 0x40000000L )
243+ const X509_NAME * subj ;
244+ #else
237245 X509_NAME * subj ;
238- char cname [1000 ];
246+ #endif
247+ const X509_NAME_ENTRY * cname_entry ;
248+ const ASN1_STRING * cname ;
239249 int i , found ;
240250 STACK_OF (GENERAL_NAME ) * subj_alt_names ;
241251
@@ -244,10 +254,11 @@ static int verify_hostname(X509 *cert, const char *hostname)
244254 if ((subj_alt_names = X509_get_ext_d2i (cert , NID_subject_alt_name , NULL , NULL ))) {
245255 int num_subj_alt_names = sk_GENERAL_NAME_num (subj_alt_names );
246256 for (i = 0 ; !found && i < num_subj_alt_names ; i ++ ) {
257+ int ntype ;
247258 GENERAL_NAME * subj_alt_name = sk_GENERAL_NAME_value (subj_alt_names , i );
248- if ( subj_alt_name -> type == GEN_DNS &&
249- strlen (( const char * ) subj_alt_name -> d . ia5 -> data ) == ( size_t ) subj_alt_name -> d . ia5 -> length &&
250- host_matches (hostname , ( const char * )( subj_alt_name -> d . ia5 -> data ) ))
259+ ASN1_STRING * subj_alt_str = GENERAL_NAME_get0_value ( subj_alt_name , & ntype );
260+
261+ if ( ntype == GEN_DNS && host_matches (hostname , subj_alt_str ))
251262 found = 1 ;
252263 }
253264 sk_GENERAL_NAME_pop_free (subj_alt_names , GENERAL_NAME_free );
@@ -258,12 +269,14 @@ static int verify_hostname(X509 *cert, const char *hostname)
258269 /* try the common name */
259270 if (!(subj = X509_get_subject_name (cert )))
260271 return error ("cannot get certificate subject" );
261- if ((len = X509_NAME_get_text_by_NID (subj , NID_commonName , cname , sizeof (cname ))) < 0 )
272+ if ((i = X509_NAME_get_index_by_NID (subj , NID_commonName , -1 )) < 0 ||
273+ (cname_entry = X509_NAME_get_entry (subj , i )) == NULL ||
274+ (cname = X509_NAME_ENTRY_get_data (cname_entry )) == NULL )
262275 return error ("cannot get certificate common name" );
263- if (strlen ( cname ) == ( size_t ) len && host_matches (hostname , cname ))
276+ if (host_matches (hostname , cname ))
264277 return 0 ;
265278 return error ("certificate owner '%s' does not match hostname '%s'" ,
266- cname , hostname );
279+ ASN1_STRING_get0_data ( cname ) , hostname );
267280}
268281
269282static int ssl_socket_connect (struct imap_socket * sock ,
0 commit comments