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)";
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) */
SSL *ssl;
struct connection *conn;
const char *servername;
+ const char *sni;
int depth;
X509 *cert;
* 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)
}
}
+ /* 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;
}