Fallback SCSV.

This patch adds server-side support for TLS_FALLBACK_SCSV (see
http://tools.ietf.org/html/draft-bmoeller-tls-downgrade-scsv-01).
This commit is contained in:
Adam Langley 2014-06-20 12:00:00 -07:00
parent 735107652b
commit 2970779684
7 changed files with 42 additions and 0 deletions

View File

@ -878,6 +878,7 @@ int ssl3_alert_code(int code)
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE); case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE);
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE); case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE);
case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY); case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
case SSL_AD_INAPPROPRIATE_FALLBACK:return(SSL3_AD_INAPPROPRIATE_FALLBACK);
default: return(-1); default: return(-1);
} }
} }

View File

@ -1774,6 +1774,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE #define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE #define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */ #define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK /* fatal */
#define SSL_ERROR_NONE 0 #define SSL_ERROR_NONE 0
#define SSL_ERROR_SSL 1 #define SSL_ERROR_SSL 1
@ -3057,5 +3058,6 @@ void ERR_load_SSL_strings(void);
#define SSL_R_UNEXPECTED_GROUP_CLOSE 433 #define SSL_R_UNEXPECTED_GROUP_CLOSE 433
#define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 434 #define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 434
#define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 435 #define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 435
#define SSL_R_INAPPROPRIATE_FALLBACK 436
#endif #endif

View File

@ -127,6 +127,9 @@ extern "C" {
/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */ /* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */
#define SSL3_CK_SCSV 0x030000FF #define SSL3_CK_SCSV 0x030000FF
/* Fallback signalling cipher suite value: not IANA assigned.
* See https://tools.ietf.org/html/draft-bmoeller-tls-downgrade-scsv-01 */
#define SSL3_CK_FALLBACK_SCSV 0x03005600
#define SSL3_CK_RSA_NULL_MD5 0x03000001 #define SSL3_CK_RSA_NULL_MD5 0x03000001
#define SSL3_CK_RSA_NULL_SHA 0x03000002 #define SSL3_CK_RSA_NULL_SHA 0x03000002
@ -351,6 +354,7 @@ extern "C" {
#define SSL3_AD_CERTIFICATE_EXPIRED 45 #define SSL3_AD_CERTIFICATE_EXPIRED 45
#define SSL3_AD_CERTIFICATE_UNKNOWN 46 #define SSL3_AD_CERTIFICATE_UNKNOWN 46
#define SSL3_AD_ILLEGAL_PARAMETER 47 /* fatal */ #define SSL3_AD_ILLEGAL_PARAMETER 47 /* fatal */
#define SSL3_AD_INAPPROPRIATE_FALLBACK 86 /* fatal */
#define TLS1_HB_REQUEST 1 #define TLS1_HB_REQUEST 1
#define TLS1_HB_RESPONSE 2 #define TLS1_HB_RESPONSE 2

View File

@ -300,6 +300,7 @@ const ERR_STRING_DATA SSL_error_string_data[] = {
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_HTTP_REQUEST), "HTTP_REQUEST"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_HTTP_REQUEST), "HTTP_REQUEST"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ILLEGAL_PADDING), "ILLEGAL_PADDING"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ILLEGAL_PADDING), "ILLEGAL_PADDING"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ILLEGAL_SUITEB_DIGEST), "ILLEGAL_SUITEB_DIGEST"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ILLEGAL_SUITEB_DIGEST), "ILLEGAL_SUITEB_DIGEST"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INAPPROPRIATE_FALLBACK), "INAPPROPRIATE_FALLBACK"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_COMPRESSION), "INCONSISTENT_COMPRESSION"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_COMPRESSION), "INCONSISTENT_COMPRESSION"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_AUDIT_PROOF), "INVALID_AUDIT_PROOF"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_AUDIT_PROOF), "INVALID_AUDIT_PROOF"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_AUTHZ_DATA), "INVALID_AUTHZ_DATA"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_AUTHZ_DATA), "INVALID_AUTHZ_DATA"},

View File

@ -1636,6 +1636,17 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
continue; continue;
} }
/* Check for FALLBACK_SCSV */
if (s->s3 && n == 2 &&
(p[0] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) &&
(p[1] == (SSL3_CK_FALLBACK_SCSV & 0xff)) &&
s->version < ssl_get_max_version(s))
{
OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, SSL_R_INAPPROPRIATE_FALLBACK);
ssl3_send_alert(s,SSL3_AL_FATAL,SSL3_AD_INAPPROPRIATE_FALLBACK);
goto err;
}
c=ssl_get_cipher_by_char(s,p); c=ssl_get_cipher_by_char(s,p);
p+=n; p+=n;
if (c != NULL) if (c != NULL)
@ -3479,6 +3490,27 @@ int ssl3_can_cutthrough(const SSL *s)
return 1; return 1;
} }
/* ssl_get_max_version returns the maximum SSL/TLS version number supported by
* |s|, or zero if all versions are disabled. */
int ssl_get_max_version(const SSL *s)
{
/* Only one version supported for DTLS. */
if (s->version == DTLS1_VERSION)
return DTLS1_VERSION;
if (!(s->options & SSL_OP_NO_TLSv1_2))
return TLS1_2_VERSION;
if (!(s->options & SSL_OP_NO_TLSv1_1))
return TLS1_1_VERSION;
if (!(s->options & SSL_OP_NO_TLSv1))
return TLS1_VERSION;
if (!(s->options & SSL_OP_NO_SSLv3))
return SSL3_VERSION;
if (!(s->options & SSL_OP_NO_SSLv2))
return SSL2_VERSION;
return 0;
}
/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer /* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
* vairable, freeing EVP_MD_CTX previously stored in that variable, if * vairable, freeing EVP_MD_CTX previously stored in that variable, if
* any. If EVP_MD pointer is passed, initializes ctx with this md * any. If EVP_MD pointer is passed, initializes ctx with this md

View File

@ -1343,6 +1343,7 @@ void tls1_set_cert_validity(SSL *s);
#endif #endif
int ssl3_can_cutthrough(const SSL *s); int ssl3_can_cutthrough(const SSL *s);
int ssl_get_max_version(const SSL *s);
EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ; EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ;
void ssl_clear_hash_ctx(EVP_MD_CTX **hash); void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,

View File

@ -1497,6 +1497,7 @@ int tls1_alert_code(int code)
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE); case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY); case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
case SSL_AD_INAPPROPRIATE_FALLBACK:return(SSL3_AD_INAPPROPRIATE_FALLBACK);
#if 0 /* not appropriate for TLS, not used for DTLS */ #if 0 /* not appropriate for TLS, not used for DTLS */
case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return
(DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);