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 <ossi@kde.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
1e1fe52923
commit
b62fb077d5
39
imap-send.c
39
imap-send.c
@ -275,6 +275,35 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve
|
|||||||
|
|
||||||
#else
|
#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)
|
static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int verify)
|
||||||
{
|
{
|
||||||
#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
|
#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
|
||||||
@ -284,6 +313,7 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve
|
|||||||
#endif
|
#endif
|
||||||
SSL_CTX *ctx;
|
SSL_CTX *ctx;
|
||||||
int ret;
|
int ret;
|
||||||
|
X509 *cert;
|
||||||
|
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
@ -327,6 +357,15 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve
|
|||||||
return -1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user