From: Matt Caswell Date: Tue, 7 Nov 2017 16:36:51 +0000 (+0000) Subject: Drop CCS messages received in the TLSv1.3 handshake X-Git-Tag: OpenSSL_1_1_1-pre1~293 X-Git-Url: https://git.openssl.org/?p=openssl.git;a=commitdiff_plain;h=fdd9236747d7b843f1f5644b3e95580b80d9a598 Drop CCS messages received in the TLSv1.3 handshake Reviewed-by: Ben Kaduk (Merged from https://github.com/openssl/openssl/pull/4701) --- diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 4410314bc1..de7c50a0a0 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2453,6 +2453,7 @@ SSL_R_INCONSISTENT_EARLY_DATA_SNI:231:inconsistent early data sni SSL_R_INCONSISTENT_EXTMS:104:inconsistent extms SSL_R_INSUFFICIENT_SECURITY:241:insufficient security SSL_R_INVALID_ALERT:205:invalid alert +SSL_R_INVALID_CCS_MESSAGE:260:invalid ccs message SSL_R_INVALID_CERTIFICATE_OR_ALG:238:invalid certificate or alg SSL_R_INVALID_COMMAND:280:invalid command SSL_R_INVALID_COMPRESSION_ALGORITHM:341:invalid compression algorithm @@ -2463,7 +2464,7 @@ SSL_R_INVALID_MAX_EARLY_DATA:174:invalid max early data SSL_R_INVALID_NULL_CMD_NAME:385:invalid null cmd name SSL_R_INVALID_SEQUENCE_NUMBER:402:invalid sequence number SSL_R_INVALID_SERVERINFO_DATA:388:invalid serverinfo data -SSL_R_INVALID_SESSION_ID:232:invalid session id +SSL_R_INVALID_SESSION_ID:999:invalid session id SSL_R_INVALID_SRP_USERNAME:357:invalid srp username SSL_R_INVALID_STATUS_RESPONSE:328:invalid status response SSL_R_INVALID_TICKET_KEYS_LENGTH:325:invalid ticket keys length @@ -2583,6 +2584,7 @@ SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS:239:\ unable to find public key parameters SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES:242:unable to load ssl3 md5 routines SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines +SSL_R_UNEXPECTED_CCS_MESSAGE:262:unexpected ccs message SSL_R_UNEXPECTED_END_OF_EARLY_DATA:178:unexpected end of early data SSL_R_UNEXPECTED_MESSAGE:244:unexpected message SSL_R_UNEXPECTED_RECORD:245:unexpected record diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h index 3199ab0ff4..9c86220336 100644 --- a/include/openssl/sslerr.h +++ b/include/openssl/sslerr.h @@ -533,6 +533,7 @@ int ERR_load_SSL_strings(void); # define SSL_R_INCONSISTENT_EXTMS 104 # define SSL_R_INSUFFICIENT_SECURITY 241 # define SSL_R_INVALID_ALERT 205 +# define SSL_R_INVALID_CCS_MESSAGE 260 # define SSL_R_INVALID_CERTIFICATE_OR_ALG 238 # define SSL_R_INVALID_COMMAND 280 # define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 @@ -543,7 +544,7 @@ int ERR_load_SSL_strings(void); # define SSL_R_INVALID_NULL_CMD_NAME 385 # define SSL_R_INVALID_SEQUENCE_NUMBER 402 # define SSL_R_INVALID_SERVERINFO_DATA 388 -# define SSL_R_INVALID_SESSION_ID 232 +# define SSL_R_INVALID_SESSION_ID 999 # define SSL_R_INVALID_SRP_USERNAME 357 # define SSL_R_INVALID_STATUS_RESPONSE 328 # define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 @@ -685,6 +686,7 @@ int ERR_load_SSL_strings(void); # define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 # define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242 # define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243 +# define SSL_R_UNEXPECTED_CCS_MESSAGE 262 # define SSL_R_UNEXPECTED_END_OF_EARLY_DATA 178 # define SSL_R_UNEXPECTED_MESSAGE 244 # define SSL_R_UNEXPECTED_RECORD 245 diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index 213f00104d..c1776e98f1 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -333,8 +333,11 @@ int ssl3_get_record(SSL *s) } } - if (SSL_IS_TLS13(s) && s->enc_read_ctx != NULL - && thisrr->type != SSL3_RT_APPLICATION_DATA) { + if (SSL_IS_TLS13(s) + && s->enc_read_ctx != NULL + && thisrr->type != SSL3_RT_APPLICATION_DATA + && (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC + || !SSL_IS_FIRST_HANDSHAKE(s))) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_GET_RECORD, SSL_R_BAD_RECORD_TYPE); return -1; @@ -444,6 +447,36 @@ int ssl3_get_record(SSL *s) & EVP_CIPH_FLAG_PIPELINE) && ssl3_record_app_data_waiting(s)); + if (num_recs == 1 + && thisrr->type == SSL3_RT_CHANGE_CIPHER_SPEC + && SSL_IS_TLS13(s) + && SSL_IS_FIRST_HANDSHAKE(s)) { + /* + * CCS messages must be exactly 1 byte long, containing the value 0x01 + */ + if (thisrr->length != 1 || thisrr->data[0] != 0x01) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_SSL3_GET_RECORD, + SSL_R_INVALID_CCS_MESSAGE); + return -1; + } + /* + * CCS messages are ignored in TLSv1.3. We treat it like an empty + * handshake record + */ + thisrr->type = SSL3_RT_HANDSHAKE; + RECORD_LAYER_inc_empty_record_count(&s->rlayer); + if (RECORD_LAYER_get_empty_record_count(&s->rlayer) + > MAX_EMPTY_RECORDS) { + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_GET_RECORD, + SSL_R_UNEXPECTED_CCS_MESSAGE); + return -1; + } + thisrr->read = 1; + RECORD_LAYER_set_numrpipes(&s->rlayer, 1); + + return 1; + } + /* * If in encrypt-then-mac mode calculate mac from encrypted record. All * the details below are public so no timing details can leak. diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index fa02b21b9d..3322685c19 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -852,6 +852,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INSUFFICIENT_SECURITY), "insufficient security"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_ALERT), "invalid alert"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CCS_MESSAGE), + "invalid ccs message"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CERTIFICATE_OR_ALG), "invalid certificate or alg"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_COMMAND), "invalid command"}, @@ -1125,6 +1127,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "unable to load ssl3 md5 routines"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES), "unable to load ssl3 sha1 routines"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_CCS_MESSAGE), + "unexpected ccs message"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_END_OF_EARLY_DATA), "unexpected end of early data"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_MESSAGE), "unexpected message"}, diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index c2d63fa100..23cb31ab69 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -326,7 +326,8 @@ (SSL_IS_TLS13(s) || (s)->early_data_state == SSL_EARLY_DATA_WRITING \ || (s)->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) -# define SSL_IS_FIRST_HANDSHAKE(S) ((s)->s3->tmp.finish_md_len == 0) +# define SSL_IS_FIRST_HANDSHAKE(S) ((s)->s3->tmp.finish_md_len == 0 \ + || (s)->s3->tmp.peer_finish_md_len == 0) /* See if we need explicit IV */ # define SSL_USE_EXPLICIT_IV(s) \