summaryrefslogtreecommitdiff
path: root/imap-send.c
diff options
context:
space:
mode:
authorOswald Buddenhagen <ossi@kde.org>2013-02-15 12:50:35 -0800
committerJunio C Hamano <gitster@pobox.com>2013-02-19 21:47:22 -0800
commitb62fb077d5504deadea931fd16075729f39b8f47 (patch)
treeef911a96c6794d12b52f84be2dfe407102ccd4d5 /imap-send.c
parent1e1fe52923a8f582c4f50b41f0dd978d5d7c9bd3 (diff)
downloadgit-b62fb077d5504deadea931fd16075729f39b8f47.tar.gz
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>
Diffstat (limited to 'imap-send.c')
-rw-r--r--imap-send.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/imap-send.c b/imap-send.c
index 94f53c2c1d..0b9c464ad9 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -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)
@@ -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();
@@ -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