changeset 22747:01e96a26135c

lib-ssl-iostream: Verify SSL server's hostname against cert if it's non-NULL The hostname verification was skipped when handshake-callback wasn't used. All of the existing code used the callback though, so this doesn't fix any bugs.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Tue, 31 Oct 2017 23:37:44 +0200
parents 48980d280f13
children 597c668f887a
files src/lib-ssl-iostream/iostream-openssl.c src/lib-ssl-iostream/iostream-ssl.h
diffstat 2 files changed, 13 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-ssl-iostream/iostream-openssl.c	Tue Oct 31 19:49:56 2017 +0200
+++ b/src/lib-ssl-iostream/iostream-openssl.c	Tue Oct 31 23:37:44 2017 +0200
@@ -601,6 +601,13 @@
 			openssl_iostream_set_error(ssl_io, error);
 			ssl_io->handshake_failed = TRUE;
 		}
+	} else if (ssl_io->connected_host != NULL && !ssl_io->handshake_failed) {
+		if (ssl_iostream_cert_match_name(ssl_io, ssl_io->connected_host) < 0) {
+			openssl_iostream_set_error(ssl_io, t_strdup_printf(
+				"SSL certificate doesn't match expected host name %s",
+				ssl_io->connected_host));
+			ssl_io->handshake_failed = TRUE;
+		}
 	}
 	if (ssl_io->handshake_failed) {
 		i_stream_close(ssl_io->plain_input);
--- a/src/lib-ssl-iostream/iostream-ssl.h	Tue Oct 31 19:49:56 2017 +0200
+++ b/src/lib-ssl-iostream/iostream-ssl.h	Tue Oct 31 23:37:44 2017 +0200
@@ -23,7 +23,8 @@
 };
 
 /* Returns 0 if ok, -1 and sets error_r if failed. The returned error string
-   becomes available via ssl_iostream_get_last_error() */
+   becomes available via ssl_iostream_get_last_error(). The callback most
+   likely should be calling ssl_iostream_check_cert_validity(). */
 typedef int
 ssl_iostream_handshake_callback_t(const char **error_r, void *context);
 
@@ -47,6 +48,10 @@
 				 const char *prefix);
 
 int ssl_iostream_handshake(struct ssl_iostream *ssl_io);
+/* Call the given callback when SSL handshake finishes. The callback must
+   verify whether the certificate and its hostname is valid. If there is no
+   callback, the default is to use ssl_iostream_check_cert_validity() with the
+   same host as given to io_stream_create_ssl_client() */
 void ssl_iostream_set_handshake_callback(struct ssl_iostream *ssl_io,
 					 ssl_iostream_handshake_callback_t *callback,
 					 void *context);