@@ -80,46 +80,73 @@ static int ssl_teardown(mbedtls_ssl_context *ssl)
8080 return ret ;
8181}
8282
83+ static int check_host_name (const char * name , const char * host )
84+ {
85+ if (!strcasecmp (name , host ))
86+ return 0 ;
87+
88+ if (gitno__match_host (name , host ) < 0 )
89+ return -1 ;
90+
91+ return 0 ;
92+ }
93+
8394static int verify_server_cert (mbedtls_ssl_context * ssl , const char * host )
8495{
8596 const mbedtls_x509_crt * cert ;
86- int flags ;
87- struct in6_addr addr6 ;
88- struct in_addr addr4 ;
89- void * addr ;
97+ const mbedtls_x509_sequence * alts ;
98+ int ret , matched = -1 ;
99+ size_t sn_size = 512 ;
100+ char subject_name [sn_size ], alt_name [sn_size ];
101+
90102
91- if ( ( flags = mbedtls_ssl_get_verify_result (ssl ) ) != 0 )
92- {
103+ if ((ret = mbedtls_ssl_get_verify_result (ssl )) != 0 ) {
93104 char vrfy_buf [512 ];
94- mbedtls_x509_crt_verify_info ( vrfy_buf , sizeof ( vrfy_buf ), " ! " , flags );
105+ mbedtls_x509_crt_verify_info ( vrfy_buf , sizeof ( vrfy_buf ), " ! " , ret );
95106 giterr_set (GITERR_SSL , "The SSL certificate is invalid: %s" , vrfy_buf );
96107 return GIT_ECERTIFICATE ;
97108 }
98109
99- /* Try to parse the host as an IP address to see if it is */
100- if (p_inet_pton (AF_INET , host , & addr4 )) {
101- addr = & addr4 ;
102- } else {
103- if (p_inet_pton (AF_INET6 , host , & addr6 )) {
104- addr = & addr6 ;
105- }
106- }
107-
108110 cert = mbedtls_ssl_get_peer_cert (ssl );
109111 if (!cert ) {
110112 giterr_set (GITERR_SSL , "the server did not provide a certificate" );
111113 return -1 ;
112114 }
113115
114116 /* Check the alternative names */
115- //TODO: cert->subject_alt_names
117+ alts = & cert -> subject_alt_names ;
118+ while (alts != NULL && matched != 1 ) {
119+ // Buffer is too small
120+ if ( alts -> buf .len >= sn_size )
121+ goto on_error ;
122+
123+ memcpy (alt_name , alts -> buf .p , alts -> buf .len );
124+ alt_name [alts -> buf .len ] = '\0' ;
125+
126+ if (!memchr (alt_name , '\0' , alts -> buf .len )) {
127+ if (check_host_name (alt_name , host ) < 0 )
128+ matched = 0 ;
129+ else
130+ matched = 1 ;
131+ }
132+
133+ alts = alts -> next ;
134+ }
135+ if (matched == 0 )
136+ goto cert_fail_name ;
137+
138+ if (matched == 1 )
139+ return 0 ;
116140
117141 /* If no alternative names are available, check the common name */
118- /*TODO
119- mbedtls_x509_name peer_name = cert->subject;
120- if (peer_name == NULL)
142+ ret = mbedtls_x509_dn_gets (subject_name , sn_size , & cert -> subject );
143+ if (ret == 0 )
121144 goto on_error ;
122- */
145+ if (memchr (subject_name , '\0' , ret ))
146+ goto cert_fail_name ;
147+
148+ if (check_host_name (subject_name , host ) < 0 )
149+ goto cert_fail_name ;
123150
124151 return 0 ;
125152
@@ -151,12 +178,9 @@ int mbedtls_connect(git_stream *stream)
151178
152179 st -> connected = true;
153180
154- mbedtls_ssl_set_bio (st -> ssl , st -> io , bio_write , bio_read , NULL );
155-
156- /* specify the host in case SNI is needed */
157- #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
158181 mbedtls_ssl_set_hostname (st -> ssl , st -> host );
159- #endif
182+
183+ mbedtls_ssl_set_bio (st -> ssl , st -> io , bio_write , bio_read , NULL );
160184
161185 if ((ret = mbedtls_ssl_handshake (st -> ssl )) != 0 )
162186 return ssl_set_error (st -> ssl , ret );
0 commit comments