Skip to content

Commit b62fb07

Browse files
ossilatorgitster
authored andcommitted
imap-send: the subject of SSL certificate must match the host
We did not check a valid certificate's subject at all, and would have happily talked with a wrong host after connecting to an incorrect address and getting a valid certificate that does not belong to the host we intended to talk to. Signed-off-by: Oswald Buddenhagen <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1e1fe52 commit b62fb07

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

imap-send.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,35 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve
275275

276276
#else
277277

278+
static int host_matches(const char *host, const char *pattern)
279+
{
280+
if (pattern[0] == '*' && pattern[1] == '.') {
281+
pattern += 2;
282+
if (!(host = strchr(host, '.')))
283+
return 0;
284+
host++;
285+
}
286+
287+
return *host && *pattern && !strcasecmp(host, pattern);
288+
}
289+
290+
static int verify_hostname(X509 *cert, const char *hostname)
291+
{
292+
int len;
293+
X509_NAME *subj;
294+
char cname[1000];
295+
296+
/* try the common name */
297+
if (!(subj = X509_get_subject_name(cert)))
298+
return error("cannot get certificate subject");
299+
if ((len = X509_NAME_get_text_by_NID(subj, NID_commonName, cname, sizeof(cname))) < 0)
300+
return error("cannot get certificate common name");
301+
if (strlen(cname) == (size_t)len && host_matches(hostname, cname))
302+
return 0;
303+
return error("certificate owner '%s' does not match hostname '%s'",
304+
cname, hostname);
305+
}
306+
278307
static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int verify)
279308
{
280309
#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
@@ -284,6 +313,7 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve
284313
#endif
285314
SSL_CTX *ctx;
286315
int ret;
316+
X509 *cert;
287317

288318
SSL_library_init();
289319
SSL_load_error_strings();
@@ -327,6 +357,15 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve
327357
return -1;
328358
}
329359

360+
if (verify) {
361+
/* make sure the hostname matches that of the certificate */
362+
cert = SSL_get_peer_certificate(sock->ssl);
363+
if (!cert)
364+
return error("unable to get peer certificate.");
365+
if (verify_hostname(cert, server.host) < 0)
366+
return -1;
367+
}
368+
330369
return 0;
331370
}
332371
#endif

0 commit comments

Comments
 (0)