diff --git a/include/proto/connection.h b/include/proto/connection.h index 09467ba50..9b025941c 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -605,6 +605,8 @@ static inline const char *conn_err_code_str(struct connection *c) case CO_ER_SSL_RENEG: return "Rejected a client-initiated SSL renegociation attempt"; case CO_ER_SSL_CA_FAIL: return "SSL client CA chain cannot be verified"; case CO_ER_SSL_CRT_FAIL: return "SSL client certificate not trusted"; + case CO_ER_SSL_MISMATCH: return "Server presented an SSL certificate different from the configured one"; + case CO_ER_SSL_MISMATCH_SNI: return "Server presented an SSL certificate different from the expected one"; case CO_ER_SSL_HANDSHAKE: return "SSL handshake failure"; case CO_ER_SSL_HANDSHAKE_HB: return "SSL handshake failure after heartbeat"; case CO_ER_SSL_KILLED_HB: return "Stopped a TLSv1 heartbeat attack (CVE-2014-0160)"; diff --git a/include/types/connection.h b/include/types/connection.h index 1e3fb7389..7da0a7a9b 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -179,6 +179,8 @@ enum { CO_ER_SSL_RENEG, /* forbidden client renegociation */ CO_ER_SSL_CA_FAIL, /* client cert verification failed in the CA chain */ CO_ER_SSL_CRT_FAIL, /* client cert verification failed on the certificate */ + CO_ER_SSL_MISMATCH, /* Server presented an SSL certificate different from the configured one */ + CO_ER_SSL_MISMATCH_SNI, /* Server presented an SSL certificate different from the expected one */ CO_ER_SSL_HANDSHAKE, /* SSL error during handshake */ CO_ER_SSL_HANDSHAKE_HB, /* SSL error during handshake with heartbeat present */ CO_ER_SSL_KILLED_HB, /* Stopped a TLSv1 heartbeat attack (CVE-2014-0160) */ diff --git a/src/ssl_sock.c b/src/ssl_sock.c index c53cc063e..207f4275a 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -3931,6 +3931,7 @@ static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx) SSL *ssl; struct connection *conn; const char *servername; + const char *sni; int depth; X509 *cert; @@ -3952,6 +3953,7 @@ static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx) * verification is OK. */ servername = SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name); + sni = servername; if (!servername) { servername = objt_server(conn->target)->ssl_ctx.verify_host; if (!servername) @@ -4003,6 +4005,9 @@ static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx) } } + /* report the mismatch and indicate if SNI was used or not */ + if (!ok && !conn->err_code) + conn->err_code = sni ? CO_ER_SSL_MISMATCH_SNI : CO_ER_SSL_MISMATCH; return ok; }