diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 096dbdca..016c83c2 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -4136,12 +4136,10 @@ struct ssl_session_st { uint8_t *tlsext_tick; // Session ticket size_t tlsext_ticklen; // Session ticket length - size_t tlsext_signed_cert_timestamp_list_length; - uint8_t *tlsext_signed_cert_timestamp_list; // Server's list. + CRYPTO_BUFFER *signed_cert_timestamp_list; // The OCSP response that came with the session. - size_t ocsp_response_length; - uint8_t *ocsp_response; + CRYPTO_BUFFER *ocsp_response; // peer_sha256 contains the SHA-256 hash of the peer's certificate if // |peer_sha256_valid| is true. diff --git a/ssl/handshake_client.cc b/ssl/handshake_client.cc index dd09797c..e3c46418 100644 --- a/ssl/handshake_client.cc +++ b/ssl/handshake_client.cc @@ -1162,9 +1162,10 @@ static int ssl3_get_cert_status(SSL_HANDSHAKE *hs) { return -1; } - if (!CBS_stow(&ocsp_response, &hs->new_session->ocsp_response, - &hs->new_session->ocsp_response_length)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + CRYPTO_BUFFER_free(hs->new_session->ocsp_response); + hs->new_session->ocsp_response = + CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool); + if (hs->new_session->ocsp_response == nullptr) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return -1; } diff --git a/ssl/ssl_asn1.cc b/ssl/ssl_asn1.cc index 0cf90d18..b87c7954 100644 --- a/ssl/ssl_asn1.cc +++ b/ssl/ssl_asn1.cc @@ -311,20 +311,22 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, uint8_t **out_data, } } - if (in->tlsext_signed_cert_timestamp_list_length > 0) { + if (in->signed_cert_timestamp_list != nullptr) { if (!CBB_add_asn1(&session, &child, kSignedCertTimestampListTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || - !CBB_add_bytes(&child2, in->tlsext_signed_cert_timestamp_list, - in->tlsext_signed_cert_timestamp_list_length)) { + !CBB_add_bytes(&child2, + CRYPTO_BUFFER_data(in->signed_cert_timestamp_list), + CRYPTO_BUFFER_len(in->signed_cert_timestamp_list))) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } - if (in->ocsp_response_length > 0) { + if (in->ocsp_response != nullptr) { if (!CBB_add_asn1(&session, &child, kOCSPResponseTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || - !CBB_add_bytes(&child2, in->ocsp_response, in->ocsp_response_length)) { + !CBB_add_bytes(&child2, CRYPTO_BUFFER_data(in->ocsp_response), + CRYPTO_BUFFER_len(in->ocsp_response))) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -470,6 +472,29 @@ static int SSL_SESSION_parse_octet_string(CBS *cbs, uint8_t **out_ptr, return 1; } +static int SSL_SESSION_parse_crypto_buffer(CBS *cbs, CRYPTO_BUFFER **out, + unsigned tag, + CRYPTO_BUFFER_POOL *pool) { + if (!CBS_peek_asn1_tag(cbs, tag)) { + return 1; + } + + CBS child, value; + if (!CBS_get_asn1(cbs, &child, tag) || + !CBS_get_asn1(&child, &value, CBS_ASN1_OCTETSTRING) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + CRYPTO_BUFFER_free(*out); + *out = CRYPTO_BUFFER_new_from_CBS(&value, pool); + if (*out == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + /* SSL_SESSION_parse_bounded_octet_string parses an optional ASN.1 OCTET STRING * explicitly tagged with |tag| of size at most |max_out|. */ static int SSL_SESSION_parse_bounded_octet_string( @@ -635,13 +660,11 @@ UniquePtr SSL_SESSION_parse(CBS *cbs, &session, ret->original_handshake_hash, &ret->original_handshake_hash_len, sizeof(ret->original_handshake_hash), kOriginalHandshakeHashTag) || - !SSL_SESSION_parse_octet_string( - &session, &ret->tlsext_signed_cert_timestamp_list, - &ret->tlsext_signed_cert_timestamp_list_length, - kSignedCertTimestampListTag) || - !SSL_SESSION_parse_octet_string( - &session, &ret->ocsp_response, &ret->ocsp_response_length, - kOCSPResponseTag)) { + !SSL_SESSION_parse_crypto_buffer(&session, + &ret->signed_cert_timestamp_list, + kSignedCertTimestampListTag, pool) || + !SSL_SESSION_parse_crypto_buffer(&session, &ret->ocsp_response, + kOCSPResponseTag, pool)) { return nullptr; } diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc index 026e218b..32ec272e 100644 --- a/ssl/ssl_lib.cc +++ b/ssl/ssl_lib.cc @@ -1811,28 +1811,27 @@ void SSL_enable_ocsp_stapling(SSL *ssl) { void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out, size_t *out_len) { SSL_SESSION *session = SSL_get_session(ssl); - - *out_len = 0; - *out = NULL; - if (ssl->server || !session || !session->tlsext_signed_cert_timestamp_list) { + if (ssl->server || !session || !session->signed_cert_timestamp_list) { + *out_len = 0; + *out = NULL; return; } - *out = session->tlsext_signed_cert_timestamp_list; - *out_len = session->tlsext_signed_cert_timestamp_list_length; + *out = CRYPTO_BUFFER_data(session->signed_cert_timestamp_list); + *out_len = CRYPTO_BUFFER_len(session->signed_cert_timestamp_list); } void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out, size_t *out_len) { SSL_SESSION *session = SSL_get_session(ssl); - - *out_len = 0; - *out = NULL; if (ssl->server || !session || !session->ocsp_response) { + *out_len = 0; + *out = NULL; return; } - *out = session->ocsp_response; - *out_len = session->ocsp_response_length; + + *out = CRYPTO_BUFFER_data(session->ocsp_response); + *out_len = CRYPTO_BUFFER_len(session->ocsp_response); } int SSL_set_tlsext_host_name(SSL *ssl, const char *name) { diff --git a/ssl/ssl_session.cc b/ssl/ssl_session.cc index dad0656f..6bacc806 100644 --- a/ssl/ssl_session.cc +++ b/ssl/ssl_session.cc @@ -227,24 +227,15 @@ UniquePtr SSL_SESSION_dup(SSL_SESSION *session, int dup_flags) { new_session->verify_result = session->verify_result; - new_session->ocsp_response_length = session->ocsp_response_length; if (session->ocsp_response != NULL) { - new_session->ocsp_response = (uint8_t *)BUF_memdup( - session->ocsp_response, session->ocsp_response_length); - if (new_session->ocsp_response == NULL) { - return nullptr; - } + new_session->ocsp_response = session->ocsp_response; + CRYPTO_BUFFER_up_ref(new_session->ocsp_response); } - new_session->tlsext_signed_cert_timestamp_list_length = - session->tlsext_signed_cert_timestamp_list_length; - if (session->tlsext_signed_cert_timestamp_list != NULL) { - new_session->tlsext_signed_cert_timestamp_list = (uint8_t *)BUF_memdup( - session->tlsext_signed_cert_timestamp_list, - session->tlsext_signed_cert_timestamp_list_length); - if (new_session->tlsext_signed_cert_timestamp_list == NULL) { - return nullptr; - } + if (session->signed_cert_timestamp_list != NULL) { + new_session->signed_cert_timestamp_list = + session->signed_cert_timestamp_list; + CRYPTO_BUFFER_up_ref(new_session->signed_cert_timestamp_list); } OPENSSL_memcpy(new_session->peer_sha256, session->peer_sha256, @@ -898,8 +889,8 @@ void SSL_SESSION_free(SSL_SESSION *session) { session->x509_method->session_clear(session); OPENSSL_free(session->tlsext_hostname); OPENSSL_free(session->tlsext_tick); - OPENSSL_free(session->tlsext_signed_cert_timestamp_list); - OPENSSL_free(session->ocsp_response); + CRYPTO_BUFFER_free(session->signed_cert_timestamp_list); + CRYPTO_BUFFER_free(session->ocsp_response); OPENSSL_free(session->psk_identity); OPENSSL_free(session->early_alpn); OPENSSL_cleanse(session, sizeof(*session)); diff --git a/ssl/t1_lib.cc b/ssl/t1_lib.cc index bbe64019..e50710a5 100644 --- a/ssl/t1_lib.cc +++ b/ssl/t1_lib.cc @@ -1327,11 +1327,14 @@ static int ext_sct_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, * requirement, so tolerate this. * * TODO(davidben): Enforce this anyway. */ - if (!ssl->s3->session_reused && - !CBS_stow(contents, &hs->new_session->tlsext_signed_cert_timestamp_list, - &hs->new_session->tlsext_signed_cert_timestamp_list_length)) { - *out_alert = SSL_AD_INTERNAL_ERROR; - return 0; + if (!ssl->s3->session_reused) { + CRYPTO_BUFFER_free(hs->new_session->signed_cert_timestamp_list); + hs->new_session->signed_cert_timestamp_list = + CRYPTO_BUFFER_new_from_CBS(contents, ssl->ctx->pool); + if (hs->new_session->signed_cert_timestamp_list == nullptr) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return 0; + } } return 1; diff --git a/ssl/tls13_both.cc b/ssl/tls13_both.cc index 39e0cb32..6e7260e0 100644 --- a/ssl/tls13_both.cc +++ b/ssl/tls13_both.cc @@ -284,11 +284,14 @@ int tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, return 0; } - if (sk_CRYPTO_BUFFER_num(certs.get()) == 1 && - !CBS_stow(&ocsp_response, &hs->new_session->ocsp_response, - &hs->new_session->ocsp_response_length)) { - ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - return 0; + if (sk_CRYPTO_BUFFER_num(certs.get()) == 1) { + CRYPTO_BUFFER_free(hs->new_session->ocsp_response); + hs->new_session->ocsp_response = + CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool); + if (hs->new_session->ocsp_response == nullptr) { + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return 0; + } } } @@ -305,12 +308,14 @@ int tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, return 0; } - if (sk_CRYPTO_BUFFER_num(certs.get()) == 1 && - !CBS_stow( - &sct, &hs->new_session->tlsext_signed_cert_timestamp_list, - &hs->new_session->tlsext_signed_cert_timestamp_list_length)) { - ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - return 0; + if (sk_CRYPTO_BUFFER_num(certs.get()) == 1) { + CRYPTO_BUFFER_free(hs->new_session->signed_cert_timestamp_list); + hs->new_session->signed_cert_timestamp_list = + CRYPTO_BUFFER_new_from_CBS(&sct, ssl->ctx->pool); + if (hs->new_session->signed_cert_timestamp_list == nullptr) { + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return 0; + } } } }