From 963918b88fb3e7210ec0552868b22469452c79c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 10 Mar 2014 09:34:49 +0100 Subject: [PATCH] Countermeasure against "triple handshake" attack --- ChangeLog | 5 +++++ library/ssl_tls.c | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/ChangeLog b/ChangeLog index b39681987..513f9f5c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,11 @@ PolarSSL ChangeLog Changes * Introduced POLARSSL_HAVE_READDIR_R for systems without it +Security + * Forbid change of server certificate during renegotiation to prevent + "triple handshake" attack when authentication mode is optional (the + attack was already impossible when authentication is required). + Bugfix * Fixed X.509 hostname comparison (with non-regular characters) * SSL now gracefully handles missing RNG diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 2a8fcedda..d6e9dd3e3 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -2402,6 +2402,30 @@ int ssl_parse_certificate( ssl_context *ssl ) SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert ); + /* + * On client, make sure the server cert doesn't change during renego to + * avoid "triple handshake" attack: https://secure-resumption.com/ + */ + if( ssl->endpoint == SSL_IS_CLIENT && + ssl->renegotiation == SSL_RENEGOTIATION ) + { + if( ssl->session->peer_cert == NULL ) + { + SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + if( ssl->session->peer_cert->raw.len != + ssl->session_negotiate->peer_cert->raw.len || + memcmp( ssl->session->peer_cert->raw.p, + ssl->session_negotiate->peer_cert->raw.p, + ssl->session->peer_cert->raw.len ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ); + } + } + if( ssl->authmode != SSL_VERIFY_NONE ) { if( ssl->ca_chain == NULL )