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/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) {