Skip to content

Commit

Permalink
imap-send: the subject of SSL certificate must match the host
Browse files Browse the repository at this point in the history
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 <ossi@kde.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Oswald Buddenhagen authored and Junio C Hamano committed Feb 20, 2013
1 parent 1e1fe52 commit b62fb07
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions imap-send.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,35 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve

#else

static int host_matches(const char *host, const char *pattern)
{
if (pattern[0] == '*' && pattern[1] == '.') {
pattern += 2;
if (!(host = strchr(host, '.')))
return 0;
host++;
}

return *host && *pattern && !strcasecmp(host, pattern);
}

static int verify_hostname(X509 *cert, const char *hostname)
{
int len;
X509_NAME *subj;
char cname[1000];

/* try the common name */
if (!(subj = X509_get_subject_name(cert)))
return error("cannot get certificate subject");
if ((len = X509_NAME_get_text_by_NID(subj, NID_commonName, cname, sizeof(cname))) < 0)
return error("cannot get certificate common name");
if (strlen(cname) == (size_t)len && host_matches(hostname, cname))
return 0;
return error("certificate owner '%s' does not match hostname '%s'",
cname, hostname);
}

static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int verify)
{
#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
Expand All @@ -284,6 +313,7 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve
#endif
SSL_CTX *ctx;
int ret;
X509 *cert;

SSL_library_init();
SSL_load_error_strings();
Expand Down Expand Up @@ -327,6 +357,15 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve
return -1;
}

if (verify) {
/* make sure the hostname matches that of the certificate */
cert = SSL_get_peer_certificate(sock->ssl);
if (!cert)
return error("unable to get peer certificate.");
if (verify_hostname(cert, server.host) < 0)
return -1;
}

return 0;
}
#endif
Expand Down

0 comments on commit b62fb07

Please sign in to comment.