diff --git a/deps/openssl/openssl/include/openssl/ssl.h b/deps/openssl/openssl/include/openssl/ssl.h index 2a536b01ca..ecdda54895 100644 --- a/deps/openssl/openssl/include/openssl/ssl.h +++ b/deps/openssl/openssl/include/openssl/ssl.h @@ -639,19 +639,30 @@ void SSL_set_msg_callback(SSL *ssl, # define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) # define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) -typedef enum { - SSL_KEY_CLIENT_EARLY_TRAFFIC, - SSL_KEY_CLIENT_HANDSHAKE_TRAFFIC, - SSL_KEY_CLIENT_APPLICATION_TRAFFIC, - SSL_KEY_SERVER_HANDSHAKE_TRAFFIC, - SSL_KEY_SERVER_APPLICATION_TRAFFIC -} OSSL_KEY_TYPE; - -void SSL_set_key_callback(SSL *ssl, - int (*cb)(SSL *ssl, int name, - const unsigned char *secret, - size_t secretlen, void *arg), - void *arg); +/* + * ssl_encryption_level_t represents a specific QUIC encryption level used to + * transmit handshake messages. + */ +typedef enum ssl_encryption_level_t { + ssl_encryption_initial = 0, + ssl_encryption_early_data, + ssl_encryption_handshake, + ssl_encryption_application +} OSSL_ENCRYPTION_LEVEL; + +/* + * Adaptation of the set_encryption_secrets approach defined in + * https://github.com/openssl/openssl/pull/8797 + */ +void SSL_set_encryption_secrets_callback(SSL *ssl, + int (*cb)(SSL* ssl, + /* OSSL_ENCRYPTION_LEVEL */ + int level, + const uint8_t *read_secret, + const uint8_t *write_secret, + size_t secret_len, + void* arg), + void *arg); # define SSL_get_extms_support(s) \ SSL_ctrl((s),SSL_CTRL_GET_EXTMS_SUPPORT,0,NULL) diff --git a/deps/openssl/openssl/include/openssl/sslerr.h b/deps/openssl/openssl/include/openssl/sslerr.h index 3d6850dea3..fa0606a266 100644 --- a/deps/openssl/openssl/include/openssl/sslerr.h +++ b/deps/openssl/openssl/include/openssl/sslerr.h @@ -95,6 +95,8 @@ int ERR_load_SSL_strings(void); # define SSL_F_PITEM_NEW 624 # define SSL_F_PQUEUE_NEW 625 # define SSL_F_PROCESS_KEY_SHARE_EXT 439 +# define SSL_F_QUIC_CHANGE_CIPHER_STATE 0 +# define SSL_F_QUIC_SET_ENCRYPTION_SECRETS 0 # define SSL_F_READ_STATE_MACHINE 352 # define SSL_F_SET_CLIENT_CIPHERSUITE 540 # define SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET 595 diff --git a/deps/openssl/openssl/ssl/ssl_lib.c b/deps/openssl/openssl/ssl/ssl_lib.c index e4a68af961..e13a306426 100644 --- a/deps/openssl/openssl/ssl/ssl_lib.c +++ b/deps/openssl/openssl/ssl/ssl_lib.c @@ -4333,14 +4333,18 @@ void SSL_set_msg_callback(SSL *ssl, SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); } -void SSL_set_key_callback(SSL *ssl, - int (*cb)(SSL *ssl, int name, - const unsigned char *secret, - size_t secretlen, void *arg), - void *arg) -{ - ssl->key_callback = cb; - ssl->key_callback_arg = arg; +void SSL_set_encryption_secrets_callback(SSL *ssl, + int (*cb)(SSL* ssl, + /* OSSL_ENCRYPTION_LEVEL */ + int level, + const uint8_t *read_secret, + const uint8_t *write_secret, + size_t secret_len, + void *arg), + void *arg) +{ + ssl->encryption_secrets_callback = cb; + ssl->encryption_secrets_callback_arg = arg; } void SSL_CTX_set_not_resumable_session_callback(SSL_CTX *ctx, diff --git a/deps/openssl/openssl/ssl/ssl_locl.h b/deps/openssl/openssl/ssl/ssl_locl.h index 7c5e24c960..2861a205f5 100644 --- a/deps/openssl/openssl/ssl/ssl_locl.h +++ b/deps/openssl/openssl/ssl/ssl_locl.h @@ -1125,9 +1125,12 @@ struct ssl_st { void (*msg_callback) (int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg); void *msg_callback_arg; - int (*key_callback)(SSL *ssl, int name, const unsigned char *secret, - size_t secretlen, void *arg); - void *key_callback_arg; + int (*encryption_secrets_callback)(SSL* ssl, int level, + const uint8_t *read_secret, + const uint8_t *write_secret, + size_t secret_len, + void *arg); + void *encryption_secrets_callback_arg; int hit; /* reusing a previous session */ X509_VERIFY_PARAM *param; /* Per connection DANE state */ @@ -1156,6 +1159,9 @@ struct ssl_st { unsigned char handshake_traffic_hash[EVP_MAX_MD_SIZE]; unsigned char client_app_traffic_secret[EVP_MAX_MD_SIZE]; unsigned char server_app_traffic_secret[EVP_MAX_MD_SIZE]; + unsigned char client_hand_traffic_secret[EVP_MAX_MD_SIZE]; + unsigned char server_hand_traffic_secret[EVP_MAX_MD_SIZE]; + unsigned char client_early_traffic_secret[EVP_MAX_MD_SIZE]; unsigned char exporter_master_secret[EVP_MAX_MD_SIZE]; unsigned char early_exporter_master_secret[EVP_MAX_MD_SIZE]; EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ diff --git a/deps/openssl/openssl/ssl/tls13_enc.c b/deps/openssl/openssl/ssl/tls13_enc.c index 098c46cb1f..a44e6cf2a5 100644 --- a/deps/openssl/openssl/ssl/tls13_enc.c +++ b/deps/openssl/openssl/ssl/tls13_enc.c @@ -427,27 +427,207 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, return 0; } -int tls13_change_cipher_state(SSL *s, int which) +static int quic_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL level) { + uint8_t *c2s_secret = NULL; + uint8_t *s2c_secret = NULL; + size_t len; + const EVP_MD *md; + + if (!(ssl->mode & SSL_MODE_QUIC_HACK)) + return 1; + + /* secrets from the POV of the client */ + switch (level) { + case ssl_encryption_early_data: + c2s_secret = ssl->client_early_traffic_secret; + break; + case ssl_encryption_handshake: + c2s_secret = ssl->client_hand_traffic_secret; + s2c_secret = ssl->server_hand_traffic_secret; + break; + case ssl_encryption_application: + c2s_secret = ssl->client_app_traffic_secret; + s2c_secret = ssl->server_app_traffic_secret; + break; + default: + return 1; + } + + md = ssl_handshake_md(ssl); + if (md == NULL) { + /* May not have selected cipher, yet */ + const SSL_CIPHER *c = NULL; + + if (ssl->session != NULL) + c = SSL_SESSION_get0_cipher(ssl->session); + else if (ssl->psksession != NULL) + c = SSL_SESSION_get0_cipher(ssl->psksession); + + if (c != NULL) + md = SSL_CIPHER_get_handshake_digest(c); + } + + if ((len = EVP_MD_size(md)) <= 0) { + SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_SET_ENCRYPTION_SECRETS, + ERR_R_INTERNAL_ERROR); + return 0; + } + + void *arg = ssl->encryption_secrets_callback_arg; + if (ssl->server) { + if (!ssl->encryption_secrets_callback(ssl, level, c2s_secret, + s2c_secret, len, arg)) { + SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, + SSL_F_QUIC_SET_ENCRYPTION_SECRETS, + ERR_R_INTERNAL_ERROR); + return 0; + } + } else { + if (!ssl->encryption_secrets_callback(ssl, level, s2c_secret, + c2s_secret, len, arg)) { + SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, + SSL_F_QUIC_SET_ENCRYPTION_SECRETS, + ERR_R_INTERNAL_ERROR); + return 0; + } + } + + return 1; +} + #ifdef CHARSET_EBCDIC - static const unsigned char client_early_traffic[] = {0x63, 0x20, 0x65, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; - static const unsigned char client_handshake_traffic[] = {0x63, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; - static const unsigned char client_application_traffic[] = {0x63, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; - static const unsigned char server_handshake_traffic[] = {0x73, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; - static const unsigned char server_application_traffic[] = {0x73, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; - static const unsigned char exporter_master_secret[] = {0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00}; - static const unsigned char resumption_master_secret[] = {0x72, 0x65, 0x73, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00}; - static const unsigned char early_exporter_master_secret[] = {0x65, 0x20, 0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00}; +static const unsigned char client_early_traffic[] = {0x63, 0x20, 0x65, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; +static const unsigned char client_handshake_traffic[] = {0x63, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; +static const unsigned char client_application_traffic[] = {0x63, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; +static const unsigned char server_handshake_traffic[] = {0x73, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; +static const unsigned char server_application_traffic[] = {0x73, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; +static const unsigned char exporter_master_secret[] = {0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00}; +static const unsigned char resumption_master_secret[] = {0x72, 0x65, 0x73, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00}; +static const unsigned char early_exporter_master_secret[] = {0x65, 0x20, 0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00}; #else - static const unsigned char client_early_traffic[] = "c e traffic"; - static const unsigned char client_handshake_traffic[] = "c hs traffic"; - static const unsigned char client_application_traffic[] = "c ap traffic"; - static const unsigned char server_handshake_traffic[] = "s hs traffic"; - static const unsigned char server_application_traffic[] = "s ap traffic"; - static const unsigned char exporter_master_secret[] = "exp master"; - static const unsigned char resumption_master_secret[] = "res master"; - static const unsigned char early_exporter_master_secret[] = "e exp master"; +static const unsigned char client_early_traffic[] = "c e traffic"; +static const unsigned char client_handshake_traffic[] = "c hs traffic"; +static const unsigned char client_application_traffic[] = "c ap traffic"; +static const unsigned char server_handshake_traffic[] = "s hs traffic"; +static const unsigned char server_application_traffic[] = "s ap traffic"; +static const unsigned char exporter_master_secret[] = "exp master"; +static const unsigned char resumption_master_secret[] = "res master"; +static const unsigned char early_exporter_master_secret[] = "e exp master"; #endif + +static int quic_change_cipher_state(SSL *s, int which) +{ + unsigned char hash[EVP_MAX_MD_SIZE]; + size_t hashlen = 0; + int hashleni; + int ret = 0; + const EVP_MD *md = NULL; + OSSL_ENCRYPTION_LEVEL level = ssl_encryption_initial; + int is_handshake = ((which & SSL3_CC_HANDSHAKE) == SSL3_CC_HANDSHAKE); + int is_client_read = ((which & SSL3_CHANGE_CIPHER_CLIENT_READ) == SSL3_CHANGE_CIPHER_CLIENT_READ); + int is_server_write = ((which & SSL3_CHANGE_CIPHER_SERVER_WRITE) == SSL3_CHANGE_CIPHER_SERVER_WRITE); + int is_early = (which & SSL3_CC_EARLY); + + md = ssl_handshake_md(s); + if (!ssl3_digest_cached_records(s, 1) + || !ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) { + /* SSLfatal() already called */; + goto err; + } + + /* Ensure cast to size_t is safe */ + hashleni = EVP_MD_size(md); + if (!ossl_assert(hashleni >= 0)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_CHANGE_CIPHER_STATE, + ERR_R_EVP_LIB); + goto err; + } + hashlen = (size_t)hashleni; + + if (is_client_read || is_server_write) { + if (is_handshake) { + level = ssl_encryption_handshake; + + if (!tls13_hkdf_expand(s, md, s->handshake_secret, + client_handshake_traffic, + sizeof(client_handshake_traffic)-1, + hash, hashlen, + s->client_hand_traffic_secret, hashlen, 1) + || !ssl_log_secret(s, CLIENT_HANDSHAKE_LABEL, + s->client_hand_traffic_secret, hashlen) + || !tls13_derive_finishedkey(s, md, + s->client_hand_traffic_secret, + s->client_finished_secret, hashlen) + || !tls13_hkdf_expand(s, md, s->handshake_secret, + server_handshake_traffic, + sizeof(server_handshake_traffic)-1, hash, + hashlen, + s->server_hand_traffic_secret, hashlen, 1) + || !ssl_log_secret(s, SERVER_HANDSHAKE_LABEL, + s->server_hand_traffic_secret, hashlen) + || !tls13_derive_finishedkey(s, md, + s->server_hand_traffic_secret, + s->server_finished_secret, + hashlen)) { + /* SSLfatal() already called */ + goto err; + } + } else { + level = ssl_encryption_application; + + if (!tls13_hkdf_expand(s, md, s->master_secret, + client_application_traffic, + sizeof(client_application_traffic)-1, + hash, hashlen, + s->client_app_traffic_secret, hashlen, 1) + || !ssl_log_secret(s, CLIENT_APPLICATION_LABEL, + s->client_app_traffic_secret, hashlen) + || !tls13_hkdf_expand(s, md, s->master_secret, + server_application_traffic, + sizeof(server_application_traffic)-1, + hash, hashlen, + s->server_app_traffic_secret, hashlen, 1) + || !ssl_log_secret(s, SERVER_APPLICATION_LABEL, + s->server_app_traffic_secret, hashlen) + || !tls13_hkdf_expand(s, md, s->master_secret, + resumption_master_secret, + sizeof(resumption_master_secret)-1, + hash, hashlen, + s->resumption_master_secret, + hashlen, 1)) { + /* SSLfatal() already called */ + goto err; + } + } + if (!quic_set_encryption_secrets(s, level)) { + /* SSLfatal() already called */ + goto err; + } + } else { + if (is_early) { + level = ssl_encryption_early_data; + + if (!tls13_hkdf_expand(s, md, s->early_secret, client_early_traffic, + sizeof(client_early_traffic)-1, hash, + hashlen, + s->client_early_traffic_secret, hashlen, 1) + || !ssl_log_secret(s, CLIENT_EARLY_LABEL, + s->client_early_traffic_secret, hashlen) + || !quic_set_encryption_secrets(s, level)) { + /* SSLfatal() already called */ + goto err; + } + } + } + + ret = 1; + err: + return ret; +} + +int tls13_change_cipher_state(SSL *s, int which) +{ unsigned char *iv; unsigned char secret[EVP_MAX_MD_SIZE]; unsigned char hashval[EVP_MAX_MD_SIZE]; @@ -463,6 +643,11 @@ int tls13_change_cipher_state(SSL *s, int which) const EVP_MD *md = NULL; const EVP_CIPHER *cipher = NULL; + // If QUIC, defer to quic_change_cipher_state + if (s->mode & SSL_MODE_QUIC_HACK) { + return quic_change_cipher_state(s, which); + } + if (which & SSL3_CC_READ) { if (s->enc_read_ctx != NULL) { EVP_CIPHER_CTX_reset(s->enc_read_ctx); @@ -671,56 +856,6 @@ int tls13_change_cipher_state(SSL *s, int which) goto err; } - if (s->key_callback) { - int type; - if (label == client_early_traffic) { - type = SSL_KEY_CLIENT_EARLY_TRAFFIC; - } else if (label == client_handshake_traffic) { - type = SSL_KEY_CLIENT_HANDSHAKE_TRAFFIC; - } else if (label == client_application_traffic) { - type = SSL_KEY_CLIENT_APPLICATION_TRAFFIC; - } else if (label == server_handshake_traffic) { - type = SSL_KEY_SERVER_HANDSHAKE_TRAFFIC; - } else if (label == server_application_traffic) { - type = SSL_KEY_SERVER_APPLICATION_TRAFFIC; - } else { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); - goto err; - } - if (!s->key_callback(s, type, secret, hashlen, s->key_callback_arg)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - if (s->server) { - switch (type) { - case SSL_KEY_CLIENT_HANDSHAKE_TRAFFIC: - case SSL_KEY_CLIENT_APPLICATION_TRAFFIC: - if (s->rlayer.rbuf.left) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); - goto err; - } - break; - } - } else { - switch (type) { - case SSL_KEY_SERVER_HANDSHAKE_TRAFFIC: - case SSL_KEY_SERVER_APPLICATION_TRAFFIC: - if (s->rlayer.rbuf.left) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); - goto err; - } - break; - } - } - } - if (label == server_application_traffic) { memcpy(s->server_app_traffic_secret, secret, hashlen); /* Now we create the exporter master secret */ diff --git a/deps/openssl/openssl/util/libssl.num b/deps/openssl/openssl/util/libssl.num index a07b2f5bbf..2b1f7f8a9a 100644 --- a/deps/openssl/openssl/util/libssl.num +++ b/deps/openssl/openssl/util/libssl.num @@ -498,4 +498,4 @@ SSL_CTX_get_recv_max_early_data 498 1_1_1 EXIST::FUNCTION: SSL_CTX_set_recv_max_early_data 499 1_1_1 EXIST::FUNCTION: SSL_CTX_set_post_handshake_auth 500 1_1_1 EXIST::FUNCTION: SSL_get_signature_type_nid 501 1_1_1a EXIST::FUNCTION: -SSL_set_key_callback 502 3_0_0 EXIST::FUNCTION: +SSL_set_encryption_secrets_callback 503 3_0_0 EXIST::FUNCTION: