X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fstatem%2Fstatem_lib.c;h=8932ac44ca8acad2e07355ed52a9fafc341365a0;hp=79ac9be04ba9532ffa01682b3ca330dc631e2a0c;hb=HEAD;hpb=963eb12dbd551df71d7eb054e095c1b85f4aaab9 diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 79ac9be04b..8932ac44ca 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -20,6 +20,7 @@ #include #include #include +#include /* * Map error codes to TLS/SSL alart types. @@ -36,18 +37,62 @@ const unsigned char hrrrandom[] = { 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c }; +int ossl_statem_set_mutator(SSL *s, + ossl_statem_mutate_handshake_cb mutate_handshake_cb, + ossl_statem_finish_mutate_handshake_cb finish_mutate_handshake_cb, + void *mutatearg) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + sc->statem.mutate_handshake_cb = mutate_handshake_cb; + sc->statem.mutatearg = mutatearg; + sc->statem.finish_mutate_handshake_cb = finish_mutate_handshake_cb; + + return 1; +} + /* * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or * SSL3_RT_CHANGE_CIPHER_SPEC) */ -int ssl3_do_write(SSL *s, int type) +int ssl3_do_write(SSL_CONNECTION *s, uint8_t type) { int ret; size_t written = 0; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); - ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], + /* + * If we're running the test suite then we may need to mutate the message + * we've been asked to write. Does not happen in normal operation. + */ + if (s->statem.mutate_handshake_cb != NULL + && !s->statem.write_in_progress + && type == SSL3_RT_HANDSHAKE + && s->init_num >= SSL3_HM_HEADER_LENGTH) { + unsigned char *msg; + size_t msglen; + + if (!s->statem.mutate_handshake_cb((unsigned char *)s->init_buf->data, + s->init_num, + &msg, &msglen, + s->statem.mutatearg)) + return -1; + if (msglen < SSL3_HM_HEADER_LENGTH + || !BUF_MEM_grow(s->init_buf, msglen)) + return -1; + memcpy(s->init_buf->data, msg, msglen); + s->init_num = msglen; + s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; + s->statem.finish_mutate_handshake_cb(s->statem.mutatearg); + s->statem.write_in_progress = 1; + } + + ret = ssl3_write_bytes(ssl, type, &s->init_buf->data[s->init_off], s->init_num, &written); - if (ret < 0) + if (ret <= 0) return -1; if (type == SSL3_RT_HANDSHAKE) /* @@ -55,7 +100,8 @@ int ssl3_do_write(SSL *s, int type) * ignore the result anyway * TLS1.3 KeyUpdate and NewSessionTicket do not need to be added */ - if (!SSL_IS_TLS13(s) || (s->statem.hand_state != TLS_ST_SW_SESSION_TICKET + if (!SSL_CONNECTION_IS_TLS13(s) + || (s->statem.hand_state != TLS_ST_SW_SESSION_TICKET && s->statem.hand_state != TLS_ST_CW_KEY_UPDATE && s->statem.hand_state != TLS_ST_SW_KEY_UPDATE)) if (!ssl3_finish_mac(s, @@ -63,9 +109,10 @@ int ssl3_do_write(SSL *s, int type) written)) return -1; if (written == s->init_num) { + s->statem.write_in_progress = 0; if (s->msg_callback) s->msg_callback(1, s->version, type, s->init_buf->data, - (size_t)(s->init_off + s->init_num), s, + (size_t)(s->init_off + s->init_num), ssl, s->msg_callback_arg); return 1; } @@ -74,7 +121,7 @@ int ssl3_do_write(SSL *s, int type) return 0; } -int tls_close_construct_packet(SSL *s, WPACKET *pkt, int htype) +int tls_close_construct_packet(SSL_CONNECTION *s, WPACKET *pkt, int htype) { size_t msglen; @@ -88,9 +135,11 @@ int tls_close_construct_packet(SSL *s, WPACKET *pkt, int htype) return 1; } -int tls_setup_handshake(SSL *s) +int tls_setup_handshake(SSL_CONNECTION *s) { int ver_min, ver_max, ok; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (!ssl3_init_finished_mac(s)) { /* SSLfatal() already called */ @@ -106,18 +155,13 @@ int tls_setup_handshake(SSL *s) } /* Sanity check that we have MD5-SHA1 if we need it */ - if (s->ctx->ssl_digest_methods[SSL_MD_MD5_SHA1_IDX] == NULL) { - int md5sha1_needed = 0; + if (sctx->ssl_digest_methods[SSL_MD_MD5_SHA1_IDX] == NULL) { + int negotiated_minversion; + int md5sha1_needed_maxversion = SSL_CONNECTION_IS_DTLS(s) + ? DTLS1_VERSION : TLS1_1_VERSION; /* We don't have MD5-SHA1 - do we need it? */ - if (SSL_IS_DTLS(s)) { - if (DTLS_VERSION_LE(ver_max, DTLS1_VERSION)) - md5sha1_needed = 1; - } else { - if (ver_max <= TLS1_1_VERSION) - md5sha1_needed = 1; - } - if (md5sha1_needed) { + if (ssl_version_cmp(s, ver_max, md5sha1_needed_maxversion) <= 0) { SSLfatal_data(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_SUITABLE_DIGEST_ALGORITHM, "The max supported SSL/TLS version needs the" @@ -128,14 +172,12 @@ int tls_setup_handshake(SSL *s) } ok = 1; + /* Don't allow TLSv1.1 or below to be negotiated */ - if (SSL_IS_DTLS(s)) { - if (DTLS_VERSION_LT(ver_min, DTLS1_2_VERSION)) - ok = SSL_set_min_proto_version(s, DTLS1_2_VERSION); - } else { - if (ver_min < TLS1_2_VERSION) - ok = SSL_set_min_proto_version(s, TLS1_2_VERSION); - } + negotiated_minversion = SSL_CONNECTION_IS_DTLS(s) ? + DTLS1_2_VERSION : TLS1_2_VERSION; + if (ssl_version_cmp(s, ver_min, negotiated_minversion) < 0) + ok = SSL_set_min_proto_version(ssl, negotiated_minversion); if (!ok) { /* Shouldn't happen */ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, ERR_R_INTERNAL_ERROR); @@ -145,7 +187,7 @@ int tls_setup_handshake(SSL *s) ok = 0; if (s->server) { - STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(s); + STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(ssl); int i; /* @@ -155,16 +197,16 @@ int tls_setup_handshake(SSL *s) */ for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i); + int cipher_minprotover = SSL_CONNECTION_IS_DTLS(s) + ? c->min_dtls : c->min_tls; + int cipher_maxprotover = SSL_CONNECTION_IS_DTLS(s) + ? c->max_dtls : c->max_tls; - if (SSL_IS_DTLS(s)) { - if (DTLS_VERSION_GE(ver_max, c->min_dtls) && - DTLS_VERSION_LE(ver_max, c->max_dtls)) - ok = 1; - } else if (ver_max >= c->min_tls && ver_max <= c->max_tls) { + if (ssl_version_cmp(s, ver_max, cipher_minprotover) >= 0 + && ssl_version_cmp(s, ver_max, cipher_maxprotover) <= 0) { ok = 1; - } - if (ok) break; + } } if (!ok) { SSLfatal_data(s, SSL_AD_HANDSHAKE_FAILURE, @@ -175,18 +217,19 @@ int tls_setup_handshake(SSL *s) } if (SSL_IS_FIRST_HANDSHAKE(s)) { /* N.B. s->session_ctx == s->ctx here */ - tsan_counter(&s->session_ctx->stats.sess_accept); + ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_accept); } else { /* N.B. s->ctx may not equal s->session_ctx */ - tsan_counter(&s->ctx->stats.sess_accept_renegotiate); + ssl_tsan_counter(sctx, &sctx->stats.sess_accept_renegotiate); s->s3.tmp.cert_request = 0; } } else { if (SSL_IS_FIRST_HANDSHAKE(s)) - tsan_counter(&s->session_ctx->stats.sess_connect); + ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_connect); else - tsan_counter(&s->session_ctx->stats.sess_connect_renegotiate); + ssl_tsan_counter(s->session_ctx, + &s->session_ctx->stats.sess_connect_renegotiate); /* mark client_random uninitialized */ memset(s->s3.client_random, 0, sizeof(s->s3.client_random)); @@ -194,7 +237,7 @@ int tls_setup_handshake(SSL *s) s->s3.tmp.cert_req = 0; - if (SSL_IS_DTLS(s)) + if (SSL_CONNECTION_IS_DTLS(s)) s->statem.use_timer = 1; } @@ -208,23 +251,17 @@ int tls_setup_handshake(SSL *s) #define TLS13_TBS_START_SIZE 64 #define TLS13_TBS_PREAMBLE_SIZE (TLS13_TBS_START_SIZE + 33 + 1) -static int get_cert_verify_tbs_data(SSL *s, unsigned char *tls13tbs, +static int get_cert_verify_tbs_data(SSL_CONNECTION *s, unsigned char *tls13tbs, void **hdata, size_t *hdatalen) { -#ifdef CHARSET_EBCDIC - static const char servercontext[] = { 0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, - 0x33, 0x2c, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, - 0x69, 0x66, 0x79, 0x00 }; - static const char clientcontext[] = { 0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, - 0x33, 0x2c, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, - 0x69, 0x66, 0x79, 0x00 }; -#else - static const char servercontext[] = "TLS 1.3, server CertificateVerify"; - static const char clientcontext[] = "TLS 1.3, client CertificateVerify"; -#endif - if (SSL_IS_TLS13(s)) { + /* ASCII: "TLS 1.3, server CertificateVerify", in hex for EBCDIC compatibility */ + static const char servercontext[] = "\x54\x4c\x53\x20\x31\x2e\x33\x2c\x20\x73\x65\x72" + "\x76\x65\x72\x20\x43\x65\x72\x74\x69\x66\x69\x63\x61\x74\x65\x56\x65\x72\x69\x66\x79"; + /* ASCII: "TLS 1.3, client CertificateVerify", in hex for EBCDIC compatibility */ + static const char clientcontext[] = "\x54\x4c\x53\x20\x31\x2e\x33\x2c\x20\x63\x6c\x69" + "\x65\x6e\x74\x20\x43\x65\x72\x74\x69\x66\x69\x63\x61\x74\x65\x56\x65\x72\x69\x66\x79"; + + if (SSL_CONNECTION_IS_TLS13(s)) { size_t hashlen; /* Set the first 64 bytes of to-be-signed data to octet 32 */ @@ -269,7 +306,7 @@ static int get_cert_verify_tbs_data(SSL *s, unsigned char *tls13tbs, return 1; } -int tls_construct_cert_verify(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_cert_verify(SSL_CONNECTION *s, WPACKET *pkt) { EVP_PKEY *pkey = NULL; const EVP_MD *md = NULL; @@ -280,6 +317,7 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) unsigned char *sig = NULL; unsigned char tls13tbs[TLS13_TBS_PREAMBLE_SIZE + EVP_MAX_MD_SIZE]; const SIGALG_LOOKUP *lu = s->s3.tmp.sigalg; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (lu == NULL || s->s3.tmp.cert == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -287,14 +325,14 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) } pkey = s->s3.tmp.cert->privatekey; - if (pkey == NULL || !tls1_lookup_md(s->ctx, lu, &md)) { + if (pkey == NULL || !tls1_lookup_md(sctx, lu, &md)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } mctx = EVP_MD_CTX_new(); if (mctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } @@ -311,7 +349,7 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) if (EVP_DigestSignInit_ex(mctx, &pctx, md == NULL ? NULL : EVP_MD_get0_name(md), - s->ctx->libctx, s->ctx->propq, pkey, + sctx->libctx, sctx->propq, pkey, NULL) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; @@ -386,14 +424,14 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) OPENSSL_free(sig); EVP_MD_CTX_free(mctx); - return 1; + return CON_FUNC_SUCCESS; err: OPENSSL_free(sig); EVP_MD_CTX_free(mctx); - return 0; + return CON_FUNC_ERROR; } -MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_cert_verify(SSL_CONNECTION *s, PACKET *pkt) { EVP_PKEY *pkey = NULL; const unsigned char *data; @@ -403,27 +441,26 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR; int j; unsigned int len; - X509 *peer; const EVP_MD *md = NULL; size_t hdatalen = 0; void *hdata; unsigned char tls13tbs[TLS13_TBS_PREAMBLE_SIZE + EVP_MAX_MD_SIZE]; EVP_MD_CTX *mctx = EVP_MD_CTX_new(); EVP_PKEY_CTX *pctx = NULL; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (mctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } - peer = s->session->peer; - pkey = X509_get0_pubkey(peer); + pkey = tls_get_peer_pkey(s); if (pkey == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - if (ssl_cert_lookup_by_pkey(pkey, NULL) == NULL) { + if (ssl_cert_lookup_by_pkey(pkey, NULL, sctx) == NULL) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE); goto err; @@ -441,11 +478,12 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) goto err; } } else if (!tls1_set_peer_legacy_sigalg(s, pkey)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_R_LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED); goto err; } - if (!tls1_lookup_md(s->ctx, s->s3.tmp.peer_sigalg, &md)) { + if (!tls1_lookup_md(sctx, s->s3.tmp.peer_sigalg, &md)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -489,7 +527,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) if (EVP_DigestVerifyInit_ex(mctx, &pctx, md == NULL ? NULL : EVP_MD_get0_name(md), - s->ctx->libctx, s->ctx->propq, pkey, + sctx->libctx, sctx->propq, pkey, NULL) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; @@ -500,10 +538,8 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) if (pktype == NID_id_GostR3410_2001 || pktype == NID_id_GostR3410_2012_256 || pktype == NID_id_GostR3410_2012_512) { - if ((gost_data = OPENSSL_malloc(len)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + if ((gost_data = OPENSSL_malloc(len)) == NULL) goto err; - } BUF_reverse(gost_data, data, len); data = gost_data; } @@ -532,6 +568,11 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) } } else { j = EVP_DigestVerify(mctx, data, len, hdata, hdatalen); +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Ignore bad signatures when fuzzing */ + if (SSL_IS_QUIC_HANDSHAKE(s)) + j = 1; +#endif if (j <= 0) { SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_R_BAD_SIGNATURE); goto err; @@ -546,7 +587,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) * want to make sure that SSL_get1_peer_certificate() will return the actual * server certificate from the client_cert_cb callback. */ - if (!s->server && SSL_IS_TLS13(s) && s->s3.tmp.cert_req == 1) + if (!s->server && SSL_CONNECTION_IS_TLS13(s) && s->s3.tmp.cert_req == 1) ret = MSG_PROCESS_CONTINUE_PROCESSING; else ret = MSG_PROCESS_CONTINUE_READING; @@ -560,61 +601,66 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) return ret; } -int tls_construct_finished(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_finished(SSL_CONNECTION *s, WPACKET *pkt) { size_t finish_md_len; const char *sender; size_t slen; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); /* This is a real handshake so make sure we clean it up at the end */ if (!s->server && s->post_handshake_auth != SSL_PHA_REQUESTED) s->statem.cleanuphand = 1; /* - * We only change the keys if we didn't already do this when we sent the - * client certificate + * If we attempted to write early data or we're in middlebox compat mode + * then we deferred changing the handshake write keys to the last possible + * moment. If we didn't already do this when we sent the client certificate + * then we need to do it now. */ - if (SSL_IS_TLS13(s) + if (SSL_CONNECTION_IS_TLS13(s) && !s->server + && (s->early_data_state != SSL_EARLY_DATA_NONE + || (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0) && s->s3.tmp.cert_req == 0 - && (!s->method->ssl3_enc->change_cipher_state(s, + && (!ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE))) {; /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } if (s->server) { - sender = s->method->ssl3_enc->server_finished_label; - slen = s->method->ssl3_enc->server_finished_label_len; + sender = ssl->method->ssl3_enc->server_finished_label; + slen = ssl->method->ssl3_enc->server_finished_label_len; } else { - sender = s->method->ssl3_enc->client_finished_label; - slen = s->method->ssl3_enc->client_finished_label_len; + sender = ssl->method->ssl3_enc->client_finished_label; + slen = ssl->method->ssl3_enc->client_finished_label_len; } - finish_md_len = s->method->ssl3_enc->final_finish_mac(s, - sender, slen, - s->s3.tmp.finish_md); + finish_md_len = ssl->method->ssl3_enc->final_finish_mac(s, + sender, slen, + s->s3.tmp.finish_md); if (finish_md_len == 0) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } s->s3.tmp.finish_md_len = finish_md_len; if (!WPACKET_memcpy(pkt, s->s3.tmp.finish_md, finish_md_len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } /* * Log the master secret, if logging is enabled. We don't log it for * TLSv1.3: there's a different key schedule for that. */ - if (!SSL_IS_TLS13(s) && !ssl_log_secret(s, MASTER_SECRET_LABEL, - s->session->master_key, - s->session->master_key_length)) { + if (!SSL_CONNECTION_IS_TLS13(s) + && !ssl_log_secret(s, MASTER_SECRET_LABEL, s->session->master_key, + s->session->master_key_length)) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } /* @@ -622,7 +668,7 @@ int tls_construct_finished(SSL *s, WPACKET *pkt) */ if (!ossl_assert(finish_md_len <= EVP_MAX_MD_SIZE)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } if (!s->server) { memcpy(s->s3.previous_client_finished, s->s3.tmp.finish_md, @@ -634,21 +680,21 @@ int tls_construct_finished(SSL *s, WPACKET *pkt) s->s3.previous_server_finished_len = finish_md_len; } - return 1; + return CON_FUNC_SUCCESS; } -int tls_construct_key_update(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_key_update(SSL_CONNECTION *s, WPACKET *pkt) { if (!WPACKET_put_bytes_u8(pkt, s->key_update)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } s->key_update = SSL_KEY_UPDATE_NONE; - return 1; + return CON_FUNC_SUCCESS; } -MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_key_update(SSL_CONNECTION *s, PACKET *pkt) { unsigned int updatetype; @@ -697,22 +743,23 @@ MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt) * ssl3_take_mac calculates the Finished MAC for the handshakes messages seen * to far. */ -int ssl3_take_mac(SSL *s) +int ssl3_take_mac(SSL_CONNECTION *s) { const char *sender; size_t slen; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (!s->server) { - sender = s->method->ssl3_enc->server_finished_label; - slen = s->method->ssl3_enc->server_finished_label_len; + sender = ssl->method->ssl3_enc->server_finished_label; + slen = ssl->method->ssl3_enc->server_finished_label_len; } else { - sender = s->method->ssl3_enc->client_finished_label; - slen = s->method->ssl3_enc->client_finished_label_len; + sender = ssl->method->ssl3_enc->client_finished_label; + slen = ssl->method->ssl3_enc->client_finished_label_len; } s->s3.tmp.peer_finish_md_len = - s->method->ssl3_enc->final_finish_mac(s, sender, slen, - s->s3.tmp.peer_finish_md); + ssl->method->ssl3_enc->final_finish_mac(s, sender, slen, + s->s3.tmp.peer_finish_md); if (s->s3.tmp.peer_finish_md_len == 0) { /* SSLfatal() already called */ @@ -722,7 +769,8 @@ int ssl3_take_mac(SSL *s) return 1; } -MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL_CONNECTION *s, + PACKET *pkt) { size_t remain; @@ -732,7 +780,7 @@ MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt) * been consumed by ssl_get_message() so there should be no bytes left, * unless we're using DTLS1_BAD_VER, which has an extra 2 bytes */ - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if ((s->version == DTLS1_BAD_VER && remain != DTLS1_CCS_HEADER_LENGTH + 1) || (s->version != DTLS1_BAD_VER @@ -759,9 +807,7 @@ MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } - if (SSL_IS_DTLS(s)) { - dtls1_reset_seq_numbers(s, SSL3_CC_READ); - + if (SSL_CONNECTION_IS_DTLS(s)) { if (s->version == DTLS1_BAD_VER) s->d1->handshake_read_seq++; @@ -771,29 +817,35 @@ MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt) * SCTP-Auth can be deleted when a CCS is sent. Will be ignored if no * SCTP is used */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL); + BIO_ctrl(SSL_get_wbio(SSL_CONNECTION_GET_SSL(s)), + BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL); #endif } return MSG_PROCESS_CONTINUE_READING; } -MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt) { size_t md_len; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + int was_first = SSL_IS_FIRST_HANDSHAKE(s); + int ok; /* This is a real handshake so make sure we clean it up at the end */ if (s->server) { /* * To get this far we must have read encrypted data from the client. We - * no longer tolerate unencrypted alerts. This value is ignored if less - * than TLSv1.3 + * no longer tolerate unencrypted alerts. This is ignored if less than + * TLSv1.3 */ - s->statem.enc_read_state = ENC_READ_STATE_VALID; + if (s->rlayer.rrlmethod->set_plain_alerts != NULL) + s->rlayer.rrlmethod->set_plain_alerts(s->rlayer.rrl, 0); if (s->post_handshake_auth != SSL_PHA_REQUESTED) s->statem.cleanuphand = 1; - if (SSL_IS_TLS13(s) && !tls13_save_handshake_digest_for_pha(s)) { + if (SSL_CONNECTION_IS_TLS13(s) + && !tls13_save_handshake_digest_for_pha(s)) { /* SSLfatal() already called */ return MSG_PROCESS_ERROR; } @@ -803,13 +855,14 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) * In TLSv1.3 a Finished message signals a key change so the end of the * message must be on a record boundary. */ - if (SSL_IS_TLS13(s) && RECORD_LAYER_processed_read_pending(&s->rlayer)) { + if (SSL_CONNECTION_IS_TLS13(s) + && RECORD_LAYER_processed_read_pending(&s->rlayer)) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_NOT_ON_RECORD_BOUNDARY); return MSG_PROCESS_ERROR; } /* If this occurs, we have missed a message */ - if (!SSL_IS_TLS13(s) && !s->s3.change_cipher_spec) { + if (!SSL_CONNECTION_IS_TLS13(s) && !s->s3.change_cipher_spec) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_GOT_A_FIN_BEFORE_A_CCS); return MSG_PROCESS_ERROR; } @@ -822,8 +875,16 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } - if (CRYPTO_memcmp(PACKET_data(pkt), s->s3.tmp.peer_finish_md, - md_len) != 0) { + ok = CRYPTO_memcmp(PACKET_data(pkt), s->s3.tmp.peer_finish_md, + md_len); +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if (ok != 0) { + if ((PACKET_data(pkt)[0] ^ s->s3.tmp.peer_finish_md[0]) != 0xFF) { + ok = 0; + } + } +#endif + if (ok != 0) { SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_R_DIGEST_CHECK_FAILED); return MSG_PROCESS_ERROR; } @@ -849,24 +910,24 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) * In TLS1.3 we also have to change cipher state and do any final processing * of the initial server flight (if we are a client) */ - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { if (s->server) { if (s->post_handshake_auth != SSL_PHA_REQUESTED && - !s->method->ssl3_enc->change_cipher_state(s, - SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_SERVER_READ)) { + !ssl->method->ssl3_enc->change_cipher_state(s, + SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_SERVER_READ)) { /* SSLfatal() already called */ return MSG_PROCESS_ERROR; } } else { /* TLS 1.3 gets the secret size from the handshake md */ size_t dummy; - if (!s->method->ssl3_enc->generate_master_secret(s, + if (!ssl->method->ssl3_enc->generate_master_secret(s, s->master_secret, s->handshake_secret, 0, &dummy)) { /* SSLfatal() already called */ return MSG_PROCESS_ERROR; } - if (!s->method->ssl3_enc->change_cipher_state(s, + if (!ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_CLIENT_READ)) { /* SSLfatal() already called */ return MSG_PROCESS_ERROR; @@ -878,39 +939,50 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) } } + if (was_first + && !SSL_IS_FIRST_HANDSHAKE(s) + && s->rlayer.rrlmethod->set_first_handshake != NULL) + s->rlayer.rrlmethod->set_first_handshake(s->rlayer.rrl, 0); + return MSG_PROCESS_FINISHED_READING; } -int tls_construct_change_cipher_spec(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_change_cipher_spec(SSL_CONNECTION *s, WPACKET *pkt) { if (!WPACKET_put_bytes_u8(pkt, SSL3_MT_CCS)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } - return 1; + return CON_FUNC_SUCCESS; } /* Add a certificate to the WPACKET */ -static int ssl_add_cert_to_wpacket(SSL *s, WPACKET *pkt, X509 *x, int chain) +static int ssl_add_cert_to_wpacket(SSL_CONNECTION *s, WPACKET *pkt, + X509 *x, int chain, int for_comp) { int len; unsigned char *outbytes; + int context = SSL_EXT_TLS1_3_CERTIFICATE; + + if (for_comp) + context |= SSL_EXT_TLS1_3_CERTIFICATE_COMPRESSION; len = i2d_X509(x, NULL); if (len < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BUF_LIB); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BUF_LIB); return 0; } if (!WPACKET_sub_allocate_bytes_u24(pkt, len, &outbytes) || i2d_X509(x, &outbytes) != len) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - if (SSL_IS_TLS13(s) - && !tls_construct_extensions(s, pkt, SSL_EXT_TLS1_3_CERTIFICATE, x, - chain)) { + if ((SSL_CONNECTION_IS_TLS13(s) || for_comp) + && !tls_construct_extensions(s, pkt, context, x, chain)) { /* SSLfatal() already called */ return 0; } @@ -919,13 +991,14 @@ static int ssl_add_cert_to_wpacket(SSL *s, WPACKET *pkt, X509 *x, int chain) } /* Add certificate chain to provided WPACKET */ -static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) +static int ssl_add_cert_chain(SSL_CONNECTION *s, WPACKET *pkt, CERT_PKEY *cpk, int for_comp) { int i, chain_count; X509 *x; STACK_OF(X509) *extra_certs; STACK_OF(X509) *chain = NULL; X509_STORE *chain_store; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (cpk == NULL || cpk->x509 == NULL) return 1; @@ -938,26 +1011,28 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) if (cpk->chain != NULL) extra_certs = cpk->chain; else - extra_certs = s->ctx->extra_certs; + extra_certs = sctx->extra_certs; if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs) chain_store = NULL; else if (s->cert->chain_store) chain_store = s->cert->chain_store; else - chain_store = s->ctx->cert_store; + chain_store = sctx->cert_store; if (chain_store != NULL) { - X509_STORE_CTX *xs_ctx = X509_STORE_CTX_new_ex(s->ctx->libctx, - s->ctx->propq); + X509_STORE_CTX *xs_ctx = X509_STORE_CTX_new_ex(sctx->libctx, + sctx->propq); if (xs_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_X509_LIB); return 0; } if (!X509_STORE_CTX_init(xs_ctx, chain_store, x, NULL)) { X509_STORE_CTX_free(xs_ctx); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_X509_LIB); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_X509_LIB); return 0; } /* @@ -979,14 +1054,15 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) ERR_raise(ERR_LIB_SSL, SSL_R_CA_MD_TOO_WEAK); #endif X509_STORE_CTX_free(xs_ctx); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, i); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, i); return 0; } chain_count = sk_X509_num(chain); for (i = 0; i < chain_count; i++) { x = sk_X509_value(chain, i); - if (!ssl_add_cert_to_wpacket(s, pkt, x, i)) { + if (!ssl_add_cert_to_wpacket(s, pkt, x, i, for_comp)) { /* SSLfatal() already called */ X509_STORE_CTX_free(xs_ctx); return 0; @@ -996,16 +1072,17 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) } else { i = ssl_security_cert_chain(s, extra_certs, x, 0); if (i != 1) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, i); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, i); return 0; } - if (!ssl_add_cert_to_wpacket(s, pkt, x, 0)) { + if (!ssl_add_cert_to_wpacket(s, pkt, x, 0, for_comp)) { /* SSLfatal() already called */ return 0; } for (i = 0; i < sk_X509_num(extra_certs); i++) { x = sk_X509_value(extra_certs, i); - if (!ssl_add_cert_to_wpacket(s, pkt, x, i + 1)) { + if (!ssl_add_cert_to_wpacket(s, pkt, x, i + 1, for_comp)) { /* SSLfatal() already called */ return 0; } @@ -1014,18 +1091,306 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) return 1; } -unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) +EVP_PKEY* tls_get_peer_pkey(const SSL_CONNECTION *sc) +{ + if (sc->session->peer_rpk != NULL) + return sc->session->peer_rpk; + if (sc->session->peer != NULL) + return X509_get0_pubkey(sc->session->peer); + return NULL; +} + +int tls_process_rpk(SSL_CONNECTION *sc, PACKET *pkt, EVP_PKEY **peer_rpk) +{ + EVP_PKEY *pkey = NULL; + int ret = 0; + RAW_EXTENSION *rawexts = NULL; + PACKET extensions; + PACKET context; + unsigned long cert_len = 0, spki_len = 0; + const unsigned char *spki, *spkistart; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(sc); + + /*- + * ---------------------------- + * TLS 1.3 Certificate message: + * ---------------------------- + * https://datatracker.ietf.org/doc/html/rfc8446#section-4.4.2 + * + * enum { + * X509(0), + * RawPublicKey(2), + * (255) + * } CertificateType; + * + * struct { + * select (certificate_type) { + * case RawPublicKey: + * // From RFC 7250 ASN.1_subjectPublicKeyInfo + * opaque ASN1_subjectPublicKeyInfo<1..2^24-1>; + * + * case X509: + * opaque cert_data<1..2^24-1>; + * }; + * Extension extensions<0..2^16-1>; + * } CertificateEntry; + * + * struct { + * opaque certificate_request_context<0..2^8-1>; + * CertificateEntry certificate_list<0..2^24-1>; + * } Certificate; + * + * The client MUST send a Certificate message if and only if the server + * has requested client authentication via a CertificateRequest message + * (Section 4.3.2). If the server requests client authentication but no + * suitable certificate is available, the client MUST send a Certificate + * message containing no certificates (i.e., with the "certificate_list" + * field having length 0). + * + * ---------------------------- + * TLS 1.2 Certificate message: + * ---------------------------- + * https://datatracker.ietf.org/doc/html/rfc7250#section-3 + * + * opaque ASN.1Cert<1..2^24-1>; + * + * struct { + * select(certificate_type){ + * + * // certificate type defined in this document. + * case RawPublicKey: + * opaque ASN.1_subjectPublicKeyInfo<1..2^24-1>; + * + * // X.509 certificate defined in RFC 5246 + * case X.509: + * ASN.1Cert certificate_list<0..2^24-1>; + * + * // Additional certificate type based on + * // "TLS Certificate Types" subregistry + * }; + * } Certificate; + * + * ------------- + * Consequently: + * ------------- + * After the (TLS 1.3 only) context octet string (1 byte length + data) the + * Certificate message has a 3-byte length that is zero in the client to + * server message when the client has no RPK to send. In that case, there + * are no (TLS 1.3 only) per-certificate extensions either, because the + * [CertificateEntry] list is empty. + * + * In the server to client direction, or when the client had an RPK to send, + * the TLS 1.3 message just prepends the length of the RPK+extensions, + * while TLS <= 1.2 sends just the RPK (octet-string). + * + * The context must be zero-length in the server to client direction, and + * must match the value recorded in the certificate request in the client + * to server direction. + */ + if (SSL_CONNECTION_IS_TLS13(sc)) { + if (!PACKET_get_length_prefixed_1(pkt, &context)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_INVALID_CONTEXT); + goto err; + } + if (sc->server) { + if (sc->pha_context == NULL) { + if (PACKET_remaining(&context) != 0) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_INVALID_CONTEXT); + goto err; + } + } else { + if (!PACKET_equal(&context, sc->pha_context, sc->pha_context_len)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_INVALID_CONTEXT); + goto err; + } + } + } else { + if (PACKET_remaining(&context) != 0) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_INVALID_CONTEXT); + goto err; + } + } + } + + if (!PACKET_get_net_3(pkt, &cert_len) + || PACKET_remaining(pkt) != cert_len) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); + goto err; + } + + /* + * The list length may be zero when there is no RPK. In the case of TLS + * 1.2 this is actually the RPK length, which cannot be zero as specified, + * but that breaks the ability of the client to decline client auth. We + * overload the 0 RPK length to mean "no RPK". This interpretation is + * also used some other (reference?) implementations, but is not supported + * by the verbatim RFC7250 text. + */ + if (cert_len == 0) + return 1; + + if (SSL_CONNECTION_IS_TLS13(sc)) { + /* + * With TLS 1.3, a non-empty explicit-length RPK octet-string followed + * by a possibly empty extension block. + */ + if (!PACKET_get_net_3(pkt, &spki_len)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); + goto err; + } + if (spki_len == 0) { + /* empty RPK */ + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_EMPTY_RAW_PUBLIC_KEY); + goto err; + } + } else { + spki_len = cert_len; + } + + if (!PACKET_get_bytes(pkt, &spki, spki_len)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); + goto err; + } + spkistart = spki; + if ((pkey = d2i_PUBKEY_ex(NULL, &spki, spki_len, sctx->libctx, sctx->propq)) == NULL + || spki != (spkistart + spki_len)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); + goto err; + } + if (EVP_PKEY_missing_parameters(pkey)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, + SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); + goto err; + } + + /* Process the Extensions block */ + if (SSL_CONNECTION_IS_TLS13(sc)) { + if (PACKET_remaining(pkt) != (cert_len - 3 - spki_len)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_LENGTH); + goto err; + } + if (!PACKET_as_length_prefixed_2(pkt, &extensions) + || PACKET_remaining(pkt) != 0) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); + goto err; + } + if (!tls_collect_extensions(sc, &extensions, SSL_EXT_TLS1_3_RAW_PUBLIC_KEY, + &rawexts, NULL, 1)) { + /* SSLfatal already called */ + goto err; + } + /* chain index is always zero and fin always 1 for RPK */ + if (!tls_parse_all_extensions(sc, SSL_EXT_TLS1_3_RAW_PUBLIC_KEY, + rawexts, NULL, 0, 1)) { + /* SSLfatal already called */ + goto err; + } + } + ret = 1; + if (peer_rpk != NULL) { + *peer_rpk = pkey; + pkey = NULL; + } + + err: + OPENSSL_free(rawexts); + EVP_PKEY_free(pkey); + return ret; +} + +unsigned long tls_output_rpk(SSL_CONNECTION *sc, WPACKET *pkt, CERT_PKEY *cpk) +{ + int pdata_len = 0; + unsigned char *pdata = NULL; + X509_PUBKEY *xpk = NULL; + unsigned long ret = 0; + X509 *x509 = NULL; + + if (cpk != NULL && cpk->x509 != NULL) { + x509 = cpk->x509; + /* Get the RPK from the certificate */ + xpk = X509_get_X509_PUBKEY(cpk->x509); + if (xpk == NULL) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + pdata_len = i2d_X509_PUBKEY(xpk, &pdata); + } else if (cpk != NULL && cpk->privatekey != NULL) { + /* Get the RPK from the private key */ + pdata_len = i2d_PUBKEY(cpk->privatekey, &pdata); + } else { + /* The server RPK is not optional */ + if (sc->server) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + /* The client can send a zero length certificate list */ + if (!WPACKET_sub_memcpy_u24(pkt, pdata, pdata_len)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + return 1; + } + + if (pdata_len <= 0) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* + * TLSv1.2 is _just_ the raw public key + * TLSv1.3 includes extensions, so there's a length wrapper + */ + if (SSL_CONNECTION_IS_TLS13(sc)) { + if (!WPACKET_start_sub_packet_u24(pkt)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (!WPACKET_sub_memcpy_u24(pkt, pdata, pdata_len)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (SSL_CONNECTION_IS_TLS13(sc)) { + /* + * Only send extensions relevant to raw public keys. Until such + * extensions are defined, this will be an empty set of extensions. + * |x509| may be NULL, which raw public-key extensions need to handle. + */ + if (!tls_construct_extensions(sc, pkt, SSL_EXT_TLS1_3_RAW_PUBLIC_KEY, + x509, 0)) { + /* SSLfatal() already called */ + goto err; + } + if (!WPACKET_close(pkt)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + ret = 1; + err: + OPENSSL_free(pdata); + return ret; +} + +unsigned long ssl3_output_cert_chain(SSL_CONNECTION *s, WPACKET *pkt, + CERT_PKEY *cpk, int for_comp) { if (!WPACKET_start_sub_packet_u24(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - if (!ssl_add_cert_chain(s, pkt, cpk)) + if (!ssl_add_cert_chain(s, pkt, cpk, for_comp)) return 0; if (!WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -1037,14 +1402,16 @@ unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) * in NBIO events. If |clearbufs| is set then init_buf and the wbio buffer is * freed up as well. */ -WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, +WORK_STATE tls_finish_handshake(SSL_CONNECTION *s, ossl_unused WORK_STATE wst, int clearbufs, int stop) { void (*cb) (const SSL *ssl, int type, int val) = NULL; int cleanuphand = s->statem.cleanuphand; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (clearbufs) { - if (!SSL_IS_DTLS(s) + if (!SSL_CONNECTION_IS_DTLS(s) #ifndef OPENSSL_NO_SCTP /* * RFC6083: SCTP provides a reliable and in-sequence transport service for DTLS @@ -1052,7 +1419,7 @@ WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, * MUST NOT be used. * Hence the init_buf can be cleared when DTLS over SCTP as transport is used. */ - || BIO_dgram_is_sctp(SSL_get_wbio(s)) + || BIO_dgram_is_sctp(SSL_get_wbio(ssl)) #endif ) { /* @@ -1070,7 +1437,7 @@ WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, s->init_num = 0; } - if (SSL_IS_TLS13(s) && !s->server + if (SSL_CONNECTION_IS_TLS13(s) && !s->server && s->post_handshake_auth == SSL_PHA_REQUESTED) s->post_handshake_auth = SSL_PHA_EXT_SENT; @@ -1092,14 +1459,14 @@ WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, * In TLSv1.3 we update the cache as part of constructing the * NewSessionTicket */ - if (!SSL_IS_TLS13(s)) + if (!SSL_CONNECTION_IS_TLS13(s)) ssl_update_cache(s, SSL_SESS_CACHE_SERVER); /* N.B. s->ctx may not equal s->session_ctx */ - tsan_counter(&s->ctx->stats.sess_accept_good); + ssl_tsan_counter(sctx, &sctx->stats.sess_accept_good); s->handshake_func = ossl_statem_accept; } else { - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { /* * We encourage applications to only use TLSv1.3 tickets once, * so we remove this one from the cache. @@ -1115,13 +1482,15 @@ WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); } if (s->hit) - tsan_counter(&s->session_ctx->stats.sess_hit); + ssl_tsan_counter(s->session_ctx, + &s->session_ctx->stats.sess_hit); s->handshake_func = ossl_statem_connect; - tsan_counter(&s->session_ctx->stats.sess_connect_good); + ssl_tsan_counter(s->session_ctx, + &s->session_ctx->stats.sess_connect_good); } - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { /* done with handshaking */ s->d1->handshake_read_seq = 0; s->d1->handshake_write_seq = 0; @@ -1132,17 +1501,17 @@ WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, if (s->info_callback != NULL) cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; + else if (sctx->info_callback != NULL) + cb = sctx->info_callback; /* The callback may expect us to not be in init at handshake done */ ossl_statem_set_in_init(s, 0); if (cb != NULL) { if (cleanuphand - || !SSL_IS_TLS13(s) + || !SSL_CONNECTION_IS_TLS13(s) || SSL_IS_FIRST_HANDSHAKE(s)) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); + cb(ssl, SSL_CB_HANDSHAKE_DONE, 1); } if (!stop) { @@ -1154,21 +1523,23 @@ WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, return WORK_FINISHED_STOP; } -int tls_get_message_header(SSL *s, int *mt) +int tls_get_message_header(SSL_CONNECTION *s, int *mt) { /* s->init_num < SSL3_HM_HEADER_LENGTH */ - int skip_message, i, recvd_type; + int skip_message, i; + uint8_t recvd_type; unsigned char *p; size_t l, readbytes; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); p = (unsigned char *)s->init_buf->data; do { while (s->init_num < SSL3_HM_HEADER_LENGTH) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &recvd_type, - &p[s->init_num], - SSL3_HM_HEADER_LENGTH - s->init_num, - 0, &readbytes); + i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, &recvd_type, + &p[s->init_num], + SSL3_HM_HEADER_LENGTH - s->init_num, + 0, &readbytes); if (i <= 0) { s->rwstate = SSL_READING; return 0; @@ -1223,7 +1594,7 @@ int tls_get_message_header(SSL *s, int *mt) if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - p, SSL3_HM_HEADER_LENGTH, s, + p, SSL3_HM_HEADER_LENGTH, ssl, s->msg_callback_arg); } } while (skip_message); @@ -1240,8 +1611,7 @@ int tls_get_message_header(SSL *s, int *mt) * Total message size is the remaining record bytes to read * plus the SSL3_HM_HEADER_LENGTH bytes that we already read */ - l = RECORD_LAYER_get_rrec_length(&s->rlayer) - + SSL3_HM_HEADER_LENGTH; + l = s->rlayer.tlsrecs[0].length + SSL3_HM_HEADER_LENGTH; s->s3.tmp.message_size = l; s->init_msg = s->init_buf->data; @@ -1263,11 +1633,12 @@ int tls_get_message_header(SSL *s, int *mt) return 1; } -int tls_get_message_body(SSL *s, size_t *len) +int tls_get_message_body(SSL_CONNECTION *s, size_t *len) { size_t n, readbytes; unsigned char *p; int i; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (s->s3.tmp.message_type == SSL3_MT_CHANGE_CIPHER_SPEC) { /* We've already read everything in */ @@ -1278,8 +1649,8 @@ int tls_get_message_body(SSL *s, size_t *len) p = s->init_msg; n = s->s3.tmp.message_size - s->init_num; while (n > 0) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL, - &p[s->init_num], n, 0, &readbytes); + i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, + &p[s->init_num], n, 0, &readbytes); if (i <= 0) { s->rwstate = SSL_READING; *len = 0; @@ -1309,7 +1680,7 @@ int tls_get_message_body(SSL *s, size_t *len) } if (s->msg_callback) s->msg_callback(0, SSL2_VERSION, 0, s->init_buf->data, - (size_t)s->init_num, s, s->msg_callback_arg); + (size_t)s->init_num, ssl, s->msg_callback_arg); } else { /* * We defer feeding in the HRR until later. We'll do it as part of @@ -1319,8 +1690,9 @@ int tls_get_message_body(SSL *s, size_t *len) */ #define SERVER_HELLO_RANDOM_OFFSET (SSL3_HM_HEADER_LENGTH + 2) /* KeyUpdate and NewSessionTicket do not need to be added */ - if (!SSL_IS_TLS13(s) || (s->s3.tmp.message_type != SSL3_MT_NEWSESSION_TICKET - && s->s3.tmp.message_type != SSL3_MT_KEY_UPDATE)) { + if (!SSL_CONNECTION_IS_TLS13(s) + || (s->s3.tmp.message_type != SSL3_MT_NEWSESSION_TICKET + && s->s3.tmp.message_type != SSL3_MT_KEY_UPDATE)) { if (s->s3.tmp.message_type != SSL3_MT_SERVER_HELLO || s->init_num < SERVER_HELLO_RANDOM_OFFSET + SSL3_RANDOM_SIZE || memcmp(hrrrandom, @@ -1336,7 +1708,7 @@ int tls_get_message_body(SSL *s, size_t *len) } if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, - (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s, + (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, ssl, s->msg_callback_arg); } @@ -1400,22 +1772,30 @@ int ssl_x509err2alert(int x509err) return tp->alert; } -int ssl_allow_compression(SSL *s) +int ssl_allow_compression(SSL_CONNECTION *s) { if (s->options & SSL_OP_NO_COMPRESSION) return 0; return ssl_security(s, SSL_SECOP_COMPRESSION, 0, 0, NULL); } -static int version_cmp(const SSL *s, int a, int b) +/* + * SSL/TLS/DTLS version comparison + * + * Returns + * 0 if versiona is equal to versionb + * 1 if versiona is greater than versionb + * -1 if versiona is less than versionb + */ +int ssl_version_cmp(const SSL_CONNECTION *s, int versiona, int versionb) { - int dtls = SSL_IS_DTLS(s); + int dtls = SSL_CONNECTION_IS_DTLS(s); - if (a == b) + if (versiona == versionb) return 0; if (!dtls) - return a < b ? -1 : 1; - return DTLS_VERSION_LT(a, b) ? -1 : 1; + return versiona < versionb ? -1 : 1; + return DTLS_VERSION_LT(versiona, versionb) ? -1 : 1; } typedef struct { @@ -1487,17 +1867,17 @@ static const version_info dtls_version_table[] = { * * Returns 0 on success, or an SSL error reason on failure. */ -static int ssl_method_error(const SSL *s, const SSL_METHOD *method) +static int ssl_method_error(const SSL_CONNECTION *s, const SSL_METHOD *method) { int version = method->version; if ((s->min_proto_version != 0 && - version_cmp(s, version, s->min_proto_version) < 0) || + ssl_version_cmp(s, version, s->min_proto_version) < 0) || ssl_security(s, SSL_SECOP_VERSION, 0, version, NULL) == 0) return SSL_R_VERSION_TOO_LOW; if (s->max_proto_version != 0 && - version_cmp(s, version, s->max_proto_version) > 0) + ssl_version_cmp(s, version, s->max_proto_version) > 0) return SSL_R_VERSION_TOO_HIGH; if ((s->options & method->mask) != 0) @@ -1513,19 +1893,20 @@ static int ssl_method_error(const SSL *s, const SSL_METHOD *method) * certificate type, or has PSK or a certificate callback configured, or has * a servername callback configure. Otherwise returns 0. */ -static int is_tls13_capable(const SSL *s) +static int is_tls13_capable(const SSL_CONNECTION *s) { - int i; + size_t i; int curve; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); - if (!ossl_assert(s->ctx != NULL) || !ossl_assert(s->session_ctx != NULL)) + if (!ossl_assert(sctx != NULL) || !ossl_assert(s->session_ctx != NULL)) return 0; /* * A servername callback can change the available certs, so if a servername * cb is set then we just assume TLSv1.3 will be ok */ - if (s->ctx->ext.servername_cb != NULL + if (sctx->ext.servername_cb != NULL || s->session_ctx->ext.servername_cb != NULL) return 1; @@ -1537,7 +1918,8 @@ static int is_tls13_capable(const SSL *s) if (s->psk_find_session_cb != NULL || s->cert->cert_cb != NULL) return 1; - for (i = 0; i < SSL_PKEY_NUM; i++) { + /* All provider-based sig algs are required to support at least TLS1.3 */ + for (i = 0; i < s->ssl_pkey_num; i++) { /* Skip over certs disallowed for TLSv1.3 */ switch (i) { case SSL_PKEY_DSA_SIGN: @@ -1574,15 +1956,16 @@ static int is_tls13_capable(const SSL *s) * * Returns 1 when supported, otherwise 0 */ -int ssl_version_supported(const SSL *s, int version, const SSL_METHOD **meth) +int ssl_version_supported(const SSL_CONNECTION *s, int version, + const SSL_METHOD **meth) { const version_info *vent; const version_info *table; - switch (s->method->version) { + switch (SSL_CONNECTION_GET_SSL(s)->method->version) { default: /* Version should match method version for non-ANY method */ - return version_cmp(s, version, s->version) == 0; + return ssl_version_cmp(s, version, s->version) == 0; case TLS_ANY_VERSION: table = tls_version_table; break; @@ -1592,16 +1975,19 @@ int ssl_version_supported(const SSL *s, int version, const SSL_METHOD **meth) } for (vent = table; - vent->version != 0 && version_cmp(s, version, vent->version) <= 0; + vent->version != 0 && ssl_version_cmp(s, version, vent->version) <= 0; ++vent) { - if (vent->cmeth != NULL - && version_cmp(s, version, vent->version) == 0 - && ssl_method_error(s, vent->cmeth()) == 0 + const SSL_METHOD *(*thismeth)(void) = s->server ? vent->smeth + : vent->cmeth; + + if (thismeth != NULL + && ssl_version_cmp(s, version, vent->version) == 0 + && ssl_method_error(s, thismeth()) == 0 && (!s->server || version != TLS1_3_VERSION || is_tls13_capable(s))) { if (meth != NULL) - *meth = vent->cmeth(); + *meth = thismeth(); return 1; } } @@ -1617,26 +2003,27 @@ int ssl_version_supported(const SSL *s, int version, const SSL_METHOD **meth) * * Returns 1 when using the highest enabled version, 0 otherwise. */ -int ssl_check_version_downgrade(SSL *s) +int ssl_check_version_downgrade(SSL_CONNECTION *s) { const version_info *vent; const version_info *table; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); /* * Check that the current protocol is the highest enabled version - * (according to s->ctx->method, as version negotiation may have changed + * (according to ssl->defltmethod, as version negotiation may have changed * s->method). */ - if (s->version == s->ctx->method->version) + if (s->version == ssl->defltmeth->version) return 1; /* * Apparently we're using a version-flexible SSL_METHOD (not at its * highest protocol version). */ - if (s->ctx->method->version == TLS_method()->version) + if (ssl->defltmeth->version == TLS_method()->version) table = tls_version_table; - else if (s->ctx->method->version == DTLS_method()->version) + else if (ssl->defltmeth->version == DTLS_method()->version) table = dtls_version_table; else { /* Unexpected state; fail closed. */ @@ -1674,8 +2061,10 @@ int ssl_set_version_bound(int method_version, int version, int *bound) valid_tls = version >= SSL3_VERSION && version <= TLS_MAX_VERSION_INTERNAL; valid_dtls = - DTLS_VERSION_LE(version, DTLS_MAX_VERSION_INTERNAL) && - DTLS_VERSION_GE(version, DTLS1_BAD_VER); + /* We support client side pre-standardisation version of DTLS */ + (version == DTLS1_BAD_VER) + || (DTLS_VERSION_LE(version, DTLS_MAX_VERSION_INTERNAL) + && DTLS_VERSION_GE(version, DTLS1_VERSION)); if (!valid_tls && !valid_dtls) return 0; @@ -1711,12 +2100,12 @@ int ssl_set_version_bound(int method_version, int version, int *bound) return 1; } -static void check_for_downgrade(SSL *s, int vers, DOWNGRADE *dgrd) +static void check_for_downgrade(SSL_CONNECTION *s, int vers, DOWNGRADE *dgrd) { if (vers == TLS1_2_VERSION && ssl_version_supported(s, TLS1_3_VERSION, NULL)) { *dgrd = DOWNGRADE_TO_1_2; - } else if (!SSL_IS_DTLS(s) + } else if (!SSL_CONNECTION_IS_DTLS(s) && vers < TLS1_2_VERSION /* * We need to ensure that a server that disables TLSv1.2 @@ -1741,7 +2130,8 @@ static void check_for_downgrade(SSL *s, int vers, DOWNGRADE *dgrd) * * Returns 0 on success or an SSL error reason number on failure. */ -int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) +int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello, + DOWNGRADE *dgrd) { /*- * With version-flexible methods we have an initial state with: @@ -1752,7 +2142,8 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) * So we detect version-flexible methods via the method version, not the * handle version. */ - int server_version = s->method->version; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + int server_version = ssl->method->version; int client_version = hello->legacy_version; const version_info *vent; const version_info *table; @@ -1763,8 +2154,8 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) switch (server_version) { default: - if (!SSL_IS_TLS13(s)) { - if (version_cmp(s, client_version, s->version) < 0) + if (!SSL_CONNECTION_IS_TLS13(s)) { + if (ssl_version_cmp(s, client_version, s->version) < 0) return SSL_R_WRONG_SSL_VERSION; *dgrd = DOWNGRADE_NONE; /* @@ -1795,7 +2186,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) if (!suppversions->present && s->hello_retry_request != SSL_HRR_NONE) return SSL_R_UNSUPPORTED_PROTOCOL; - if (suppversions->present && !SSL_IS_DTLS(s)) { + if (suppversions->present && !SSL_CONNECTION_IS_DTLS(s)) { unsigned int candidate_vers = 0; unsigned int best_vers = 0; const SSL_METHOD *best_method = NULL; @@ -1821,7 +2212,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) return SSL_R_BAD_LEGACY_VERSION; while (PACKET_get_net_2(&versionslist, &candidate_vers)) { - if (version_cmp(s, candidate_vers, best_vers) <= 0) + if (ssl_version_cmp(s, candidate_vers, best_vers) <= 0) continue; if (ssl_version_supported(s, candidate_vers, &best_method)) best_vers = candidate_vers; @@ -1843,7 +2234,10 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) } check_for_downgrade(s, best_vers, dgrd); s->version = best_vers; - s->method = best_method; + ssl->method = best_method; + if (!ssl_set_record_protocol_version(s, best_vers)) + return ERR_R_INTERNAL_ERROR; + return 0; } return SSL_R_UNSUPPORTED_PROTOCOL; @@ -1853,7 +2247,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) * If the supported versions extension isn't present, then the highest * version we can negotiate is TLSv1.2 */ - if (version_cmp(s, client_version, TLS1_3_VERSION) >= 0) + if (ssl_version_cmp(s, client_version, TLS1_3_VERSION) >= 0) client_version = TLS1_2_VERSION; /* @@ -1864,13 +2258,16 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) const SSL_METHOD *method; if (vent->smeth == NULL || - version_cmp(s, client_version, vent->version) < 0) + ssl_version_cmp(s, client_version, vent->version) < 0) continue; method = vent->smeth(); if (ssl_method_error(s, method) == 0) { check_for_downgrade(s, vent->version, dgrd); s->version = vent->version; - s->method = method; + ssl->method = method; + if (!ssl_set_record_protocol_version(s, s->version)) + return ERR_R_INTERNAL_ERROR; + return 0; } disabled = 1; @@ -1889,11 +2286,13 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) * * Returns 1 on success or 0 on error. */ -int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) +int ssl_choose_client_version(SSL_CONNECTION *s, int version, + RAW_EXTENSION *extensions) { const version_info *vent; const version_info *table; int ret, ver_min, ver_max, real_max, origv; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); origv = s->version; s->version = version; @@ -1914,9 +2313,9 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) return 0; } - switch (s->method->version) { + switch (ssl->method->version) { default: - if (s->version != s->method->version) { + if (s->version != ssl->method->version) { s->version = origv; SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_WRONG_SSL_VERSION); return 0; @@ -1928,6 +2327,10 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) * versions they don't want. If not, then easy to fix, just return * ssl_method_error(s, s->method) */ + if (!ssl_set_record_protocol_version(s, s->version)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } return 1; case TLS_ANY_VERSION: table = tls_version_table; @@ -1943,13 +2346,8 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) SSLfatal(s, SSL_AD_PROTOCOL_VERSION, ret); return 0; } - if (SSL_IS_DTLS(s) ? DTLS_VERSION_LT(s->version, ver_min) - : s->version < ver_min) { - s->version = origv; - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNSUPPORTED_PROTOCOL); - return 0; - } else if (SSL_IS_DTLS(s) ? DTLS_VERSION_GT(s->version, ver_max) - : s->version > ver_max) { + if (ssl_version_cmp(s, s->version, ver_min) < 0 + || ssl_version_cmp(s, s->version, ver_max) > 0) { s->version = origv; SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNSUPPORTED_PROTOCOL); return 0; @@ -1969,7 +2367,7 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) SSL_R_INAPPROPRIATE_FALLBACK); return 0; } - } else if (!SSL_IS_DTLS(s) + } else if (!SSL_CONNECTION_IS_DTLS(s) && s->version < TLS1_2_VERSION && real_max > s->version) { if (memcmp(tls11downgrade, @@ -1987,7 +2385,11 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) if (vent->cmeth == NULL || s->version != vent->version) continue; - s->method = vent->cmeth(); + ssl->method = vent->cmeth(); + if (!ssl_set_record_protocol_version(s, s->version)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } return 1; } @@ -2018,17 +2420,17 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) * Returns 0 on success or an SSL error reason number on failure. On failure * min_version and max_version will also be set to 0. */ -int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version, - int *real_max) +int ssl_get_min_max_version(const SSL_CONNECTION *s, int *min_version, + int *max_version, int *real_max) { int version, tmp_real_max; int hole; - const SSL_METHOD *single = NULL; const SSL_METHOD *method; const version_info *table; const version_info *vent; + const SSL *ssl = SSL_CONNECTION_GET_SSL(s); - switch (s->method->version) { + switch (ssl->method->version) { default: /* * If this SSL handle is not from a version flexible method we don't @@ -2064,13 +2466,12 @@ int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version, * the valid protocol entries) and we don't have a selected version yet. * * Whenever "hole == 1", and we hit an enabled method, its version becomes - * the selected version, and the method becomes a candidate "single" - * method. We're no longer in a hole, so "hole" becomes 0. + * the selected version. We're no longer in a hole, so "hole" becomes 0. * - * If "hole == 0" and we hit an enabled method, then "single" is cleared, - * as we support a contiguous range of at least two methods. If we hit - * a disabled method, then hole becomes true again, but nothing else - * changes yet, because all the remaining methods may be disabled too. + * If "hole == 0" and we hit an enabled method, we support a contiguous + * range of at least two methods. If we hit a disabled method, + * then hole becomes true again, but nothing else changes yet, + * because all the remaining methods may be disabled too. * If we again hit an enabled method after the new hole, it becomes * selected, as we start from scratch. */ @@ -2097,12 +2498,11 @@ int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version, if (ssl_method_error(s, method) != 0) { hole = 1; } else if (!hole) { - single = NULL; *min_version = method->version; } else { if (real_max != NULL && tmp_real_max != 0) *real_max = tmp_real_max; - version = (single = method)->version; + version = method->version; *min_version = version; hole = 0; } @@ -2125,7 +2525,7 @@ int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version, * * Returns 0 on success or an SSL error reason number on failure. */ -int ssl_set_client_hello_version(SSL *s) +int ssl_set_client_hello_version(SSL_CONNECTION *s) { int ver_min, ver_max, ret; @@ -2143,9 +2543,22 @@ int ssl_set_client_hello_version(SSL *s) s->version = ver_max; - /* TLS1.3 always uses TLS1.2 in the legacy_version field */ - if (!SSL_IS_DTLS(s) && ver_max > TLS1_2_VERSION) + if (SSL_CONNECTION_IS_DTLS(s)) { + if (ver_max == DTLS1_BAD_VER) { + /* + * Even though this is technically before version negotiation, + * because we have asked for DTLS1_BAD_VER we will never negotiate + * anything else, and this has impacts on the record layer for when + * we read the ServerHello. So we need to tell the record layer + * about this immediately. + */ + if (!ssl_set_record_protocol_version(s, ver_max)) + return 0; + } + } else if (ver_max > TLS1_2_VERSION) { + /* TLS1.3 always uses TLS1.2 in the legacy_version field */ ver_max = TLS1_2_VERSION; + } s->client_version = ver_max; return 0; @@ -2157,7 +2570,7 @@ int ssl_set_client_hello_version(SSL *s) * used. Returns 1 if the group is in the list (and allowed if |checkallow| is * 1) or 0 otherwise. */ -int check_in_list(SSL *s, uint16_t group_id, const uint16_t *groups, +int check_in_list(SSL_CONNECTION *s, uint16_t group_id, const uint16_t *groups, size_t num_groups, int checkallow) { size_t i; @@ -2179,7 +2592,8 @@ int check_in_list(SSL *s, uint16_t group_id, const uint16_t *groups, } /* Replace ClientHello1 in the transcript hash with a synthetic message */ -int create_synthetic_message_hash(SSL *s, const unsigned char *hashval, +int create_synthetic_message_hash(SSL_CONNECTION *s, + const unsigned char *hashval, size_t hashlen, const unsigned char *hrr, size_t hrrlen) { @@ -2237,14 +2651,14 @@ static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b) return X509_NAME_cmp(*a, *b); } -int parse_ca_names(SSL *s, PACKET *pkt) +int parse_ca_names(SSL_CONNECTION *s, PACKET *pkt) { STACK_OF(X509_NAME) *ca_sk = sk_X509_NAME_new(ca_dn_cmp); X509_NAME *xn = NULL; PACKET cadns; if (ca_sk == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } /* get the CA RDNs */ @@ -2274,7 +2688,7 @@ int parse_ca_names(SSL *s, PACKET *pkt) } if (!sk_X509_NAME_push(ca_sk, xn)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } xn = NULL; @@ -2291,23 +2705,25 @@ int parse_ca_names(SSL *s, PACKET *pkt) return 0; } -const STACK_OF(X509_NAME) *get_ca_names(SSL *s) +const STACK_OF(X509_NAME) *get_ca_names(SSL_CONNECTION *s) { - const STACK_OF(X509_NAME) *ca_sk = NULL;; + const STACK_OF(X509_NAME) *ca_sk = NULL; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (s->server) { - ca_sk = SSL_get_client_CA_list(s); + ca_sk = SSL_get_client_CA_list(ssl); if (ca_sk != NULL && sk_X509_NAME_num(ca_sk) == 0) ca_sk = NULL; } if (ca_sk == NULL) - ca_sk = SSL_get0_CA_list(s); + ca_sk = SSL_get0_CA_list(ssl); return ca_sk; } -int construct_ca_names(SSL *s, const STACK_OF(X509_NAME) *ca_sk, WPACKET *pkt) +int construct_ca_names(SSL_CONNECTION *s, const STACK_OF(X509_NAME) *ca_sk, + WPACKET *pkt) { /* Start sub-packet for client CA list */ if (!WPACKET_start_sub_packet_u16(pkt)) { @@ -2343,14 +2759,14 @@ int construct_ca_names(SSL *s, const STACK_OF(X509_NAME) *ca_sk, WPACKET *pkt) } /* Create a buffer containing data to be signed for server key exchange */ -size_t construct_key_exchange_tbs(SSL *s, unsigned char **ptbs, +size_t construct_key_exchange_tbs(SSL_CONNECTION *s, unsigned char **ptbs, const void *param, size_t paramlen) { size_t tbslen = 2 * SSL3_RANDOM_SIZE + paramlen; unsigned char *tbs = OPENSSL_malloc(tbslen); if (tbs == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; } memcpy(tbs, s->s3.client_random, SSL3_RANDOM_SIZE); @@ -2366,7 +2782,7 @@ size_t construct_key_exchange_tbs(SSL *s, unsigned char **ptbs, * Saves the current handshake digest for Post-Handshake Auth, * Done after ClientFinished is processed, done exactly once */ -int tls13_save_handshake_digest_for_pha(SSL *s) +int tls13_save_handshake_digest_for_pha(SSL_CONNECTION *s) { if (s->pha_dgst == NULL) { if (!ssl3_digest_cached_records(s, 1)) @@ -2393,7 +2809,7 @@ int tls13_save_handshake_digest_for_pha(SSL *s) * Restores the Post-Handshake Auth handshake digest * Done just before sending/processing the Cert Request */ -int tls13_restore_handshake_digest_for_pha(SSL *s) +int tls13_restore_handshake_digest_for_pha(SSL_CONNECTION *s) { if (s->pha_dgst == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -2406,3 +2822,76 @@ int tls13_restore_handshake_digest_for_pha(SSL *s) } return 1; } + +#ifndef OPENSSL_NO_COMP_ALG +MSG_PROCESS_RETURN tls13_process_compressed_certificate(SSL_CONNECTION *sc, + PACKET *pkt, + PACKET *tmppkt, + BUF_MEM *buf) +{ + MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR; + int comp_alg; + COMP_METHOD *method = NULL; + COMP_CTX *comp = NULL; + size_t expected_length; + size_t comp_length; + int i; + int found = 0; + + if (buf == NULL) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!PACKET_get_net_2(pkt, (unsigned int*)&comp_alg)) { + SSLfatal(sc, SSL_AD_BAD_CERTIFICATE, ERR_R_INTERNAL_ERROR); + goto err; + } + /* If we have a prefs list, make sure the algorithm is in it */ + if (sc->cert_comp_prefs[0] != TLSEXT_comp_cert_none) { + for (i = 0; sc->cert_comp_prefs[i] != TLSEXT_comp_cert_none; i++) { + if (sc->cert_comp_prefs[i] == comp_alg) { + found = 1; + break; + } + } + if (!found) { + SSLfatal(sc, SSL_AD_BAD_CERTIFICATE, SSL_R_BAD_COMPRESSION_ALGORITHM); + goto err; + } + } + if (!ossl_comp_has_alg(comp_alg)) { + SSLfatal(sc, SSL_AD_BAD_CERTIFICATE, SSL_R_BAD_COMPRESSION_ALGORITHM); + goto err; + } + switch (comp_alg) { + case TLSEXT_comp_cert_zlib: + method = COMP_zlib_oneshot(); + break; + case TLSEXT_comp_cert_brotli: + method = COMP_brotli_oneshot(); + break; + case TLSEXT_comp_cert_zstd: + method = COMP_zstd_oneshot(); + break; + default: + SSLfatal(sc, SSL_AD_BAD_CERTIFICATE, SSL_R_BAD_COMPRESSION_ALGORITHM); + goto err; + } + + if ((comp = COMP_CTX_new(method)) == NULL + || !PACKET_get_net_3_len(pkt, &expected_length) + || !PACKET_get_net_3_len(pkt, &comp_length) + || PACKET_remaining(pkt) != comp_length + || !BUF_MEM_grow(buf, expected_length) + || !PACKET_buf_init(tmppkt, (unsigned char *)buf->data, expected_length) + || COMP_expand_block(comp, (unsigned char *)buf->data, expected_length, + (unsigned char*)PACKET_data(pkt), comp_length) != (int)expected_length) { + SSLfatal(sc, SSL_AD_BAD_CERTIFICATE, SSL_R_BAD_DECOMPRESSION); + goto err; + } + ret = MSG_PROCESS_CONTINUE_PROCESSING; + err: + COMP_CTX_free(comp); + return ret; +} +#endif