Give SSL_SESSION a destructor.
Previously we'd partially attempted the ssl_st / bssl::SSLConnection
subclassing split, but that gets messy when we actually try to add a
destructor, because CRYPTO_EX_DATA's cleanup function needs an ssl_st*,
not a bssl::SSLConnection*. Downcasting is technically undefined at this
point and will likely offend some CFI-like check.
Moreover, it appears that even with today's subclassing split,
New<SSL>() emits symbols like:
W ssl_st*& std::forward<ssl_st*&>(std::remove_reference<ssl_st*&>::type&)
The compiler does not bother emitting them in optimized builds, but it
does suggest we can't really avoid claiming the ssl_st type name at the
symbol level, short of doing reinterpret_casts at all API boundaries.
And, of course, we've already long claimed it at the #include level.
So I've just left this defining directly on ssl_session_st. The cost is
we need to write some silly "bssl::" prefixes in the headers, but so it
goes. In the likely event we change our minds again, we can always
revise this.
Change-Id: Ieb429e8eaabe7c2961ef7f8d9234fb71f19a5e2a
Reviewed-on: https://boringssl-review.googlesource.com/29587
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/handshake.cc b/ssl/handshake.cc
index cfba839..c1837a8 100644
--- a/ssl/handshake.cc
+++ b/ssl/handshake.cc
@@ -281,16 +281,6 @@
return 1;
}
-static void set_crypto_buffer(CRYPTO_BUFFER **dest, CRYPTO_BUFFER *src) {
- // TODO(davidben): Remove this helper once |SSL_SESSION| can use |UniquePtr|
- // and |UniquePtr| has up_ref helpers.
- CRYPTO_BUFFER_free(*dest);
- *dest = src;
- if (src != nullptr) {
- CRYPTO_BUFFER_up_ref(src);
- }
-}
-
enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
const SSL_SESSION *prev_session = ssl->s3->established_session.get();
@@ -300,18 +290,19 @@
// so this check is sufficient to ensure the reported peer certificate never
// changes on renegotiation.
assert(!ssl->server);
- if (sk_CRYPTO_BUFFER_num(prev_session->certs) !=
- sk_CRYPTO_BUFFER_num(hs->new_session->certs)) {
+ if (sk_CRYPTO_BUFFER_num(prev_session->certs.get()) !=
+ sk_CRYPTO_BUFFER_num(hs->new_session->certs.get())) {
OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_CERT_CHANGED);
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_verify_invalid;
}
- for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(hs->new_session->certs); i++) {
+ for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(hs->new_session->certs.get());
+ i++) {
const CRYPTO_BUFFER *old_cert =
- sk_CRYPTO_BUFFER_value(prev_session->certs, i);
+ sk_CRYPTO_BUFFER_value(prev_session->certs.get(), i);
const CRYPTO_BUFFER *new_cert =
- sk_CRYPTO_BUFFER_value(hs->new_session->certs, i);
+ sk_CRYPTO_BUFFER_value(hs->new_session->certs.get(), i);
if (CRYPTO_BUFFER_len(old_cert) != CRYPTO_BUFFER_len(new_cert) ||
OPENSSL_memcmp(CRYPTO_BUFFER_data(old_cert),
CRYPTO_BUFFER_data(new_cert),
@@ -326,10 +317,9 @@
// certificate. Since we only authenticated the previous one, copy other
// authentication from the established session and ignore what was newly
// received.
- set_crypto_buffer(&hs->new_session->ocsp_response,
- prev_session->ocsp_response);
- set_crypto_buffer(&hs->new_session->signed_cert_timestamp_list,
- prev_session->signed_cert_timestamp_list);
+ hs->new_session->ocsp_response = UpRef(prev_session->ocsp_response);
+ hs->new_session->signed_cert_timestamp_list =
+ UpRef(prev_session->signed_cert_timestamp_list);
hs->new_session->verify_result = prev_session->verify_result;
return ssl_verify_ok;
}
diff --git a/ssl/handshake_client.cc b/ssl/handshake_client.cc
index c649eba..eba21f3 100644
--- a/ssl/handshake_client.cc
+++ b/ssl/handshake_client.cc
@@ -402,7 +402,7 @@
if (ssl->session->is_server ||
!ssl_supports_version(hs, ssl->session->ssl_version) ||
(ssl->session->session_id_length == 0 &&
- ssl->session->tlsext_ticklen == 0) ||
+ ssl->session->ticket.empty()) ||
ssl->session->not_resumable ||
!ssl_session_is_time_valid(ssl, ssl->session)) {
ssl_set_session(ssl, NULL);
@@ -772,16 +772,13 @@
CBS body = msg.body;
uint8_t alert = SSL_AD_DECODE_ERROR;
- UniquePtr<STACK_OF(CRYPTO_BUFFER)> chain;
- if (!ssl_parse_cert_chain(&alert, &chain, &hs->peer_pubkey, NULL, &body,
- ssl->ctx->pool)) {
+ if (!ssl_parse_cert_chain(&alert, &hs->new_session->certs, &hs->peer_pubkey,
+ NULL, &body, ssl->ctx->pool)) {
ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
- sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free);
- hs->new_session->certs = chain.release();
- if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0 ||
+ if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0 ||
CBS_len(&body) != 0 ||
!ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
@@ -791,7 +788,7 @@
if (!ssl_check_leaf_certificate(
hs, hs->peer_pubkey.get(),
- sk_CRYPTO_BUFFER_value(hs->new_session->certs, 0))) {
+ sk_CRYPTO_BUFFER_value(hs->new_session->certs.get(), 0))) {
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
@@ -838,9 +835,8 @@
return ssl_hs_error;
}
- CRYPTO_BUFFER_free(hs->new_session->ocsp_response);
- hs->new_session->ocsp_response =
- CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool);
+ hs->new_session->ocsp_response.reset(
+ CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool));
if (hs->new_session->ocsp_response == nullptr) {
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
@@ -1225,9 +1221,8 @@
}
assert(psk_len <= PSK_MAX_PSK_LEN);
- OPENSSL_free(hs->new_session->psk_identity);
- hs->new_session->psk_identity = BUF_strdup(identity);
- if (hs->new_session->psk_identity == NULL) {
+ hs->new_session->psk_identity.reset(BUF_strdup(identity));
+ if (hs->new_session->psk_identity == nullptr) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return ssl_hs_error;
}
@@ -1526,8 +1521,8 @@
}
CBS new_session_ticket = msg.body, ticket;
- uint32_t tlsext_tick_lifetime_hint;
- if (!CBS_get_u32(&new_session_ticket, &tlsext_tick_lifetime_hint) ||
+ uint32_t ticket_lifetime_hint;
+ if (!CBS_get_u32(&new_session_ticket, &ticket_lifetime_hint) ||
!CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) ||
CBS_len(&new_session_ticket) != 0) {
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
@@ -1561,14 +1556,13 @@
session = renewed_session.get();
}
- // |tlsext_tick_lifetime_hint| is measured from when the ticket was issued.
+ // |ticket_lifetime_hint| is measured from when the ticket was issued.
ssl_session_rebase_time(ssl, session);
- if (!CBS_stow(&ticket, &session->tlsext_tick, &session->tlsext_ticklen)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ if (!session->ticket.CopyFrom(ticket)) {
return ssl_hs_error;
}
- session->tlsext_tick_lifetime_hint = tlsext_tick_lifetime_hint;
+ session->ticket_lifetime_hint = ticket_lifetime_hint;
// Generate a session ID for this session based on the session ticket. We use
// the session ID mechanism for detecting ticket resumption. This also fits in
diff --git a/ssl/handshake_server.cc b/ssl/handshake_server.cc
index 65a6299..edbe617 100644
--- a/ssl/handshake_server.cc
+++ b/ssl/handshake_server.cc
@@ -965,17 +965,14 @@
CBS certificate_msg = msg.body;
uint8_t alert = SSL_AD_DECODE_ERROR;
- UniquePtr<STACK_OF(CRYPTO_BUFFER)> chain;
- if (!ssl_parse_cert_chain(&alert, &chain, &hs->peer_pubkey,
+ if (!ssl_parse_cert_chain(&alert, &hs->new_session->certs, &hs->peer_pubkey,
hs->config->retain_only_sha256_of_client_certs
? hs->new_session->peer_sha256
- : NULL,
+ : nullptr,
&certificate_msg, ssl->ctx->pool)) {
ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
- sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free);
- hs->new_session->certs = chain.release();
if (CBS_len(&certificate_msg) != 0 ||
!ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) {
@@ -984,7 +981,7 @@
return ssl_hs_error;
}
- if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) {
+ if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0) {
// No client certificate so the handshake buffer may be discarded.
hs->transcript.FreeBuffer();
@@ -1009,7 +1006,7 @@
}
static enum ssl_hs_wait_t do_verify_client_certificate(SSL_HANDSHAKE *hs) {
- if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) > 0) {
+ if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) > 0) {
switch (ssl_verify_peer_cert(hs)) {
case ssl_verify_ok:
break;
@@ -1058,12 +1055,13 @@
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
-
- if (!CBS_strdup(&psk_identity, &hs->new_session->psk_identity)) {
+ char *raw = nullptr;
+ if (!CBS_strdup(&psk_identity, &raw)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
+ hs->new_session->psk_identity.reset(raw);
}
// Depending on the key exchange method, compute |premaster_secret|.
@@ -1178,7 +1176,7 @@
// Look up the key for the identity.
uint8_t psk[PSK_MAX_PSK_LEN];
unsigned psk_len = hs->config->psk_server_callback(
- ssl, hs->new_session->psk_identity, psk, sizeof(psk));
+ ssl, hs->new_session->psk_identity.get(), psk, sizeof(psk));
if (psk_len > PSK_MAX_PSK_LEN) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
@@ -1468,8 +1466,7 @@
// If we aren't retaining peer certificates then we can discard it now.
if (hs->new_session != NULL &&
hs->config->retain_only_sha256_of_client_certs) {
- sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free);
- hs->new_session->certs = NULL;
+ hs->new_session->certs.reset();
ssl->ctx->x509_method->session_clear(hs->new_session.get());
}
diff --git a/ssl/internal.h b/ssl/internal.h
index d66b418..52320f2 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -3195,113 +3195,112 @@
struct ssl_ctx_st : public bssl::SSLContext {};
struct ssl_st : public bssl::SSLConnection {};
-// TODO(davidben): This type was recently made opaque. After 2018-06-13, move it
-// into a namespace and make it C++.
struct ssl_session_st {
- CRYPTO_refcount_t references;
- uint16_t ssl_version; // what ssl version session info is being kept in here?
+ explicit ssl_session_st(const bssl::SSL_X509_METHOD *method);
+ ssl_session_st(const ssl_session_st &) = delete;
+ ssl_session_st &operator=(const ssl_session_st &) = delete;
+
+ CRYPTO_refcount_t references = 1;
+ uint16_t ssl_version = 0; // what ssl version session info is being kept in here?
// group_id is the ID of the ECDH group used to establish this session or zero
// if not applicable or unknown.
- uint16_t group_id;
+ uint16_t group_id = 0;
// peer_signature_algorithm is the signature algorithm used to authenticate
// the peer, or zero if not applicable or unknown.
- uint16_t peer_signature_algorithm;
+ uint16_t peer_signature_algorithm = 0;
// master_key, in TLS 1.2 and below, is the master secret associated with the
// session. In TLS 1.3 and up, it is the resumption secret.
- int master_key_length;
- uint8_t master_key[SSL_MAX_MASTER_KEY_LENGTH];
+ int master_key_length = 0;
+ uint8_t master_key[SSL_MAX_MASTER_KEY_LENGTH] = {0};
// session_id - valid?
- unsigned int session_id_length;
- uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
+ unsigned session_id_length = 0;
+ uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH] = {0};
// this is used to determine whether the session is being reused in
// the appropriate context. It is up to the application to set this,
// via SSL_new
- uint8_t sid_ctx_length;
- uint8_t sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+ uint8_t sid_ctx_length = 0;
+ uint8_t sid_ctx[SSL_MAX_SID_CTX_LENGTH] = {0};
- char *psk_identity;
+ bssl::UniquePtr<char> psk_identity;
// certs contains the certificate chain from the peer, starting with the leaf
// certificate.
- STACK_OF(CRYPTO_BUFFER) *certs;
+ bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> certs;
- const bssl::SSL_X509_METHOD *x509_method;
+ const bssl::SSL_X509_METHOD *x509_method = nullptr;
// x509_peer is the peer's certificate.
- X509 *x509_peer;
+ X509 *x509_peer = nullptr;
// x509_chain is the certificate chain sent by the peer. NOTE: for historical
// reasons, when a client (so the peer is a server), the chain includes
// |peer|, but when a server it does not.
- STACK_OF(X509) *x509_chain;
+ STACK_OF(X509) *x509_chain = nullptr;
// x509_chain_without_leaf is a lazily constructed copy of |x509_chain| that
// omits the leaf certificate. This exists because OpenSSL, historically,
// didn't include the leaf certificate in the chain for a server, but did for
// a client. The |x509_chain| always includes it and, if an API call requires
// a chain without, it is stored here.
- STACK_OF(X509) *x509_chain_without_leaf;
+ STACK_OF(X509) *x509_chain_without_leaf = nullptr;
// verify_result is the result of certificate verification in the case of
// non-fatal certificate errors.
- long verify_result;
+ long verify_result = X509_V_ERR_INVALID_CALL;
// timeout is the lifetime of the session in seconds, measured from |time|.
// This is renewable up to |auth_timeout|.
- uint32_t timeout;
+ uint32_t timeout = SSL_DEFAULT_SESSION_TIMEOUT;
// auth_timeout is the non-renewable lifetime of the session in seconds,
// measured from |time|.
- uint32_t auth_timeout;
+ uint32_t auth_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
// time is the time the session was issued, measured in seconds from the UNIX
// epoch.
- uint64_t time;
+ uint64_t time = 0;
- const SSL_CIPHER *cipher;
+ const SSL_CIPHER *cipher = nullptr;
CRYPTO_EX_DATA ex_data; // application specific data
// These are used to make removal of session-ids more efficient and to
// implement a maximum cache size.
- SSL_SESSION *prev, *next;
+ SSL_SESSION *prev = nullptr, *next = nullptr;
- // RFC4507 info
- uint8_t *tlsext_tick; // Session ticket
- size_t tlsext_ticklen; // Session ticket length
+ bssl::Array<uint8_t> ticket;
- CRYPTO_BUFFER *signed_cert_timestamp_list;
+ bssl::UniquePtr<CRYPTO_BUFFER> signed_cert_timestamp_list;
// The OCSP response that came with the session.
- CRYPTO_BUFFER *ocsp_response;
+ bssl::UniquePtr<CRYPTO_BUFFER> ocsp_response;
// peer_sha256 contains the SHA-256 hash of the peer's certificate if
// |peer_sha256_valid| is true.
- uint8_t peer_sha256[SHA256_DIGEST_LENGTH];
+ uint8_t peer_sha256[SHA256_DIGEST_LENGTH] = {0};
// original_handshake_hash contains the handshake hash (either SHA-1+MD5 or
// SHA-2, depending on TLS version) for the original, full handshake that
// created a session. This is used by Channel IDs during resumption.
- uint8_t original_handshake_hash[EVP_MAX_MD_SIZE];
- uint8_t original_handshake_hash_len;
+ uint8_t original_handshake_hash[EVP_MAX_MD_SIZE] = {0};
+ uint8_t original_handshake_hash_len = 0;
- uint32_t tlsext_tick_lifetime_hint; // Session lifetime hint in seconds
+ uint32_t ticket_lifetime_hint = 0; // Session lifetime hint in seconds
- uint32_t ticket_age_add;
+ uint32_t ticket_age_add = 0;
// ticket_max_early_data is the maximum amount of data allowed to be sent as
// early data. If zero, 0-RTT is disallowed.
- uint32_t ticket_max_early_data;
+ uint32_t ticket_max_early_data = 0;
// early_alpn is the ALPN protocol from the initial handshake. This is only
// stored for TLS 1.3 and above in order to enforce ALPN matching for 0-RTT
// resumptions.
- uint8_t *early_alpn;
- size_t early_alpn_len;
+ bssl::Array<uint8_t> early_alpn;
// extended_master_secret is whether the master secret in this session was
// generated using EMS and thus isn't vulnerable to the Triple Handshake
@@ -3319,6 +3318,10 @@
// is_server is whether this session was created by a server.
bool is_server:1;
+
+ private:
+ ~ssl_session_st();
+ friend void SSL_SESSION_free(SSL_SESSION *);
};
diff --git a/ssl/ssl_asn1.cc b/ssl/ssl_asn1.cc
index 54e87bf..5dfacb2 100644
--- a/ssl/ssl_asn1.cc
+++ b/ssl/ssl_asn1.cc
@@ -224,8 +224,8 @@
// The peer certificate is only serialized if the SHA-256 isn't
// serialized instead.
- if (sk_CRYPTO_BUFFER_num(in->certs) > 0 && !in->peer_sha256_valid) {
- const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs, 0);
+ if (sk_CRYPTO_BUFFER_num(in->certs.get()) > 0 && !in->peer_sha256_valid) {
+ const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs.get(), 0);
if (!CBB_add_asn1(&session, &child, kPeerTag) ||
!CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer),
CRYPTO_BUFFER_len(buffer))) {
@@ -252,25 +252,26 @@
if (in->psk_identity) {
if (!CBB_add_asn1(&session, &child, kPSKIdentityTag) ||
- !CBB_add_asn1_octet_string(&child, (const uint8_t *)in->psk_identity,
- strlen(in->psk_identity))) {
+ !CBB_add_asn1_octet_string(&child,
+ (const uint8_t *)in->psk_identity.get(),
+ strlen(in->psk_identity.get()))) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
}
- if (in->tlsext_tick_lifetime_hint > 0) {
+ if (in->ticket_lifetime_hint > 0) {
if (!CBB_add_asn1(&session, &child, kTicketLifetimeHintTag) ||
- !CBB_add_asn1_uint64(&child, in->tlsext_tick_lifetime_hint)) {
+ !CBB_add_asn1_uint64(&child, in->ticket_lifetime_hint)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
}
- if (in->tlsext_tick && !for_ticket) {
+ if (!in->ticket.empty() && !for_ticket) {
if (!CBB_add_asn1(&session, &child, kTicketTag) ||
- !CBB_add_asn1_octet_string(&child, in->tlsext_tick,
- in->tlsext_ticklen)) {
+ !CBB_add_asn1_octet_string(&child, in->ticket.data(),
+ in->ticket.size())) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -297,8 +298,8 @@
if (in->signed_cert_timestamp_list != nullptr) {
if (!CBB_add_asn1(&session, &child, kSignedCertTimestampListTag) ||
!CBB_add_asn1_octet_string(
- &child, CRYPTO_BUFFER_data(in->signed_cert_timestamp_list),
- CRYPTO_BUFFER_len(in->signed_cert_timestamp_list))) {
+ &child, CRYPTO_BUFFER_data(in->signed_cert_timestamp_list.get()),
+ CRYPTO_BUFFER_len(in->signed_cert_timestamp_list.get()))) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -306,9 +307,9 @@
if (in->ocsp_response != nullptr) {
if (!CBB_add_asn1(&session, &child, kOCSPResponseTag) ||
- !CBB_add_asn1_octet_string(&child,
- CRYPTO_BUFFER_data(in->ocsp_response),
- CRYPTO_BUFFER_len(in->ocsp_response))) {
+ !CBB_add_asn1_octet_string(
+ &child, CRYPTO_BUFFER_data(in->ocsp_response.get()),
+ CRYPTO_BUFFER_len(in->ocsp_response.get()))) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -333,13 +334,13 @@
// serialized instead.
if (in->certs != NULL &&
!in->peer_sha256_valid &&
- sk_CRYPTO_BUFFER_num(in->certs) >= 2) {
+ sk_CRYPTO_BUFFER_num(in->certs.get()) >= 2) {
if (!CBB_add_asn1(&session, &child, kCertChainTag)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
- for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(in->certs); i++) {
- const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs, i);
+ for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(in->certs.get()); i++) {
+ const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs.get(), i);
if (!CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer),
CRYPTO_BUFFER_len(buffer))) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
@@ -386,10 +387,10 @@
return 0;
}
- if (in->early_alpn) {
+ if (!in->early_alpn.empty()) {
if (!CBB_add_asn1(&session, &child, kEarlyALPNTag) ||
- !CBB_add_asn1_octet_string(&child, (const uint8_t *)in->early_alpn,
- in->early_alpn_len)) {
+ !CBB_add_asn1_octet_string(&child, in->early_alpn.data(),
+ in->early_alpn.size())) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -398,13 +399,11 @@
return CBB_flush(cbb);
}
-// SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING
-// explicitly tagged with |tag| from |cbs| and saves it in |*out|. On
-// entry, if |*out| is not NULL, it frees the existing contents. If
-// the element was not found, it sets |*out| to NULL. It returns one
-// on success, whether or not the element was found, and zero on
-// decode error.
-static int SSL_SESSION_parse_string(CBS *cbs, char **out, unsigned tag) {
+// SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING explicitly
+// tagged with |tag| from |cbs| and saves it in |*out|. If the element was not
+// found, it sets |*out| to NULL. It returns one on success, whether or not the
+// element was found, and zero on decode error.
+static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr<char> *out, unsigned tag) {
CBS value;
int present;
if (!CBS_get_optional_asn1_octet_string(cbs, &value, &present, tag)) {
@@ -416,38 +415,33 @@
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
return 0;
}
- if (!CBS_strdup(&value, out)) {
+ char *raw = nullptr;
+ if (!CBS_strdup(&value, &raw)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
+ out->reset(raw);
} else {
- OPENSSL_free(*out);
- *out = NULL;
+ out->reset();
}
return 1;
}
-// SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING
-// explicitly tagged with |tag| from |cbs| and stows it in |*out_ptr|
-// and |*out_len|. If |*out_ptr| is not NULL, it frees the existing
-// contents. On entry, if the element was not found, it sets
-// |*out_ptr| to NULL. It returns one on success, whether or not the
-// element was found, and zero on decode error.
-static int SSL_SESSION_parse_octet_string(CBS *cbs, uint8_t **out_ptr,
- size_t *out_len, unsigned tag) {
+// SSL_SESSION_parse_octet_string gets an optional ASN.1 OCTET STRING explicitly
+// tagged with |tag| from |cbs| and stows it in |*out|. It returns one on
+// success, whether or not the element was found, and zero on decode error.
+static bool SSL_SESSION_parse_octet_string(CBS *cbs, Array<uint8_t> *out,
+ unsigned tag) {
CBS value;
if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
- return 0;
+ return false;
}
- if (!CBS_stow(&value, out_ptr, out_len)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- return 1;
+ return out->CopyFrom(value);
}
-static int SSL_SESSION_parse_crypto_buffer(CBS *cbs, CRYPTO_BUFFER **out,
+static int SSL_SESSION_parse_crypto_buffer(CBS *cbs,
+ UniquePtr<CRYPTO_BUFFER> *out,
unsigned tag,
CRYPTO_BUFFER_POOL *pool) {
if (!CBS_peek_asn1_tag(cbs, tag)) {
@@ -461,8 +455,7 @@
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
return 0;
}
- CRYPTO_BUFFER_free(*out);
- *out = CRYPTO_BUFFER_new_from_CBS(&value, pool);
+ out->reset(CRYPTO_BUFFER_new_from_CBS(&value, pool));
if (*out == nullptr) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
@@ -617,10 +610,9 @@
if (!SSL_SESSION_parse_string(&session, &ret->psk_identity,
kPSKIdentityTag) ||
- !SSL_SESSION_parse_u32(&session, &ret->tlsext_tick_lifetime_hint,
+ !SSL_SESSION_parse_u32(&session, &ret->ticket_lifetime_hint,
kTicketLifetimeHintTag, 0) ||
- !SSL_SESSION_parse_octet_string(&session, &ret->tlsext_tick,
- &ret->tlsext_ticklen, kTicketTag)) {
+ !SSL_SESSION_parse_octet_string(&session, &ret->ticket, kTicketTag)) {
return nullptr;
}
@@ -680,8 +672,8 @@
return nullptr;
}
if (has_peer || has_cert_chain) {
- ret->certs = sk_CRYPTO_BUFFER_new_null();
- if (ret->certs == NULL) {
+ ret->certs.reset(sk_CRYPTO_BUFFER_new_null());
+ if (ret->certs == nullptr) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return nullptr;
}
@@ -689,7 +681,7 @@
if (has_peer) {
UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new_from_CBS(&peer, pool));
if (!buffer ||
- !PushToStack(ret->certs, std::move(buffer))) {
+ !PushToStack(ret->certs.get(), std::move(buffer))) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return nullptr;
}
@@ -705,7 +697,7 @@
UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new_from_CBS(&cert, pool));
if (buffer == nullptr ||
- !PushToStack(ret->certs, std::move(buffer))) {
+ !PushToStack(ret->certs.get(), std::move(buffer))) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return nullptr;
}
@@ -746,7 +738,7 @@
!SSL_SESSION_parse_u32(&session, &ret->auth_timeout, kAuthTimeoutTag,
ret->timeout) ||
!SSL_SESSION_parse_octet_string(&session, &ret->early_alpn,
- &ret->early_alpn_len, kEarlyALPNTag) ||
+ kEarlyALPNTag) ||
CBS_len(&session) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
return nullptr;
diff --git a/ssl/ssl_cert.cc b/ssl/ssl_cert.cc
index 8b869c8..04c77ad 100644
--- a/ssl/ssl_cert.cc
+++ b/ssl/ssl_cert.cc
@@ -808,7 +808,7 @@
return NULL;
}
- return session->certs;
+ return session->certs.get();
}
const STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs(const SSL *ssl) {
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
index a153c60..0363e32 100644
--- a/ssl/ssl_lib.cc
+++ b/ssl/ssl_lib.cc
@@ -2048,8 +2048,8 @@
return;
}
- *out = CRYPTO_BUFFER_data(session->signed_cert_timestamp_list);
- *out_len = CRYPTO_BUFFER_len(session->signed_cert_timestamp_list);
+ *out = CRYPTO_BUFFER_data(session->signed_cert_timestamp_list.get());
+ *out_len = CRYPTO_BUFFER_len(session->signed_cert_timestamp_list.get());
}
void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
@@ -2061,8 +2061,8 @@
return;
}
- *out = CRYPTO_BUFFER_data(session->ocsp_response);
- *out_len = CRYPTO_BUFFER_len(session->ocsp_response);
+ *out = CRYPTO_BUFFER_data(session->ocsp_response.get());
+ *out_len = CRYPTO_BUFFER_len(session->ocsp_response.get());
}
int SSL_set_tlsext_host_name(SSL *ssl, const char *name) {
@@ -2191,8 +2191,8 @@
void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data,
unsigned *out_len) {
if (SSL_in_early_data(ssl) && !ssl->server) {
- *out_data = ssl->s3->hs->early_session->early_alpn;
- *out_len = ssl->s3->hs->early_session->early_alpn_len;
+ *out_data = ssl->s3->hs->early_session->early_alpn.data();
+ *out_len = ssl->s3->hs->early_session->early_alpn.size();
} else {
*out_data = ssl->s3->alpn_selected.data();
*out_len = ssl->s3->alpn_selected.size();
@@ -2545,7 +2545,7 @@
if (session == NULL) {
return NULL;
}
- return session->psk_identity;
+ return session->psk_identity.get();
}
void SSL_set_psk_client_callback(
diff --git a/ssl/ssl_session.cc b/ssl/ssl_session.cc
index a2a1482..379cea7 100644
--- a/ssl/ssl_session.cc
+++ b/ssl/ssl_session.cc
@@ -166,22 +166,7 @@
static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock);
UniquePtr<SSL_SESSION> ssl_session_new(const SSL_X509_METHOD *x509_method) {
- UniquePtr<SSL_SESSION> session(
- (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION)));
- if (!session) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- OPENSSL_memset(session.get(), 0, sizeof(SSL_SESSION));
-
- session->x509_method = x509_method;
- session->verify_result = X509_V_ERR_INVALID_CALL;
- session->references = 1;
- session->timeout = SSL_DEFAULT_SESSION_TIMEOUT;
- session->auth_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
- session->time = time(NULL);
- CRYPTO_new_ex_data(&session->ex_data);
- return session;
+ return MakeUnique<SSL_SESSION>(x509_method);
}
uint32_t ssl_hash_session_id(Span<const uint8_t> session_id) {
@@ -222,20 +207,20 @@
new_session->cipher = session->cipher;
// Copy authentication state.
- if (session->psk_identity != NULL) {
- new_session->psk_identity = BUF_strdup(session->psk_identity);
- if (new_session->psk_identity == NULL) {
+ if (session->psk_identity != nullptr) {
+ new_session->psk_identity.reset(BUF_strdup(session->psk_identity.get()));
+ if (new_session->psk_identity == nullptr) {
return nullptr;
}
}
- if (session->certs != NULL) {
+ if (session->certs != nullptr) {
auto buf_up_ref = [](CRYPTO_BUFFER *buf) {
CRYPTO_BUFFER_up_ref(buf);
return buf;
};
- new_session->certs = sk_CRYPTO_BUFFER_deep_copy(session->certs, buf_up_ref,
- CRYPTO_BUFFER_free);
- if (new_session->certs == NULL) {
+ new_session->certs.reset(sk_CRYPTO_BUFFER_deep_copy(
+ session->certs.get(), buf_up_ref, CRYPTO_BUFFER_free));
+ if (new_session->certs == nullptr) {
return nullptr;
}
}
@@ -246,16 +231,9 @@
new_session->verify_result = session->verify_result;
- if (session->ocsp_response != NULL) {
- new_session->ocsp_response = session->ocsp_response;
- CRYPTO_BUFFER_up_ref(new_session->ocsp_response);
- }
-
- 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);
- }
+ new_session->ocsp_response = UpRef(session->ocsp_response);
+ new_session->signed_cert_timestamp_list =
+ UpRef(session->signed_cert_timestamp_list);
OPENSSL_memcpy(new_session->peer_sha256, session->peer_sha256,
SHA256_DIGEST_LENGTH);
@@ -280,31 +258,20 @@
session->original_handshake_hash_len);
new_session->original_handshake_hash_len =
session->original_handshake_hash_len;
- new_session->tlsext_tick_lifetime_hint = session->tlsext_tick_lifetime_hint;
+ new_session->ticket_lifetime_hint = session->ticket_lifetime_hint;
new_session->ticket_age_add = session->ticket_age_add;
new_session->ticket_max_early_data = session->ticket_max_early_data;
new_session->extended_master_secret = session->extended_master_secret;
- if (session->early_alpn != NULL) {
- new_session->early_alpn =
- (uint8_t *)BUF_memdup(session->early_alpn, session->early_alpn_len);
- if (new_session->early_alpn == NULL) {
- return nullptr;
- }
+ if (!new_session->early_alpn.CopyFrom(session->early_alpn)) {
+ return nullptr;
}
- new_session->early_alpn_len = session->early_alpn_len;
}
// Copy the ticket.
- if (dup_flags & SSL_SESSION_INCLUDE_TICKET) {
- if (session->tlsext_tick != NULL) {
- new_session->tlsext_tick =
- (uint8_t *)BUF_memdup(session->tlsext_tick, session->tlsext_ticklen);
- if (new_session->tlsext_tick == NULL) {
- return nullptr;
- }
- }
- new_session->tlsext_ticklen = session->tlsext_ticklen;
+ if (dup_flags & SSL_SESSION_INCLUDE_TICKET &&
+ !new_session->ticket.CopyFrom(session->ticket)) {
+ return nullptr;
}
// The new_session does not get a copy of the ex_data.
@@ -667,7 +634,7 @@
// If the session contains a client certificate (either the full
// certificate or just the hash) then require that the form of the
// certificate matches the current configuration.
- ((sk_CRYPTO_BUFFER_num(session->certs) == 0 &&
+ ((sk_CRYPTO_BUFFER_num(session->certs.get()) == 0 &&
!session->peer_sha256_valid) ||
session->peer_sha256_valid ==
hs->config->retain_only_sha256_of_client_certs);
@@ -883,6 +850,22 @@
using namespace bssl;
+ssl_session_st::ssl_session_st(const SSL_X509_METHOD *method)
+ : x509_method(method),
+ extended_master_secret(false),
+ peer_sha256_valid(false),
+ not_resumable(false),
+ ticket_age_add_valid(false),
+ is_server(false) {
+ CRYPTO_new_ex_data(&ex_data);
+ time = ::time(nullptr);
+}
+
+ssl_session_st::~ssl_session_st() {
+ CRYPTO_free_ex_data(&g_ex_data_class, this, &ex_data);
+ x509_method->session_clear(this);
+}
+
SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx) {
return ssl_session_new(ctx->x509_method).release();
}
@@ -898,17 +881,7 @@
return;
}
- CRYPTO_free_ex_data(&g_ex_data_class, session, &session->ex_data);
-
- OPENSSL_cleanse(session->master_key, sizeof(session->master_key));
- OPENSSL_cleanse(session->session_id, sizeof(session->session_id));
- sk_CRYPTO_BUFFER_pop_free(session->certs, CRYPTO_BUFFER_free);
- session->x509_method->session_clear(session);
- OPENSSL_free(session->tlsext_tick);
- CRYPTO_BUFFER_free(session->signed_cert_timestamp_list);
- CRYPTO_BUFFER_free(session->ocsp_response);
- OPENSSL_free(session->psk_identity);
- OPENSSL_free(session->early_alpn);
+ session->~ssl_session_st();
OPENSSL_free(session);
}
@@ -951,15 +924,15 @@
const STACK_OF(CRYPTO_BUFFER) *
SSL_SESSION_get0_peer_certificates(const SSL_SESSION *session) {
- return session->certs;
+ return session->certs.get();
}
void SSL_SESSION_get0_signed_cert_timestamp_list(const SSL_SESSION *session,
const uint8_t **out,
size_t *out_len) {
if (session->signed_cert_timestamp_list) {
- *out = CRYPTO_BUFFER_data(session->signed_cert_timestamp_list);
- *out_len = CRYPTO_BUFFER_len(session->signed_cert_timestamp_list);
+ *out = CRYPTO_BUFFER_data(session->signed_cert_timestamp_list.get());
+ *out_len = CRYPTO_BUFFER_len(session->signed_cert_timestamp_list.get());
} else {
*out = nullptr;
*out_len = 0;
@@ -969,8 +942,8 @@
void SSL_SESSION_get0_ocsp_response(const SSL_SESSION *session,
const uint8_t **out, size_t *out_len) {
if (session->ocsp_response) {
- *out = CRYPTO_BUFFER_data(session->ocsp_response);
- *out_len = CRYPTO_BUFFER_len(session->ocsp_response);
+ *out = CRYPTO_BUFFER_data(session->ocsp_response.get());
+ *out_len = CRYPTO_BUFFER_len(session->ocsp_response.get());
} else {
*out = nullptr;
*out_len = 0;
@@ -1040,31 +1013,24 @@
}
int SSL_SESSION_has_ticket(const SSL_SESSION *session) {
- return session->tlsext_ticklen > 0;
+ return !session->ticket.empty();
}
void SSL_SESSION_get0_ticket(const SSL_SESSION *session,
const uint8_t **out_ticket, size_t *out_len) {
if (out_ticket != nullptr) {
- *out_ticket = session->tlsext_tick;
+ *out_ticket = session->ticket.data();
}
- *out_len = session->tlsext_ticklen;
+ *out_len = session->ticket.size();
}
int SSL_SESSION_set_ticket(SSL_SESSION *session, const uint8_t *ticket,
size_t ticket_len) {
- uint8_t *copy = (uint8_t *)BUF_memdup(ticket, ticket_len);
- if (copy == nullptr) {
- return 0;
- }
- OPENSSL_free(session->tlsext_tick);
- session->tlsext_tick = copy;
- session->tlsext_ticklen = ticket_len;
- return 1;
+ return session->ticket.CopyFrom(MakeConstSpan(ticket, ticket_len));
}
uint32_t SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session) {
- return session->tlsext_tick_lifetime_hint;
+ return session->ticket_lifetime_hint;
}
const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *session) {
diff --git a/ssl/ssl_x509.cc b/ssl/ssl_x509.cc
index 0af4167..4f2fc9e 100644
--- a/ssl/ssl_x509.cc
+++ b/ssl/ssl_x509.cc
@@ -283,7 +283,7 @@
static int ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) {
bssl::UniquePtr<STACK_OF(X509)> chain;
- if (sk_CRYPTO_BUFFER_num(sess->certs) > 0) {
+ if (sk_CRYPTO_BUFFER_num(sess->certs.get()) > 0) {
chain.reset(sk_X509_new_null());
if (!chain) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
@@ -292,7 +292,7 @@
}
X509 *leaf = nullptr;
- for (CRYPTO_BUFFER *cert : sess->certs) {
+ for (CRYPTO_BUFFER *cert : sess->certs.get()) {
UniquePtr<X509> x509(X509_parse_from_buffer(cert));
if (!x509) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
diff --git a/ssl/t1_lib.cc b/ssl/t1_lib.cc
index 6db7de7..49c8955 100644
--- a/ssl/t1_lib.cc
+++ b/ssl/t1_lib.cc
@@ -943,8 +943,7 @@
return true;
}
- const uint8_t *ticket_data = NULL;
- int ticket_len = 0;
+ Span<const uint8_t> ticket;
// Renegotiation does not participate in session resumption. However, still
// advertise the extension to avoid potentially breaking servers which carry
@@ -952,17 +951,16 @@
// without upstream's 3c3f0259238594d77264a78944d409f2127642c4.
if (!ssl->s3->initial_handshake_complete &&
ssl->session != NULL &&
- ssl->session->tlsext_tick != NULL &&
+ !ssl->session->ticket.empty() &&
// Don't send TLS 1.3 session tickets in the ticket extension.
ssl_session_protocol_version(ssl->session) < TLS1_3_VERSION) {
- ticket_data = ssl->session->tlsext_tick;
- ticket_len = ssl->session->tlsext_ticklen;
+ ticket = ssl->session->ticket;
}
- CBB ticket;
+ CBB ticket_cbb;
if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) ||
- !CBB_add_u16_length_prefixed(out, &ticket) ||
- !CBB_add_bytes(&ticket, ticket_data, ticket_len) ||
+ !CBB_add_u16_length_prefixed(out, &ticket_cbb) ||
+ !CBB_add_bytes(&ticket_cbb, ticket.data(), ticket.size()) ||
!CBB_flush(out)) {
return false;
}
@@ -1343,9 +1341,8 @@
//
// TODO(davidben): Enforce this anyway.
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);
+ hs->new_session->signed_cert_timestamp_list.reset(
+ 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 false;
@@ -1875,7 +1872,7 @@
}
size_t binder_len = EVP_MD_size(ssl_session_get_digest(ssl->session));
- return 15 + ssl->session->tlsext_ticklen + binder_len;
+ return 15 + ssl->session->ticket.size() + binder_len;
}
static bool ext_pre_shared_key_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
@@ -1909,8 +1906,8 @@
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_u16_length_prefixed(&contents, &identity) ||
!CBB_add_u16_length_prefixed(&identity, &ticket) ||
- !CBB_add_bytes(&ticket, ssl->session->tlsext_tick,
- ssl->session->tlsext_ticklen) ||
+ !CBB_add_bytes(&ticket, ssl->session->ticket.data(),
+ ssl->session->ticket.size()) ||
!CBB_add_u32(&identity, obfuscated_ticket_age) ||
!CBB_add_u16_length_prefixed(&contents, &binders) ||
!CBB_add_u8_length_prefixed(&binders, &binder) ||
@@ -2076,10 +2073,8 @@
hs->received_hello_retry_request ||
// In case ALPN preferences changed since this session was established,
// avoid reporting a confusing value in |SSL_get0_alpn_selected|.
- (ssl->session->early_alpn_len != 0 &&
- !ssl_is_alpn_protocol_allowed(
- hs, MakeConstSpan(ssl->session->early_alpn,
- ssl->session->early_alpn_len)))) {
+ (!ssl->session->early_alpn.empty() &&
+ !ssl_is_alpn_protocol_allowed(hs, ssl->session->early_alpn))) {
return true;
}
diff --git a/ssl/tls13_both.cc b/ssl/tls13_both.cc
index 495838c..9149e76 100644
--- a/ssl/tls13_both.cc
+++ b/ssl/tls13_both.cc
@@ -256,9 +256,8 @@
}
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);
+ hs->new_session->ocsp_response.reset(
+ CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool));
if (hs->new_session->ocsp_response == nullptr) {
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return 0;
@@ -280,9 +279,8 @@
}
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);
+ hs->new_session->signed_cert_timestamp_list.reset(
+ CRYPTO_BUFFER_new_from_CBS(&sct, ssl->ctx->pool));
if (hs->new_session->signed_cert_timestamp_list == nullptr) {
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return 0;
@@ -298,9 +296,7 @@
}
hs->peer_pubkey = std::move(pkey);
-
- sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free);
- hs->new_session->certs = certs.release();
+ hs->new_session->certs = std::move(certs);
if (!ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
@@ -308,7 +304,7 @@
return 0;
}
- if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) {
+ if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0) {
if (!allow_anonymous) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED);
diff --git a/ssl/tls13_client.cc b/ssl/tls13_client.cc
index 317b4d3..1f1d4b4 100644
--- a/ssl/tls13_client.cc
+++ b/ssl/tls13_client.cc
@@ -429,20 +429,14 @@
}
// Store the negotiated ALPN in the session.
- if (!ssl->s3->alpn_selected.empty()) {
- hs->new_session->early_alpn = (uint8_t *)BUF_memdup(
- ssl->s3->alpn_selected.data(), ssl->s3->alpn_selected.size());
- if (hs->new_session->early_alpn == NULL) {
- ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- return ssl_hs_error;
- }
- hs->new_session->early_alpn_len = ssl->s3->alpn_selected.size();
+ if (!hs->new_session->early_alpn.CopyFrom(ssl->s3->alpn_selected)) {
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return ssl_hs_error;
}
if (ssl->s3->early_data_accepted) {
if (hs->early_session->cipher != hs->new_session->cipher ||
- MakeConstSpan(hs->early_session->early_alpn,
- hs->early_session->early_alpn_len) !=
+ MakeConstSpan(hs->early_session->early_alpn) !=
ssl->s3->alpn_selected) {
OPENSSL_PUT_ERROR(SSL, SSL_R_ALPN_MISMATCH_ON_EARLY_DATA);
return ssl_hs_error;
@@ -849,7 +843,7 @@
!CBS_get_u32(&body, &session->ticket_age_add) ||
!CBS_get_u8_length_prefixed(&body, &ticket_nonce) ||
!CBS_get_u16_length_prefixed(&body, &ticket) ||
- !CBS_stow(&ticket, &session->tlsext_tick, &session->tlsext_ticklen) ||
+ !session->ticket.CopyFrom(ticket) ||
!CBS_get_u16_length_prefixed(&body, &extensions) ||
CBS_len(&body) != 0) {
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
diff --git a/ssl/tls13_server.cc b/ssl/tls13_server.cc
index 481dc54..a113504 100644
--- a/ssl/tls13_server.cc
+++ b/ssl/tls13_server.cc
@@ -395,8 +395,7 @@
// Custom extensions is incompatible with 0-RTT.
hs->custom_extensions.received == 0 &&
// The negotiated ALPN must match the one in the ticket.
- ssl->s3->alpn_selected ==
- MakeConstSpan(session->early_alpn, session->early_alpn_len)) {
+ MakeConstSpan(ssl->s3->alpn_selected) == session->early_alpn) {
ssl->s3->early_data_accepted = true;
}
@@ -425,14 +424,9 @@
hs->new_session->cipher = hs->new_cipher;
// Store the initial negotiated ALPN in the session.
- if (!ssl->s3->alpn_selected.empty()) {
- hs->new_session->early_alpn = (uint8_t *)BUF_memdup(
- ssl->s3->alpn_selected.data(), ssl->s3->alpn_selected.size());
- if (hs->new_session->early_alpn == NULL) {
- ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- return ssl_hs_error;
- }
- hs->new_session->early_alpn_len = ssl->s3->alpn_selected.size();
+ if (!hs->new_session->early_alpn.CopyFrom(ssl->s3->alpn_selected)) {
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return ssl_hs_error;
}
if (ssl->ctx->dos_protection_cb != NULL &&
@@ -824,7 +818,7 @@
static enum ssl_hs_wait_t do_read_client_certificate_verify(
SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) {
+ if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0) {
// Skip this state.
hs->tls13_state = state_read_channel_id;
return ssl_hs_ok;