Turn SSL into an opaque struct

This avoids squatting on ::ssl_st::ssl_st() and ::ssl_st::~ssl_st()
symbols. All that's left now is SSL_SESSION.

Bug: 500444613
Change-Id: Ia415b58cfec41b819d32d2cb876a2b19697f5abb
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/98467
Reviewed-by: Lily Chen <chlily@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
This commit is contained in:
David Benjamin
2026-07-07 17:12:50 -04:00
committed by boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 7fd3fe21c0
commit 0e8895bd09
35 changed files with 1422 additions and 1165 deletions
+2 -2
View File
@@ -47,7 +47,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
uint8_t alert_unused;
bssl::Array<uint8_t> client_hello_inner;
bssl::ssl_decode_client_hello_inner(
ssl.get(), &alert_unused, &client_hello_inner, encoded_client_hello_inner,
&client_hello_outer);
bssl::FromOpaque(ssl.get()), &alert_unused, &client_hello_inner,
encoded_client_hello_inner, &client_hello_outer);
return 0;
}
+25 -23
View File
@@ -210,7 +210,7 @@ static UniquePtr<DTLSIncomingMessage> dtls_new_incoming_message(
// dtls1_is_current_message_complete returns whether the current handshake
// message is complete.
static bool dtls1_is_current_message_complete(const SSL *ssl) {
static bool dtls1_is_current_message_complete(const SSLImpl *ssl) {
size_t idx = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT;
DTLSIncomingMessage *frag = ssl->d1->incoming_messages[idx].get();
return frag != nullptr && frag->reassembly.IsComplete();
@@ -221,7 +221,7 @@ static bool dtls1_is_current_message_complete(const SSL *ssl) {
// queue. Otherwise, it checks `msg_hdr` is consistent with the existing one. It
// returns NULL on failure. The caller does not take ownership of the result.
static DTLSIncomingMessage *dtls1_get_incoming_message(
SSL *ssl, uint8_t *out_alert, const struct hm_header_st *msg_hdr) {
SSLImpl *ssl, uint8_t *out_alert, const struct hm_header_st *msg_hdr) {
if (msg_hdr->seq < ssl->d1->handshake_read_seq ||
msg_hdr->seq - ssl->d1->handshake_read_seq >= SSL_MAX_HANDSHAKE_FLIGHT) {
*out_alert = SSL_AD_INTERNAL_ERROR;
@@ -252,7 +252,7 @@ static DTLSIncomingMessage *dtls1_get_incoming_message(
return ssl->d1->incoming_messages[idx].get();
}
bool dtls1_process_handshake_fragments(SSL *ssl, uint8_t *out_alert,
bool dtls1_process_handshake_fragments(SSLImpl *ssl, uint8_t *out_alert,
DTLSRecordNumber record_number,
Span<const uint8_t> record) {
bool implicit_ack = false;
@@ -372,7 +372,7 @@ bool dtls1_process_handshake_fragments(SSL *ssl, uint8_t *out_alert,
return true;
}
ssl_open_record_t dtls1_open_handshake(SSL *ssl, size_t *out_consumed,
ssl_open_record_t dtls1_open_handshake(SSLImpl *ssl, size_t *out_consumed,
uint8_t *out_alert, Span<uint8_t> in) {
uint8_t type;
DTLSRecordNumber record_number;
@@ -433,7 +433,7 @@ ssl_open_record_t dtls1_open_handshake(SSL *ssl, size_t *out_consumed,
}
}
bool dtls1_get_message(const SSL *ssl, SSLMessage *out) {
bool dtls1_get_message(const SSLImpl *ssl, SSLMessage *out) {
if (!dtls1_is_current_message_complete(ssl)) {
return false;
}
@@ -451,7 +451,7 @@ bool dtls1_get_message(const SSL *ssl, SSLMessage *out) {
return true;
}
void dtls1_next_message(SSL *ssl) {
void dtls1_next_message(SSLImpl *ssl) {
assert(ssl->s3->has_message);
assert(dtls1_is_current_message_complete(ssl));
size_t index = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT;
@@ -468,7 +468,7 @@ void dtls1_next_message(SSL *ssl) {
}
}
bool dtls_has_unprocessed_handshake_data(const SSL *ssl) {
bool dtls_has_unprocessed_handshake_data(const SSLImpl *ssl) {
size_t current = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT;
for (size_t i = 0; i < SSL_MAX_HANDSHAKE_FLIGHT; i++) {
// Skip the current message.
@@ -499,7 +499,8 @@ bool dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr,
return true;
}
ssl_open_record_t dtls1_open_change_cipher_spec(SSL *ssl, size_t *out_consumed,
ssl_open_record_t dtls1_open_change_cipher_spec(SSLImpl *ssl,
size_t *out_consumed,
uint8_t *out_alert,
Span<uint8_t> in) {
if (!ssl->d1->has_change_cipher_spec) {
@@ -519,7 +520,7 @@ ssl_open_record_t dtls1_open_change_cipher_spec(SSL *ssl, size_t *out_consumed,
// Sending handshake messages.
void dtls_clear_outgoing_messages(SSL *ssl) {
void dtls_clear_outgoing_messages(SSLImpl *ssl) {
ssl->d1->outgoing_messages.clear();
ssl->d1->sent_records = nullptr;
ssl->d1->outgoing_written = 0;
@@ -530,7 +531,7 @@ void dtls_clear_outgoing_messages(SSL *ssl) {
dtls_clear_unused_write_epochs(ssl);
}
void dtls_clear_unused_write_epochs(SSL *ssl) {
void dtls_clear_unused_write_epochs(SSLImpl *ssl) {
ssl->d1->extra_write_epochs.EraseIf(
[ssl](const UniquePtr<DTLSWriteEpoch> &write_epoch) -> bool {
// Non-current epochs may be discarded once there are no incomplete
@@ -547,7 +548,7 @@ void dtls_clear_unused_write_epochs(SSL *ssl) {
});
}
bool dtls1_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type) {
bool dtls1_init_message(const SSLImpl *ssl, CBB *cbb, CBB *body, uint8_t type) {
// Pick a modest size hint to save most of the `realloc` calls.
if (!CBB_init(cbb, 64) || //
!CBB_add_u8(cbb, type) || //
@@ -561,7 +562,8 @@ bool dtls1_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type) {
return true;
}
bool dtls1_finish_message(const SSL *ssl, CBB *cbb, Array<uint8_t> *out_msg) {
bool dtls1_finish_message(const SSLImpl *ssl, CBB *cbb,
Array<uint8_t> *out_msg) {
if (!CBBFinishArray(cbb, out_msg) ||
out_msg->size() < DTLS1_HM_HEADER_LENGTH) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -577,7 +579,7 @@ bool dtls1_finish_message(const SSL *ssl, CBB *cbb, Array<uint8_t> *out_msg) {
// add_outgoing adds a new handshake message or ChangeCipherSpec to the current
// outgoing flight. It returns true on success and false on error.
static bool add_outgoing(SSL *ssl, bool is_ccs, Array<uint8_t> data) {
static bool add_outgoing(SSLImpl *ssl, bool is_ccs, Array<uint8_t> data) {
if (ssl->d1->outgoing_messages_complete) {
// If we've begun writing a new flight, we received the peer flight. Discard
// the timer and the our flight.
@@ -628,11 +630,11 @@ static bool add_outgoing(SSL *ssl, bool is_ccs, Array<uint8_t> data) {
return true;
}
bool dtls1_add_message(SSL *ssl, Array<uint8_t> data) {
bool dtls1_add_message(SSLImpl *ssl, Array<uint8_t> data) {
return add_outgoing(ssl, false /* handshake */, std::move(data));
}
bool dtls1_add_change_cipher_spec(SSL *ssl) {
bool dtls1_add_change_cipher_spec(SSLImpl *ssl) {
// DTLS 1.3 disables compatibility mode, which means that DTLS 1.3 never sends
// a ChangeCipherSpec message.
if (ssl_protocol_version(ssl) > TLS1_2_VERSION) {
@@ -643,7 +645,7 @@ bool dtls1_add_change_cipher_spec(SSL *ssl) {
// dtls1_update_mtu updates the current MTU from the BIO, ensuring it is above
// the minimum.
static void dtls1_update_mtu(SSL *ssl) {
static void dtls1_update_mtu(SSLImpl *ssl) {
// TODO(davidben): No consumer implements `BIO_CTRL_DGRAM_SET_MTU` and the
// only `BIO_CTRL_DGRAM_QUERY_MTU` implementation could use
// `SSL_set_mtu`. Does this need to be so complex?
@@ -677,7 +679,7 @@ enum seal_result_t {
// this record, it returns `seal_continue` and the caller should loop again.
// Otherwise, it returns `seal_flush` and the packet is complete (either because
// there are no more messages or the packet is full).
static seal_result_t seal_next_record(SSL *ssl, Span<uint8_t> out,
static seal_result_t seal_next_record(SSLImpl *ssl, Span<uint8_t> out,
size_t *out_len) {
*out_len = 0;
@@ -847,7 +849,7 @@ packet_full:
// seal_next_packet writes as much of the next flight as possible to `out` and
// advances `ssl->d1->outgoing_written` and `ssl->d1->outgoing_offset` as
// appropriate.
static bool seal_next_packet(SSL *ssl, Span<uint8_t> out, size_t *out_len) {
static bool seal_next_packet(SSLImpl *ssl, Span<uint8_t> out, size_t *out_len) {
size_t total = 0;
for (;;) {
size_t len;
@@ -872,7 +874,7 @@ static bool seal_next_packet(SSL *ssl, Span<uint8_t> out, size_t *out_len) {
return true;
}
static int send_flight(SSL *ssl) {
static int send_flight(SSLImpl *ssl) {
if (ssl->s3->write_shutdown != ssl_shutdown_none) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
return -1;
@@ -928,7 +930,7 @@ static int send_flight(SSL *ssl) {
return 1;
}
void dtls1_finish_flight(SSL *ssl) {
void dtls1_finish_flight(SSLImpl *ssl) {
if (ssl->d1->outgoing_messages.empty() ||
ssl->d1->outgoing_messages_complete) {
return; // Nothing to do.
@@ -953,12 +955,12 @@ void dtls1_finish_flight(SSL *ssl) {
dtls1_stop_timer(ssl);
}
void dtls1_schedule_ack(SSL *ssl) {
void dtls1_schedule_ack(SSLImpl *ssl) {
ssl->d1->ack_timer.Stop();
ssl->d1->sending_ack = !ssl->d1->records_to_ack.empty();
}
static int send_ack(SSL *ssl) {
static int send_ack(SSLImpl *ssl) {
assert(ssl_protocol_version(ssl) >= TLS1_3_VERSION);
// Ensure we don't send so many ACKs that we overflow the MTU. There is a
@@ -1017,7 +1019,7 @@ static int send_ack(SSL *ssl) {
return 1;
}
int dtls1_flush(SSL *ssl) {
int dtls1_flush(SSLImpl *ssl) {
// Send the pending ACK, if any.
if (ssl->d1->sending_ack) {
int ret = send_ack(ssl);
+39 -34
View File
@@ -63,7 +63,7 @@ bool DTLS1_STATE::Init() {
return true;
}
bool dtls1_new(SSL *ssl) {
bool dtls1_new(SSLImpl *ssl) {
if (!tls_new(ssl)) {
return false;
}
@@ -77,7 +77,7 @@ bool dtls1_new(SSL *ssl) {
return true;
}
void dtls1_free(SSL *ssl) {
void dtls1_free(SSLImpl *ssl) {
tls_free(ssl);
if (ssl == nullptr) {
@@ -124,7 +124,7 @@ uint64_t DTLSTimer::MicrosecondsRemaining(OPENSSL_timeval now) const {
return remain_us;
}
void dtls1_stop_timer(SSL *ssl) {
void dtls1_stop_timer(SSLImpl *ssl) {
ssl->d1->num_timeouts = 0;
ssl->d1->retransmit_timer.Stop();
ssl->d1->timeout_duration_ms = ssl->initial_timeout_duration_ms;
@@ -135,15 +135,16 @@ BSSL_NAMESPACE_END
using namespace bssl;
void DTLSv1_set_initial_timeout_duration(SSL *ssl, uint32_t duration_ms) {
if (!SSL_is_dtls(ssl)) {
auto *ssl_impl = FromOpaque(ssl);
if (!SSL_is_dtls(ssl_impl)) {
return;
}
// Modify the initial value for next flight.
ssl->initial_timeout_duration_ms = duration_ms;
ssl_impl->initial_timeout_duration_ms = duration_ms;
// Retransmit timer increase by factor of 2 at each timeout.
uint32_t timeout_duration_ms = duration_ms << ssl->d1->num_timeouts;
uint32_t timeout_duration_ms = duration_ms << ssl_impl->d1->num_timeouts;
if (timeout_duration_ms < duration_ms) {
timeout_duration_ms = uint32_t{60000};
} else {
@@ -151,30 +152,32 @@ void DTLSv1_set_initial_timeout_duration(SSL *ssl, uint32_t duration_ms) {
}
// Modify the value used for next timeout.
ssl->d1->timeout_duration_ms = timeout_duration_ms;
ssl_impl->d1->timeout_duration_ms = timeout_duration_ms;
// Modify retransmit timer.
if (ssl->d1->retransmit_timer.IsSet()) {
ssl->d1->retransmit_timer.UpdateDuration(uint64_t{timeout_duration_ms} *
1000);
if (ssl_impl->d1->retransmit_timer.IsSet()) {
ssl_impl->d1->retransmit_timer.UpdateDuration(
uint64_t{timeout_duration_ms} * 1000);
}
// Modify ack timer.
if (ssl->d1->ack_timer.IsSet()) {
ssl->d1->ack_timer.UpdateDuration(uint64_t{timeout_duration_ms} * 1000 / 4);
if (ssl_impl->d1->ack_timer.IsSet()) {
ssl_impl->d1->ack_timer.UpdateDuration(uint64_t{timeout_duration_ms} *
1000 / 4);
}
}
int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) {
if (!SSL_is_dtls(ssl)) {
const auto *ssl_impl = FromOpaque(ssl);
if (!SSL_is_dtls(ssl_impl)) {
return 0;
}
OPENSSL_timeval now = ssl_ctx_get_current_time(ssl->ctx.get());
OPENSSL_timeval now = ssl_ctx_get_current_time(ssl_impl->ctx.get());
uint64_t remaining_usec =
ssl->d1->retransmit_timer.MicrosecondsRemaining(now);
remaining_usec =
std::min(remaining_usec, ssl->d1->ack_timer.MicrosecondsRemaining(now));
ssl_impl->d1->retransmit_timer.MicrosecondsRemaining(now);
remaining_usec = std::min(remaining_usec,
ssl_impl->d1->ack_timer.MicrosecondsRemaining(now));
if (remaining_usec == DTLSTimer::kNever) {
return 0; // No timeout is set.
}
@@ -195,39 +198,41 @@ int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) {
}
int DTLSv1_handle_timeout(SSL *ssl) {
ssl_reset_error_state(ssl);
auto *ssl_impl = FromOpaque(ssl);
ssl_reset_error_state(ssl_impl);
if (!SSL_is_dtls(ssl)) {
if (!SSL_is_dtls(ssl_impl)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return -1;
}
if (!ssl->d1->ack_timer.IsSet() && !ssl->d1->retransmit_timer.IsSet()) {
if (!ssl_impl->d1->ack_timer.IsSet() &&
!ssl_impl->d1->retransmit_timer.IsSet()) {
// No timers are running. Don't bother querying the clock.
return 0;
}
OPENSSL_timeval now = ssl_ctx_get_current_time(ssl->ctx.get());
OPENSSL_timeval now = ssl_ctx_get_current_time(ssl_impl->ctx.get());
bool any_timer_expired = false;
if (ssl->d1->ack_timer.IsExpired(now)) {
if (ssl_impl->d1->ack_timer.IsExpired(now)) {
any_timer_expired = true;
ssl->d1->sending_ack = true;
ssl->d1->ack_timer.Stop();
ssl_impl->d1->sending_ack = true;
ssl_impl->d1->ack_timer.Stop();
}
if (ssl->d1->retransmit_timer.IsExpired(now)) {
if (ssl_impl->d1->retransmit_timer.IsExpired(now)) {
any_timer_expired = true;
ssl->d1->sending_flight = true;
ssl->d1->retransmit_timer.Stop();
ssl_impl->d1->sending_flight = true;
ssl_impl->d1->retransmit_timer.Stop();
ssl->d1->num_timeouts++;
ssl_impl->d1->num_timeouts++;
// Reduce MTU after 2 unsuccessful retransmissions.
if (ssl->d1->num_timeouts > DTLS1_MTU_TIMEOUTS &&
!(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
long mtu = BIO_ctrl(ssl->wbio.get(), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0,
nullptr);
if (ssl_impl->d1->num_timeouts > DTLS1_MTU_TIMEOUTS &&
!(SSL_get_options(ssl_impl) & SSL_OP_NO_QUERY_MTU)) {
long mtu = BIO_ctrl(ssl_impl->wbio.get(), BIO_CTRL_DGRAM_GET_FALLBACK_MTU,
0, nullptr);
if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) {
ssl->d1->mtu = (unsigned)mtu;
ssl_impl->d1->mtu = (unsigned)mtu;
}
}
}
@@ -236,5 +241,5 @@ int DTLSv1_handle_timeout(SSL *ssl) {
return 0;
}
return dtls1_flush(ssl);
return dtls1_flush(ssl_impl);
}
+5 -5
View File
@@ -32,7 +32,7 @@
BSSL_NAMESPACE_BEGIN
ssl_open_record_t dtls1_process_ack(SSL *ssl, uint8_t *out_alert,
ssl_open_record_t dtls1_process_ack(SSLImpl *ssl, uint8_t *out_alert,
DTLSRecordNumber ack_record_number,
Span<const uint8_t> data) {
// As a DTLS-1.3-capable client, it is possible to receive an ACK before we
@@ -157,7 +157,7 @@ ssl_open_record_t dtls1_process_ack(SSL *ssl, uint8_t *out_alert,
return ssl_open_record_discard;
}
ssl_open_record_t dtls1_open_app_data(SSL *ssl, Span<uint8_t> *out,
ssl_open_record_t dtls1_open_app_data(SSLImpl *ssl, Span<uint8_t> *out,
size_t *out_consumed, uint8_t *out_alert,
Span<uint8_t> in) {
assert(!SSL_in_init(ssl));
@@ -234,7 +234,7 @@ ssl_open_record_t dtls1_open_app_data(SSL *ssl, Span<uint8_t> *out,
return ssl_open_record_success;
}
int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake,
int dtls1_write_app_data(SSLImpl *ssl, bool *out_needs_handshake,
size_t *out_bytes_written, Span<const uint8_t> in) {
assert(!SSL_in_init(ssl));
*out_needs_handshake = false;
@@ -265,7 +265,7 @@ int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake,
return 1;
}
int dtls1_write_record(SSL *ssl, int type, Span<const uint8_t> in,
int dtls1_write_record(SSLImpl *ssl, int type, Span<const uint8_t> in,
uint16_t epoch) {
SSLBuffer *buf = &ssl->s3->write_buffer;
assert(in.size() <= SSL3_RT_MAX_PLAIN_LENGTH);
@@ -298,7 +298,7 @@ int dtls1_write_record(SSL *ssl, int type, Span<const uint8_t> in,
return 1;
}
int dtls1_dispatch_alert(SSL *ssl) {
int dtls1_dispatch_alert(SSLImpl *ssl) {
int ret = dtls1_write_record(ssl, SSL3_RT_ALERT, ssl->s3->send_alert,
ssl->d1->write_epoch.epoch());
if (ret <= 0) {
+10 -8
View File
@@ -92,27 +92,29 @@ int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx, const char *profiles) {
}
int SSL_set_srtp_profiles(SSL *ssl, const char *profiles) {
return ssl->config != nullptr &&
ssl_ctx_make_profiles(profiles, &ssl->config->srtp_profiles);
auto *ssl_impl = FromOpaque(ssl);
return ssl_impl->config != nullptr &&
ssl_ctx_make_profiles(profiles, &ssl_impl->config->srtp_profiles);
}
const STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(const SSL *ssl) {
if (ssl == nullptr) {
auto *ssl_impl = FromOpaque(ssl);
if (ssl_impl == nullptr) {
return nullptr;
}
if (ssl->config == nullptr) {
if (ssl_impl->config == nullptr) {
assert(0);
return nullptr;
}
return ssl->config->srtp_profiles != nullptr
? ssl->config->srtp_profiles.get()
: ssl->ctx->srtp_profiles.get();
return ssl_impl->config->srtp_profiles != nullptr
? ssl_impl->config->srtp_profiles.get()
: ssl_impl->ctx->srtp_profiles.get();
}
const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *ssl) {
return ssl->s3->srtp_profile;
return FromOpaque(ssl)->s3->srtp_profile;
}
int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) {
+4 -4
View File
@@ -25,7 +25,7 @@
using namespace bssl;
static void dtls1_on_handshake_complete(SSL *ssl) {
static void dtls1_on_handshake_complete(SSLImpl *ssl) {
if (ssl_protocol_version(ssl) <= TLS1_2_VERSION) {
// Stop the reply timer left by the last flight we sent. In DTLS 1.2, the
// retransmission timer ends when the handshake completes. If we sent the
@@ -40,7 +40,7 @@ static void dtls1_on_handshake_complete(SSL *ssl) {
}
}
static bool next_epoch(const SSL *ssl, uint16_t *out,
static bool next_epoch(const SSLImpl *ssl, uint16_t *out,
ssl_encryption_level_t level, uint16_t prev) {
switch (level) {
case ssl_encryption_initial:
@@ -68,7 +68,7 @@ static bool next_epoch(const SSL *ssl, uint16_t *out,
return false;
}
static bool dtls1_set_read_state(SSL *ssl, ssl_encryption_level_t level,
static bool dtls1_set_read_state(SSLImpl *ssl, ssl_encryption_level_t level,
UniquePtr<SSLAEADContext> aead_ctx,
Span<const uint8_t> traffic_secret) {
// Cipher changes are forbidden if the current epoch has leftover data.
@@ -108,7 +108,7 @@ static bool dtls1_set_read_state(SSL *ssl, ssl_encryption_level_t level,
return true;
}
static bool dtls1_set_write_state(SSL *ssl, ssl_encryption_level_t level,
static bool dtls1_set_write_state(SSLImpl *ssl, ssl_encryption_level_t level,
UniquePtr<SSLAEADContext> aead_ctx,
Span<const uint8_t> traffic_secret) {
uint16_t epoch;
+15 -14
View File
@@ -56,7 +56,7 @@ void DTLSReplayBitmap::Record(uint64_t seq_num) {
}
}
static uint16_t dtls_record_version(const SSL *ssl) {
static uint16_t dtls_record_version(const SSLImpl *ssl) {
if (ssl->s3->version == 0) {
// Before the version is determined, outgoing records use dTLS 1.0 for
// historical compatibility requirements.
@@ -68,7 +68,7 @@ static uint16_t dtls_record_version(const SSL *ssl) {
: ssl->s3->version;
}
static uint64_t dtls_aead_sequence(const SSL *ssl, DTLSRecordNumber num) {
static uint64_t dtls_aead_sequence(const SSLImpl *ssl, DTLSRecordNumber num) {
// DTLS 1.3 uses the sequence number with the AEAD, while DTLS 1.2 uses the
// combined value. If the version is not known, the epoch is unencrypted and
// the value is ignored.
@@ -119,7 +119,7 @@ uint64_t reconstruct_seqnum(uint16_t wire_seq, uint64_t seq_mask,
return seqnum;
}
DTLSReadEpoch *dtls_get_read_epoch(const SSL *ssl, uint16_t epoch) {
DTLSReadEpoch *dtls_get_read_epoch(const SSLImpl *ssl, uint16_t epoch) {
if (epoch == ssl->d1->read_epoch.epoch) {
return &ssl->d1->read_epoch;
}
@@ -134,7 +134,7 @@ DTLSReadEpoch *dtls_get_read_epoch(const SSL *ssl, uint16_t epoch) {
return nullptr;
}
DTLSWriteEpoch *dtls_get_write_epoch(const SSL *ssl, uint16_t epoch) {
DTLSWriteEpoch *dtls_get_write_epoch(const SSLImpl *ssl, uint16_t epoch) {
if (ssl->d1->write_epoch.epoch() == epoch) {
return &ssl->d1->write_epoch;
}
@@ -160,14 +160,14 @@ struct ParsedDTLSRecord {
uint16_t version = 0;
};
static bool use_dtls13_record_header(const SSL *ssl, uint16_t epoch) {
static bool use_dtls13_record_header(const SSLImpl *ssl, uint16_t epoch) {
// Plaintext records in DTLS 1.3 also use the DTLSPlaintext structure for
// backwards compatibility.
return ssl->s3->version != 0 && ssl_protocol_version(ssl) > TLS1_2_VERSION &&
epoch > 0;
}
static bool parse_dtls13_record(SSL *ssl, CBS *in, ParsedDTLSRecord *out) {
static bool parse_dtls13_record(SSLImpl *ssl, CBS *in, ParsedDTLSRecord *out) {
if (out->type & 0x10) {
// Connection ID bit set, which we didn't negotiate.
return false;
@@ -232,7 +232,7 @@ static bool parse_dtls13_record(SSL *ssl, CBS *in, ParsedDTLSRecord *out) {
return true;
}
static bool parse_dtls12_record(SSL *ssl, CBS *in, ParsedDTLSRecord *out) {
static bool parse_dtls12_record(SSLImpl *ssl, CBS *in, ParsedDTLSRecord *out) {
uint64_t epoch_and_seq;
if (!CBS_get_u16(in, &out->version) || //
!CBS_get_u64(in, &epoch_and_seq) ||
@@ -264,7 +264,7 @@ static bool parse_dtls12_record(SSL *ssl, CBS *in, ParsedDTLSRecord *out) {
return true;
}
static bool parse_dtls_record(SSL *ssl, CBS *cbs, ParsedDTLSRecord *out) {
static bool parse_dtls_record(SSLImpl *ssl, CBS *cbs, ParsedDTLSRecord *out) {
CBS copy = *cbs;
if (!CBS_get_u8(cbs, &out->type)) {
return false;
@@ -289,7 +289,7 @@ static bool parse_dtls_record(SSL *ssl, CBS *cbs, ParsedDTLSRecord *out) {
return true;
}
enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type,
enum ssl_open_record_t dtls_open_record(SSLImpl *ssl, uint8_t *out_type,
DTLSRecordNumber *out_number,
Span<uint8_t> *out,
size_t *out_consumed,
@@ -424,7 +424,7 @@ enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type,
return ssl_open_record_success;
}
size_t dtls_record_header_write_len(const SSL *ssl, uint16_t epoch) {
size_t dtls_record_header_write_len(const SSLImpl *ssl, uint16_t epoch) {
if (!use_dtls13_record_header(ssl, epoch)) {
return DTLS_PLAINTEXT_RECORD_HEADER_LENGTH;
}
@@ -436,7 +436,7 @@ size_t dtls_record_header_write_len(const SSL *ssl, uint16_t epoch) {
return DTLS1_3_RECORD_HEADER_WRITE_LENGTH;
}
size_t dtls_max_seal_overhead(const SSL *ssl, uint16_t epoch) {
size_t dtls_max_seal_overhead(const SSLImpl *ssl, uint16_t epoch) {
DTLSWriteEpoch *write_epoch = dtls_get_write_epoch(ssl, epoch);
if (write_epoch == nullptr) {
return 0;
@@ -450,7 +450,7 @@ size_t dtls_max_seal_overhead(const SSL *ssl, uint16_t epoch) {
return ret;
}
size_t dtls_seal_prefix_len(const SSL *ssl, uint16_t epoch) {
size_t dtls_seal_prefix_len(const SSLImpl *ssl, uint16_t epoch) {
DTLSWriteEpoch *write_epoch = dtls_get_write_epoch(ssl, epoch);
if (write_epoch == nullptr) {
return 0;
@@ -459,7 +459,8 @@ size_t dtls_seal_prefix_len(const SSL *ssl, uint16_t epoch) {
write_epoch->aead->ExplicitNonceLen();
}
size_t dtls_seal_max_input_len(const SSL *ssl, uint16_t epoch, size_t max_out) {
size_t dtls_seal_max_input_len(const SSLImpl *ssl, uint16_t epoch,
size_t max_out) {
DTLSWriteEpoch *write_epoch = dtls_get_write_epoch(ssl, epoch);
if (write_epoch == nullptr) {
return 0;
@@ -477,7 +478,7 @@ size_t dtls_seal_max_input_len(const SSL *ssl, uint16_t epoch, size_t max_out) {
return max_out;
}
bool dtls_seal_record(SSL *ssl, DTLSRecordNumber *out_number, uint8_t *out,
bool dtls_seal_record(SSLImpl *ssl, DTLSRecordNumber *out_number, uint8_t *out,
size_t *out_len, size_t max_out, uint8_t type,
const uint8_t *in, size_t in_len, uint16_t epoch) {
const size_t prefix = dtls_seal_prefix_len(ssl, epoch);
+18 -13
View File
@@ -90,7 +90,7 @@ static bool ssl_client_hello_write_without_extensions(
return true;
}
static bool is_valid_client_hello_inner(SSL *ssl, uint8_t *out_alert,
static bool is_valid_client_hello_inner(SSLImpl *ssl, uint8_t *out_alert,
Span<const uint8_t> body) {
// See RFC 9849, section 7.1.
SSL_CLIENT_HELLO client_hello;
@@ -135,7 +135,7 @@ static bool is_valid_client_hello_inner(SSL *ssl, uint8_t *out_alert,
}
bool ssl_decode_client_hello_inner(
SSL *ssl, uint8_t *out_alert, Array<uint8_t> *out_client_hello_inner,
SSLImpl *ssl, uint8_t *out_alert, Array<uint8_t> *out_client_hello_inner,
Span<const uint8_t> encoded_client_hello_inner,
const SSL_CLIENT_HELLO *client_hello_outer) {
SSL_CLIENT_HELLO client_hello_inner;
@@ -784,7 +784,7 @@ static bool setup_ech_grease(SSL_HANDSHAKE *hs) {
}
bool ssl_encrypt_client_hello(SSL_HANDSHAKE *hs, Span<const uint8_t> enc) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!hs->selected_ech_config) {
return setup_ech_grease(hs);
}
@@ -894,15 +894,17 @@ BSSL_NAMESPACE_END
using namespace bssl;
void SSL_set_enable_ech_grease(SSL *ssl, int enable) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
return;
}
ssl->config->ech_grease_enabled = !!enable;
ssl_impl->config->ech_grease_enabled = !!enable;
}
int SSL_set1_ech_config_list(SSL *ssl, const uint8_t *ech_config_list,
size_t ech_config_list_len) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
return 0;
}
@@ -911,19 +913,20 @@ int SSL_set1_ech_config_list(SSL *ssl, const uint8_t *ech_config_list,
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ECH_CONFIG_LIST);
return 0;
}
return ssl->config->client_ech_config_list.CopyFrom(span);
return ssl_impl->config->client_ech_config_list.CopyFrom(span);
}
void SSL_get0_ech_name_override(const SSL *ssl, const char **out_name,
size_t *out_name_len) {
const auto *ssl_impl = FromOpaque(ssl);
// When ECH is rejected, we use the public name. Note that, if
// `SSL_CTX_set_reverify_on_resume` is enabled, we reverify the certificate
// before the 0-RTT point. If also offering ECH, we verify as if
// ClientHelloInner was accepted and do not override. This works because, at
// this point, `ech_status` will be `ssl_ech_none`. See the
// ECH-Client-Reject-EarlyDataReject-OverrideNameOnRetry tests in runner.go.
const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
if (!ssl->server && hs && ssl->s3->ech_status == ssl_ech_rejected) {
const SSL_HANDSHAKE *hs = ssl_impl->s3->hs.get();
if (!ssl_impl->server && hs && ssl_impl->s3->ech_status == ssl_ech_rejected) {
*out_name = reinterpret_cast<const char *>(
hs->selected_ech_config->public_name.data());
*out_name_len = hs->selected_ech_config->public_name.size();
@@ -936,7 +939,8 @@ void SSL_get0_ech_name_override(const SSL *ssl, const char **out_name,
void SSL_get0_ech_retry_configs(const SSL *ssl,
const uint8_t **out_retry_configs,
size_t *out_retry_configs_len) {
const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
const auto *ssl_impl = FromOpaque(ssl);
const SSL_HANDSHAKE *hs = ssl_impl->s3->hs.get();
if (!hs || !hs->ech_authenticated_reject) {
// It is an error to call this function except in response to
// `SSL_R_ECH_REJECTED`. Returning an empty string risks the caller
@@ -1083,12 +1087,13 @@ int SSL_CTX_set1_ech_keys(SSL_CTX *ctx, SSL_ECH_KEYS *keys) {
}
int SSL_ech_accepted(const SSL *ssl) {
if (SSL_in_early_data(ssl) && !ssl->server) {
const auto *ssl_impl = FromOpaque(ssl);
if (SSL_in_early_data(ssl_impl) && !ssl_impl->server) {
// In the client early data state, we report properties as if the server
// accepted early data. The server can only accept early data with
// ClientHelloInner.
return ssl->s3->hs->selected_ech_config != nullptr;
return ssl_impl->s3->hs->selected_ech_config != nullptr;
}
return ssl->s3->ech_status == ssl_ech_accepted;
return ssl_impl->s3->ech_status == ssl_ech_accepted;
}
+61 -61
View File
@@ -115,10 +115,10 @@ static bool is_post_quantum_group(uint16_t id) {
}
}
bool ssl_parse_client_hello_with_trailing_data(const SSL *ssl, CBS *cbs,
bool ssl_parse_client_hello_with_trailing_data(const SSLImpl *ssl, CBS *cbs,
SSL_CLIENT_HELLO *out) {
OPENSSL_memset(out, 0, sizeof(*out));
out->ssl = const_cast<SSL *>(ssl);
out->ssl = const_cast<SSLImpl *>(ssl);
CBS copy = *cbs;
CBS random, session_id;
@@ -207,7 +207,7 @@ bool ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello,
}
bool tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
assert(ssl->server);
// Clients are not required to send a supported_groups extension. In this
@@ -523,7 +523,7 @@ static bool dont_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { return true; }
static bool ext_sni_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
// If offering ECH, send the public name instead of the configured name.
Span<const uint8_t> hostname;
if (type == ssl_client_hello_outer) {
@@ -613,7 +613,7 @@ static bool ext_ech_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
static bool ext_ech_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (contents == nullptr) {
return true;
}
@@ -665,7 +665,7 @@ static bool ext_ech_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
}
static bool ext_ech_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl_protocol_version(ssl) < TLS1_3_VERSION ||
ssl->s3->ech_status == ssl_ech_accepted || //
hs->ech_keys == nullptr) {
@@ -700,7 +700,7 @@ static bool ext_ech_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
static bool ext_ri_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
// Renegotiation indication is not necessary in TLS 1.3.
if (hs->min_version >= TLS1_3_VERSION || //
type == ssl_client_hello_inner) {
@@ -725,7 +725,7 @@ static bool ext_ri_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
static bool ext_ri_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
if (contents != nullptr) {
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
@@ -804,7 +804,7 @@ static bool ext_ri_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
static bool ext_ri_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// Renegotiation isn't supported as a server so this function should never be
// called after the initial handshake.
assert(!ssl->s3->initial_handshake_complete);
@@ -839,7 +839,7 @@ static bool ext_ri_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
}
static bool ext_ri_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// Renegotiation isn't supported as a server so this function should never be
// called after the initial handshake.
assert(!ssl->s3->initial_handshake_complete);
@@ -880,7 +880,7 @@ static bool ext_ems_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
static bool ext_ems_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (contents != nullptr) {
if (ssl_protocol_version(ssl) >= TLS1_3_VERSION || //
@@ -942,7 +942,7 @@ static bool ext_ems_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
static bool ext_ticket_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
// TLS 1.3 uses a different ticket extension.
if (hs->min_version >= TLS1_3_VERSION || type == ssl_client_hello_inner ||
SSL_get_options(ssl) & SSL_OP_NO_TICKET) {
@@ -973,7 +973,7 @@ static bool ext_ticket_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
static bool ext_ticket_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (contents == nullptr) {
return true;
}
@@ -1091,7 +1091,7 @@ static bool ext_ocsp_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
static bool ext_ocsp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (contents == nullptr) {
return true;
}
@@ -1134,7 +1134,7 @@ static bool ext_ocsp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
}
static bool ext_ocsp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl_protocol_version(ssl) >= TLS1_3_VERSION ||
!hs->ocsp_stapling_requested || ssl->s3->session_reused ||
!ssl_cipher_uses_certificate_auth(hs->new_cipher) ||
@@ -1156,7 +1156,7 @@ static bool ext_ocsp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
static bool ext_npn_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
if (ssl->ctx->next_proto_select_cb == nullptr ||
// Do not allow NPN to change on renegotiation.
ssl->s3->initial_handshake_complete ||
@@ -1176,7 +1176,7 @@ static bool ext_npn_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
static bool ext_npn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (contents == nullptr) {
return true;
}
@@ -1228,7 +1228,7 @@ static bool ext_npn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
static bool ext_npn_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
return true;
}
@@ -1249,7 +1249,7 @@ static bool ext_npn_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
}
static bool ext_npn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// `next_proto_neg_seen` might have been cleared when an ALPN extension was
// parsed.
if (!hs->next_proto_neg_seen) {
@@ -1299,7 +1299,7 @@ static bool ext_sct_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
static bool ext_sct_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (contents == nullptr) {
return true;
}
@@ -1351,7 +1351,7 @@ static bool ext_sct_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
}
static bool ext_sct_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
assert(hs->scts_requested);
// The extension shouldn't be sent when resuming sessions.
if (ssl_protocol_version(ssl) >= TLS1_3_VERSION || ssl->s3->session_reused ||
@@ -1379,7 +1379,7 @@ static bool ext_sct_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
static bool ext_alpn_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
if (hs->config->alpn_client_proto_list.empty() && SSL_is_quic(ssl)) {
// ALPN MUST be used with QUIC.
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_APPLICATION_PROTOCOL);
@@ -1407,7 +1407,7 @@ static bool ext_alpn_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
static bool ext_alpn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (contents == nullptr) {
if (SSL_is_quic(ssl)) {
// ALPN is required when QUIC is used.
@@ -1503,7 +1503,7 @@ bool ssl_alpn_list_contains_protocol(Span<const uint8_t> list,
bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert,
const SSL_CLIENT_HELLO *client_hello) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
CBS contents;
if (ssl->ctx->alpn_select_cb == nullptr ||
!ssl_client_hello_get_extension(
@@ -1574,7 +1574,7 @@ bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert,
}
static bool ext_alpn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl->s3->alpn_selected.empty()) {
return true;
}
@@ -1601,7 +1601,7 @@ static bool ext_alpn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
static bool ext_channel_id_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
if (!hs->config->channel_id_private || SSL_is_dtls(ssl) ||
// Don't offer Channel ID in ClientHelloOuter. ClientHelloOuter handshakes
// are not authenticated for the name that can learn the Channel ID.
@@ -1644,7 +1644,7 @@ static bool ext_channel_id_parse_serverhello(SSL_HANDSHAKE *hs,
static bool ext_channel_id_parse_clienthello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (contents == nullptr || !hs->config->channel_id_enabled ||
SSL_is_dtls(ssl)) {
return true;
@@ -1679,7 +1679,7 @@ static bool ext_channel_id_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
static bool ext_srtp_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
const STACK_OF(SRTP_PROTECTION_PROFILE) *profiles =
SSL_get_srtp_profiles(ssl);
if (profiles == nullptr || //
@@ -1711,7 +1711,7 @@ static bool ext_srtp_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
static bool ext_srtp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (contents == nullptr) {
return true;
}
@@ -1754,7 +1754,7 @@ static bool ext_srtp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
static bool ext_srtp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// DTLS-SRTP is only defined for DTLS.
if (contents == nullptr || !SSL_is_dtls(ssl)) {
return true;
@@ -1795,7 +1795,7 @@ static bool ext_srtp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
}
static bool ext_srtp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl->s3->srtp_profile == nullptr) {
return true;
}
@@ -1880,7 +1880,7 @@ static bool ext_ec_point_parse_clienthello(SSL_HANDSHAKE *hs,
}
static bool ext_ec_point_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
return true;
}
@@ -1902,7 +1902,7 @@ static bool ext_ec_point_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
// https://tools.ietf.org/html/rfc8446#section-4.2.11
bool ssl_setup_pre_shared_keys(SSL_HANDSHAKE *hs) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
if (hs->max_version < TLS1_3_VERSION) {
return true;
}
@@ -1977,7 +1977,7 @@ static bool ext_pre_shared_key_add_clienthello(const SSL_HANDSHAKE *hs,
CBB *out_extensions,
size_t *out_psk_len,
ssl_client_hello_type_t type) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
if (!should_offer_psk(hs, type)) {
*out_psk_len = 0;
// Discard empty extensions blocks.
@@ -2280,7 +2280,7 @@ static bool ext_psk_key_exchange_modes_parse_clienthello(SSL_HANDSHAKE *hs,
static bool ext_early_data_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
// The second ClientHello never offers early data, and we must have already
// filled in `early_data_reason` by this point.
if (ssl->s3->used_hello_retry_request) {
@@ -2308,7 +2308,7 @@ static bool ext_early_data_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
static bool ext_early_data_parse_serverhello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (contents == nullptr) {
if (hs->early_data_offered && !ssl->s3->used_hello_retry_request) {
ssl->s3->early_data_reason = ssl->s3->session_reused
@@ -2346,7 +2346,7 @@ static bool ext_early_data_parse_serverhello(SSL_HANDSHAKE *hs,
static bool ext_early_data_parse_clienthello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (contents == nullptr || ssl_protocol_version(ssl) < TLS1_3_VERSION) {
return true;
}
@@ -2380,7 +2380,7 @@ static bool ext_early_data_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
// https://tools.ietf.org/html/rfc8446#section-4.2.8
bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
hs->key_shares.clear();
hs->key_share_bytes.Reset();
@@ -2644,7 +2644,7 @@ bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
static bool ext_supported_versions_add_clienthello(
const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
ssl_client_hello_type_t type) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
if (hs->max_version <= TLS1_2_VERSION) {
return true;
}
@@ -2713,7 +2713,7 @@ static bool ext_supported_groups_add_clienthello(const SSL_HANDSHAKE *hs,
CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
// In PAKE mode, supported_groups and key_share are not used.
if (hs->pake_prover != nullptr) {
return true;
@@ -2884,7 +2884,7 @@ static bool ext_server_padding_parse_clienthello(SSL_HANDSHAKE *hs,
}
static bool ext_server_padding_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl_protocol_version(ssl) < TLS1_3_VERSION ||
!hs->client_requested_server_padding_size ||
!hs->config->server_padding_enabled) {
@@ -2997,7 +2997,7 @@ static bool ext_trust_anchors_parse_clienthello(SSL_HANDSHAKE *hs,
}
static bool ext_trust_anchors_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl_protocol_version(ssl) < TLS1_3_VERSION) {
return true;
}
@@ -3131,7 +3131,7 @@ static bool ext_quic_transport_params_add_clienthello_legacy(
static bool ext_quic_transport_params_parse_serverhello_impl(
SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents,
bool used_legacy_codepoint) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (contents == nullptr) {
if (used_legacy_codepoint != hs->config->quic_use_legacy_codepoint) {
// Silently ignore because we expect the other QUIC codepoint.
@@ -3167,7 +3167,7 @@ static bool ext_quic_transport_params_parse_serverhello_legacy(
static bool ext_quic_transport_params_parse_clienthello_impl(
SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents,
bool used_legacy_codepoint) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!contents) {
if (!SSL_is_quic(ssl)) {
if (hs->config->quic_transport_params.empty()) {
@@ -3633,7 +3633,7 @@ static bool ext_alps_add_clienthello_impl(const SSL_HANDSHAKE *hs, CBB *out,
CBB *out_compressible,
ssl_client_hello_type_t type,
bool use_new_codepoint) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
if ( // ALPS requires TLS 1.3.
hs->max_version < TLS1_3_VERSION ||
// Do not offer ALPS without ALPN.
@@ -3690,7 +3690,7 @@ static bool ext_alps_add_clienthello_old(const SSL_HANDSHAKE *hs, CBB *out,
static bool ext_alps_parse_serverhello_impl(SSL_HANDSHAKE *hs,
uint8_t *out_alert, CBS *contents,
bool use_new_codepoint) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (contents == nullptr) {
return true;
}
@@ -3732,7 +3732,7 @@ static bool ext_alps_parse_serverhello_old(SSL_HANDSHAKE *hs,
static bool ext_alps_add_serverhello_impl(SSL_HANDSHAKE *hs, CBB *out,
bool use_new_codepoint) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// If early data is accepted, we omit the ALPS extension. It is implicitly
// carried over from the previous connection.
if (hs->new_session == nullptr ||
@@ -3774,7 +3774,7 @@ static bool ext_alps_add_serverhello_old(SSL_HANDSHAKE *hs, CBB *out) {
bool ssl_negotiate_alps(SSL_HANDSHAKE *hs, uint8_t *out_alert,
const SSL_CLIENT_HELLO *client_hello) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl->s3->alpn_selected.empty()) {
return true;
}
@@ -4366,7 +4366,7 @@ static bool ssl_add_clienthello_tlsext_inner(SSL_HANDSHAKE *hs, CBB *out,
// are written to `extensions` and copied to `extensions_encoded`. Compressed
// extensions are buffered in `compressed` and written to the end. (ECH can
// only compress contiguous extensions.)
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
bssl::ScopedCBB compressed, outer_extensions;
CBB extensions, extensions_encoded;
if (!CBB_add_u16_length_prefixed(out, &extensions) ||
@@ -4482,7 +4482,7 @@ bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, CBB *out_encoded,
// header.
size_t msg_len = SSL3_HM_HEADER_LENGTH + CBB_len(out);
assert(out_encoded == nullptr); // Only ClientHelloInner needs two outputs.
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
CBB extensions;
if (!CBB_add_u16_length_prefixed(out, &extensions)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -4590,7 +4590,7 @@ bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, CBB *out_encoded,
}
bool ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
CBB extensions;
if (!CBB_add_u16_length_prefixed(out, &extensions)) {
goto err;
@@ -4690,7 +4690,7 @@ static bool ssl_scan_clienthello_tlsext(SSL_HANDSHAKE *hs,
bool ssl_parse_clienthello_tlsext(SSL_HANDSHAKE *hs,
const SSL_CLIENT_HELLO *client_hello) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
int alert = SSL_AD_DECODE_ERROR;
if (!ssl_scan_clienthello_tlsext(hs, client_hello, &alert)) {
ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
@@ -4776,7 +4776,7 @@ static bool ssl_scan_serverhello_tlsext(SSL_HANDSHAKE *hs, const CBS *cbs,
}
static bool ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
int ret = SSL_TLSEXT_ERR_NOACK;
int al = SSL_AD_UNRECOGNIZED_NAME;
if (ssl->ctx->servername_callback != nullptr) {
@@ -4802,7 +4802,7 @@ static bool ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs) {
}
static bool ssl_check_serverhello_tlsext(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// ALPS and ALPN have a dependency between each other, so we defer checking
// consistency to after the callbacks run.
if (hs->new_session != nullptr && hs->new_session->has_application_settings) {
@@ -4832,7 +4832,7 @@ static bool ssl_check_serverhello_tlsext(SSL_HANDSHAKE *hs) {
}
bool ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, const CBS *cbs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
int alert = SSL_AD_DECODE_ERROR;
if (!ssl_scan_serverhello_tlsext(hs, cbs, &alert)) {
ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
@@ -4995,7 +4995,7 @@ enum ssl_ticket_aead_result_t ssl_process_ticket(
SSL_HANDSHAKE *hs, UniquePtr<SSL_SESSION> *out_session,
bool *out_renew_ticket, Span<const uint8_t> ticket,
Span<const uint8_t> session_id, bool save_ticket) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
*out_renew_ticket = false;
out_session->reset();
@@ -5122,7 +5122,7 @@ bool tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey) {
bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs,
const SSLCredential *cred, uint16_t *out) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!cred->UsesPrivateKey()) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
return false;
@@ -5175,7 +5175,7 @@ bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs,
}
bool tls1_verify_channel_id(SSL_HANDSHAKE *hs, const SSLMessage &msg) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// A Channel ID handshake message is structured to contain multiple
// extensions, but the only one that can be present is Channel ID.
uint16_t extension_type;
@@ -5278,7 +5278,7 @@ bool tls1_write_channel_id(SSL_HANDSHAKE *hs, CBB *cbb) {
}
bool tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
Array<uint8_t> msg;
if (!tls13_get_cert_verify_signature_input(hs, &msg,
@@ -5319,7 +5319,7 @@ bool tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len) {
}
bool tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// This function should never be called for a resumed session because the
// handshake hashes that we wish to record are for the original, full
// handshake.
@@ -5366,7 +5366,7 @@ using namespace bssl;
int SSL_parse_client_hello(const SSL *ssl, SSL_CLIENT_HELLO *out,
const uint8_t *in, size_t len) {
CBS cbs = Span(in, len);
if (!ssl_parse_client_hello_with_trailing_data(ssl, &cbs, out)) {
if (!ssl_parse_client_hello_with_trailing_data(FromOpaque(ssl), &cbs, out)) {
return 0;
}
if (CBS_len(&cbs) != 0) {
+66 -51
View File
@@ -80,8 +80,9 @@ static bool serialize_features(CBB *out) {
bool SSL_serialize_handoff(const SSL *ssl, CBB *out,
SSL_CLIENT_HELLO *out_hello) {
const SSL3_STATE *const s3 = ssl->s3;
if (!ssl->server || //
const auto *ssl_impl = FromOpaque(ssl);
const SSL3_STATE *const s3 = ssl_impl->s3;
if (!ssl_impl->server || //
s3->hs == nullptr || //
s3->rwstate != SSL_ERROR_HANDOFF) {
return false;
@@ -98,8 +99,8 @@ bool SSL_serialize_handoff(const SSL *ssl, CBB *out,
reinterpret_cast<uint8_t *>(s3->hs_buf->data),
s3->hs_buf->length) ||
!serialize_features(&seq) || !CBB_flush(out) ||
!ssl->method->get_message(ssl, &msg) ||
!SSL_parse_client_hello(ssl, out_hello, CBS_data(&msg.body),
!ssl_impl->method->get_message(ssl_impl, &msg) ||
!SSL_parse_client_hello(ssl_impl, out_hello, CBS_data(&msg.body),
CBS_len(&msg.body))) {
return false;
}
@@ -108,8 +109,10 @@ bool SSL_serialize_handoff(const SSL *ssl, CBB *out,
}
bool SSL_decline_handoff(SSL *ssl) {
const SSL3_STATE *const s3 = ssl->s3;
if (!ssl->server || s3->hs == nullptr || s3->rwstate != SSL_ERROR_HANDOFF) {
auto *ssl_impl = FromOpaque(ssl);
const SSL3_STATE *const s3 = ssl_impl->s3;
if (!ssl_impl->server || s3->hs == nullptr ||
s3->rwstate != SSL_ERROR_HANDOFF) {
return false;
}
@@ -121,7 +124,7 @@ bool SSL_decline_handoff(SSL *ssl) {
// (possibly) reconfigures `ssl` to disallow the negotiation of features whose
// support has not been indicated. (This prevents the handshake from
// committing to features that are not supported on the handoff/handback side.)
static bool apply_remote_features(SSL *ssl, CBS *in) {
static bool apply_remote_features(SSLImpl *ssl, CBS *in) {
CBS ciphers;
if (!CBS_get_asn1(in, &ciphers, CBS_ASN1_OCTETSTRING)) {
return false;
@@ -267,13 +270,14 @@ static bool apply_remote_features(SSL *ssl, CBS *in) {
// uses_disallowed_feature returns true iff `ssl` enables a feature that
// disqualifies it for split handshakes.
static bool uses_disallowed_feature(const SSL *ssl) {
static bool uses_disallowed_feature(const SSLImpl *ssl) {
return ssl->method->is_dtls || !ssl->config->cert->credentials.empty() ||
ssl->config->quic_transport_params.size() > 0 || ssl->ctx->ech_keys;
}
bool SSL_apply_handoff(SSL *ssl, Span<const uint8_t> handoff) {
if (uses_disallowed_feature(ssl)) {
auto *ssl_impl = FromOpaque(ssl);
if (uses_disallowed_feature(ssl_impl)) {
return false;
}
@@ -288,13 +292,13 @@ bool SSL_apply_handoff(SSL *ssl, Span<const uint8_t> handoff) {
CBS transcript, hs_buf;
if (!CBS_get_asn1(&seq, &transcript, CBS_ASN1_OCTETSTRING) ||
!CBS_get_asn1(&seq, &hs_buf, CBS_ASN1_OCTETSTRING) ||
!apply_remote_features(ssl, &seq)) {
!apply_remote_features(ssl_impl, &seq)) {
return false;
}
SSL_set_accept_state(ssl);
SSL_set_accept_state(ssl_impl);
SSL3_STATE *const s3 = ssl->s3;
SSL3_STATE *const s3 = ssl_impl->s3;
s3->v2_hello_done = true;
s3->has_message = true;
@@ -314,10 +318,11 @@ bool SSL_apply_handoff(SSL *ssl, Span<const uint8_t> handoff) {
}
bool SSL_serialize_handback(const SSL *ssl, CBB *out) {
if (!ssl->server || uses_disallowed_feature(ssl)) {
const auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->server || uses_disallowed_feature(ssl_impl)) {
return false;
}
const SSL3_STATE *const s3 = ssl->s3;
const SSL3_STATE *const s3 = ssl_impl->s3;
SSL_HANDSHAKE *const hs = s3->hs.get();
handback_t type;
switch (hs->state) {
@@ -353,7 +358,7 @@ bool SSL_serialize_handback(const SSL *ssl, CBB *out) {
const uint8_t *write_iv = nullptr;
if ((type == handback_after_session_resumption ||
type == handback_after_handshake) &&
ssl->s3->version == TLS1_VERSION &&
ssl_impl->s3->version == TLS1_VERSION &&
SSL_CIPHER_is_block_cipher(s3->aead_write_ctx->cipher()) &&
!s3->aead_write_ctx->GetIV(&write_iv, &write_iv_len)) {
return false;
@@ -361,7 +366,7 @@ bool SSL_serialize_handback(const SSL *ssl, CBB *out) {
size_t read_iv_len = 0;
const uint8_t *read_iv = nullptr;
if (type == handback_after_handshake && //
ssl->s3->version == TLS1_VERSION && //
ssl_impl->s3->version == TLS1_VERSION && //
SSL_CIPHER_is_block_cipher(s3->aead_read_ctx->cipher()) && //
!s3->aead_read_ctx->GetIV(&read_iv, &read_iv_len)) {
return false;
@@ -373,7 +378,8 @@ bool SSL_serialize_handback(const SSL *ssl, CBB *out) {
if (type == handback_tls13) {
session = hs->new_session.get();
} else {
session = s3->session_reused ? ssl->session.get() : hs->new_session.get();
session =
s3->session_reused ? ssl_impl->session.get() : hs->new_session.get();
}
uint8_t read_sequence[8], write_sequence[8];
CRYPTO_store_u64_be(read_sequence, s3->read_sequence);
@@ -428,7 +434,7 @@ bool SSL_serialize_handback(const SSL *ssl, CBB *out) {
if (type == handback_tls13) {
early_data_t early_data;
// Check early data invariants.
if (ssl->enable_early_data ==
if (ssl_impl->enable_early_data ==
(s3->early_data_reason == ssl_early_data_disabled)) {
return false;
}
@@ -494,12 +500,13 @@ static bool CopyExact(Span<uint8_t> out, const CBS *in) {
}
bool SSL_apply_handback(SSL *ssl, Span<const uint8_t> handback) {
if (ssl->do_handshake != nullptr || //
ssl->method->is_dtls) {
auto *ssl_impl = FromOpaque(ssl);
if (ssl_impl->do_handshake != nullptr || //
ssl_impl->method->is_dtls) {
return false;
}
SSL3_STATE *const s3 = ssl->s3;
SSL3_STATE *const s3 = ssl_impl->s3;
uint64_t handback_version, unused_token_binding_param, cipher, type_u64,
alps_codepoint;
@@ -539,19 +546,19 @@ bool SSL_apply_handback(SSL *ssl, Span<const uint8_t> handback) {
return false;
}
s3->hs = ssl_handshake_new(ssl);
s3->hs = ssl_handshake_new(ssl_impl);
if (!s3->hs) {
return false;
}
SSL_HANDSHAKE *const hs = s3->hs.get();
if (!session_reused || type == handback_tls13) {
hs->new_session =
SSL_SESSION_parse(&seq, ssl->ctx->x509_method, ssl->ctx->pool.get());
hs->new_session = SSL_SESSION_parse(&seq, ssl_impl->ctx->x509_method,
ssl_impl->ctx->pool.get());
session = hs->new_session.get();
} else {
ssl->session =
SSL_SESSION_parse(&seq, ssl->ctx->x509_method, ssl->ctx->pool.get());
session = ssl->session.get();
ssl_impl->session = SSL_SESSION_parse(&seq, ssl_impl->ctx->x509_method,
ssl_impl->ctx->pool.get());
session = ssl_impl->session.get();
}
// Split handshakes only support X.509 certificates.
@@ -639,7 +646,8 @@ bool SSL_apply_handback(SSL *ssl, Span<const uint8_t> handback) {
s3->early_data_reason =
static_cast<ssl_early_data_reason_t>(early_data_reason);
ssl->enable_early_data = s3->early_data_reason != ssl_early_data_disabled;
ssl_impl->enable_early_data =
s3->early_data_reason != ssl_early_data_disabled;
s3->skip_early_data = false;
s3->early_data_accepted = false;
hs->early_data_offered = false;
@@ -667,15 +675,17 @@ bool SSL_apply_handback(SSL *ssl, Span<const uint8_t> handback) {
s3->early_data_reason = ssl_early_data_protocol_version;
}
ssl->s3->version = session->ssl_version;
if (!ssl_method_supports_version(ssl->method, ssl->s3->version) ||
ssl_impl->s3->version = session->ssl_version;
if (!ssl_method_supports_version(ssl_impl->method, ssl_impl->s3->version) ||
session->cipher != hs->new_cipher ||
ssl_protocol_version(ssl) < SSL_CIPHER_get_min_version(session->cipher) ||
SSL_CIPHER_get_max_version(session->cipher) < ssl_protocol_version(ssl)) {
ssl_protocol_version(ssl_impl) <
SSL_CIPHER_get_min_version(session->cipher) ||
SSL_CIPHER_get_max_version(session->cipher) <
ssl_protocol_version(ssl_impl)) {
return false;
}
ssl->do_handshake = ssl_server_handshake;
ssl->server = true;
ssl_impl->do_handshake = ssl_server_handshake;
ssl_impl->server = true;
switch (type) {
case handback_after_session_resumption:
hs->state = state12_read_change_cipher_spec;
@@ -725,7 +735,8 @@ bool SSL_apply_handback(SSL *ssl, Span<const uint8_t> handback) {
if (type != handback_after_handshake &&
(!hs->transcript.Init() ||
!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) ||
!hs->transcript.InitHash(ssl_protocol_version(ssl_impl),
hs->new_cipher) ||
!hs->transcript.Update(transcript))) {
return false;
}
@@ -749,7 +760,7 @@ bool SSL_apply_handback(SSL *ssl, Span<const uint8_t> handback) {
case handback_after_session_resumption:
// The write keys are installed after server Finished, but the client
// keys must wait for ChangeCipherSpec.
if (!tls1_configure_aead(ssl, evp_aead_seal, &key_block, session,
if (!tls1_configure_aead(ssl_impl, evp_aead_seal, &key_block, session,
write_iv)) {
return false;
}
@@ -759,9 +770,9 @@ bool SSL_apply_handback(SSL *ssl, Span<const uint8_t> handback) {
break;
case handback_after_handshake:
// The handshake is complete, so both keys are installed.
if (!tls1_configure_aead(ssl, evp_aead_seal, &key_block, session,
if (!tls1_configure_aead(ssl_impl, evp_aead_seal, &key_block, session,
write_iv) ||
!tls1_configure_aead(ssl, evp_aead_open, &key_block, session,
!tls1_configure_aead(ssl_impl, evp_aead_open, &key_block, session,
read_iv)) {
return false;
}
@@ -770,8 +781,8 @@ bool SSL_apply_handback(SSL *ssl, Span<const uint8_t> handback) {
// After server Finished, the application write keys are installed, but
// none of the read keys. The read keys are installed in the state machine
// immediately after processing handback.
if (!tls13_set_traffic_key(ssl, ssl_encryption_application, evp_aead_seal,
hs->new_session.get(),
if (!tls13_set_traffic_key(ssl_impl, ssl_encryption_application,
evp_aead_seal, hs->new_session.get(),
hs->server_traffic_secret_0)) {
return false;
}
@@ -821,7 +832,8 @@ int SSL_request_handshake_hints(SSL *ssl, const uint8_t *client_hello,
size_t client_hello_len,
const uint8_t *capabilities,
size_t capabilities_len) {
if (SSL_is_dtls(ssl) || ssl->s3->hs == nullptr) {
auto *ssl_impl = FromOpaque(ssl);
if (SSL_is_dtls(ssl_impl) || ssl_impl->s3->hs == nullptr) {
OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -832,22 +844,23 @@ int SSL_request_handshake_hints(SSL *ssl, const uint8_t *client_hello,
MakeUnique<SSL_HANDSHAKE_HINTS>();
if (pending_hints == nullptr ||
!CBS_get_asn1(&cbs, &seq, CBS_ASN1_SEQUENCE) ||
!apply_remote_features(ssl, &seq)) {
!apply_remote_features(ssl_impl, &seq)) {
return 0;
}
SSL3_STATE *const s3 = ssl->s3;
SSL3_STATE *const s3 = ssl_impl->s3;
s3->v2_hello_done = true;
s3->has_message = true;
Array<uint8_t> client_hello_msg;
ScopedCBB client_hello_cbb;
CBB client_hello_body;
if (!ssl->method->init_message(ssl, client_hello_cbb.get(),
&client_hello_body, SSL3_MT_CLIENT_HELLO) ||
if (!ssl_impl->method->init_message(ssl_impl, client_hello_cbb.get(),
&client_hello_body,
SSL3_MT_CLIENT_HELLO) ||
!CBB_add_bytes(&client_hello_body, client_hello, client_hello_len) ||
!ssl->method->finish_message(ssl, client_hello_cbb.get(),
&client_hello_msg)) {
!ssl_impl->method->finish_message(ssl_impl, client_hello_cbb.get(),
&client_hello_msg)) {
return 0;
}
@@ -936,8 +949,9 @@ static const CBS_ASN1_TAG kRenewTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 9;
static const CBS_ASN1_TAG kIgnoreTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 10;
int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) {
const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
if (!ssl->server || hs == nullptr || hs->pending_hints == nullptr) {
const auto *ssl_impl = FromOpaque(ssl);
const SSL_HANDSHAKE *hs = ssl_impl->s3->hs.get();
if (!ssl_impl->server || hs == nullptr || hs->pending_hints == nullptr) {
OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -1064,7 +1078,8 @@ static bool get_optional_implicit_null(CBS *cbs, bool *out_present,
}
int SSL_set_handshake_hints(SSL *ssl, const uint8_t *hints, size_t hints_len) {
if (SSL_is_dtls(ssl) || ssl->s3->hs == nullptr) {
auto *ssl_impl = FromOpaque(ssl);
if (SSL_is_dtls(ssl_impl) || ssl_impl->s3->hs == nullptr) {
OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -1195,6 +1210,6 @@ int SSL_set_handshake_hints(SSL *ssl, const uint8_t *hints, size_t hints_len) {
return 0;
}
ssl->s3->hs->provided_hints = std::move(hints_obj);
ssl_impl->s3->hs->provided_hints = std::move(hints_obj);
return 1;
}
+10 -10
View File
@@ -31,7 +31,7 @@
BSSL_NAMESPACE_BEGIN
SSL_HANDSHAKE::SSL_HANDSHAKE(SSL *ssl_arg)
SSL_HANDSHAKE::SSL_HANDSHAKE(SSLImpl *ssl_arg)
: ssl(ssl_arg),
transcript(SSL_is_dtls(ssl_arg)),
inner_transcript(SSL_is_dtls(ssl_arg)),
@@ -99,7 +99,7 @@ bool SSL_HANDSHAKE::GetClientHello(SSLMessage *out_msg,
return true;
}
UniquePtr<SSL_HANDSHAKE> ssl_handshake_new(SSL *ssl) {
UniquePtr<SSL_HANDSHAKE> ssl_handshake_new(SSLImpl *ssl) {
UniquePtr<SSL_HANDSHAKE> hs = MakeUnique<SSL_HANDSHAKE>(ssl);
if (!hs || !hs->transcript.Init()) {
return nullptr;
@@ -112,7 +112,7 @@ UniquePtr<SSL_HANDSHAKE> ssl_handshake_new(SSL *ssl) {
return hs;
}
bool ssl_check_message_type(SSL *ssl, const SSLMessage &msg, int type) {
bool ssl_check_message_type(SSLImpl *ssl, const SSLMessage &msg, int type) {
if (msg.type != type) {
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
@@ -123,7 +123,7 @@ bool ssl_check_message_type(SSL *ssl, const SSLMessage &msg, int type) {
return true;
}
bool ssl_add_message_cbb(SSL *ssl, CBB *cbb) {
bool ssl_add_message_cbb(SSLImpl *ssl, CBB *cbb) {
Array<uint8_t> msg;
if (!ssl->method->finish_message(ssl, cbb, &msg) ||
!ssl->method->add_message(ssl, std::move(msg))) {
@@ -133,7 +133,7 @@ bool ssl_add_message_cbb(SSL *ssl, CBB *cbb) {
return true;
}
size_t ssl_max_handshake_message_len(const SSL *ssl) {
size_t ssl_max_handshake_message_len(const SSLImpl *ssl) {
// kMaxMessageLen is the default maximum message size for handshakes which do
// not accept peer certificate chains.
static const size_t kMaxMessageLen = 16384;
@@ -265,7 +265,7 @@ static bool peer_certificates_equal(const SSL_SESSION *session,
}
enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
const SSL_SESSION *prev_session = ssl->s3->established_session.get();
if (prev_session != nullptr) {
// If renegotiating, the server must not change the server certificate. See
@@ -349,7 +349,7 @@ enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs) {
// 4. We only support custom verify callbacks.
enum ssl_verify_result_t ssl_reverify_peer_cert(SSL_HANDSHAKE *hs,
bool send_alert) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
assert(ssl->s3->established_session == nullptr);
assert(hs->config->verify_mode != SSL_VERIFY_NONE);
@@ -392,7 +392,7 @@ uint16_t ssl_get_grease_value(const SSL_HANDSHAKE *hs,
}
enum ssl_hs_wait_t ssl_get_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_message;
@@ -446,7 +446,7 @@ enum ssl_hs_wait_t ssl_get_finished(SSL_HANDSHAKE *hs) {
}
bool ssl_send_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
const SSL_SESSION *session = ssl_handshake_session(hs);
uint8_t finished_buf[EVP_MAX_MD_SIZE];
@@ -524,7 +524,7 @@ const SSL_SESSION *ssl_handshake_session(const SSL_HANDSHAKE *hs) {
}
int ssl_run_handshake(SSL_HANDSHAKE *hs, bool *out_early_return) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
for (;;) {
// If a timeout during the handshake triggered a DTLS ACK or retransmit, we
// resolve that first. E.g., if `ssl_hs_private_key_operation` is slow, the
+23 -23
View File
@@ -93,7 +93,7 @@ static bool ssl_add_tls13_cipher(CBB *cbb, uint16_t cipher_id,
static bool ssl_write_client_cipher_list(const SSL_HANDSHAKE *hs, CBB *out,
ssl_client_hello_type_t type) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
uint32_t mask_a, mask_k;
ssl_get_client_disabled(hs, &mask_a, &mask_k);
@@ -182,7 +182,7 @@ bool ssl_write_client_hello_without_extensions(const SSL_HANDSHAKE *hs,
CBB *cbb,
ssl_client_hello_type_t type,
bool empty_session_id) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
CBB child;
if (!CBB_add_u16(cbb, hs->client_version) ||
!CBB_add_bytes(cbb,
@@ -217,7 +217,7 @@ bool ssl_write_client_hello_without_extensions(const SSL_HANDSHAKE *hs,
}
bool ssl_add_client_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
ScopedCBB cbb;
CBB body;
ssl_client_hello_type_t type = hs->selected_ech_config
@@ -274,7 +274,7 @@ static bool parse_server_version(const SSL_HANDSHAKE *hs, uint16_t *out_version,
// offer early data, and some other reason code otherwise.
static ssl_early_data_reason_t should_offer_early_data(
const SSL_HANDSHAKE *hs) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
assert(!ssl->server);
if (!ssl->enable_early_data) {
return ssl_early_data_disabled;
@@ -351,7 +351,7 @@ bool ssl_accepts_server_certificate_auth(const SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_start_connect(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
ssl_do_info_callback(ssl, SSL_CB_HANDSHAKE_START, 1);
// `session_reused` must be reset in case this is a renegotiation.
@@ -455,7 +455,7 @@ static enum ssl_hs_wait_t do_start_connect(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_enter_early_data(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!hs->early_data_offered) {
hs->state = state_read_server_hello;
return ssl_hs_ok;
@@ -474,7 +474,7 @@ static enum ssl_hs_wait_t do_enter_early_data(SSL_HANDSHAKE *hs) {
static enum ssl_hs_wait_t do_early_reverify_server_certificate(
SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl->ctx->reverify_on_resume) {
// Don't send an alert on error. The alert would be in the clear, which the
// server is not expecting anyway. Alerts in between ClientHello and
@@ -516,7 +516,7 @@ static enum ssl_hs_wait_t do_early_reverify_server_certificate(
static bool handle_hello_verify_request(SSL_HANDSHAKE *hs,
const SSLMessage &msg) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
assert(SSL_is_dtls(ssl));
assert(msg.type == DTLS1_MT_HELLO_VERIFY_REQUEST);
assert(!hs->received_hello_verify_request);
@@ -580,7 +580,7 @@ bool ssl_parse_server_hello(ParsedServerHello *out, uint8_t *out_alert,
}
static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_server_hello;
@@ -841,7 +841,7 @@ static enum ssl_hs_wait_t do_tls13(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_server_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
hs->state = state_read_certificate_status;
@@ -901,7 +901,7 @@ static enum ssl_hs_wait_t do_read_server_certificate(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_certificate_status(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!hs->certificate_status_expected) {
hs->state = state_verify_server_certificate;
@@ -987,7 +987,7 @@ static enum ssl_hs_wait_t do_reverify_server_certificate(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_message;
@@ -1162,7 +1162,7 @@ static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
hs->state = state_read_server_hello_done;
@@ -1234,7 +1234,7 @@ static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_server_hello_done(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_message;
@@ -1306,7 +1306,7 @@ static bool check_credential(SSL_HANDSHAKE *hs, const SSLCredential *cred,
}
static enum ssl_hs_wait_t do_send_client_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// The peer didn't request a certificate.
if (!hs->cert_request) {
@@ -1382,7 +1382,7 @@ static_assert(sizeof(size_t) >= sizeof(unsigned),
"size_t is smaller than unsigned");
static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
ScopedCBB cbb;
CBB body;
if (!ssl->method->init_message(ssl, cbb.get(), &body,
@@ -1538,7 +1538,7 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!hs->cert_request || hs->credential == nullptr) {
hs->state = state_send_client_finished;
@@ -1595,7 +1595,7 @@ static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_send_client_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
hs->can_release_private_key = true;
if (!ssl->method->add_change_cipher_spec(ssl) ||
!tls1_change_cipher_state(hs, evp_aead_seal)) {
@@ -1641,7 +1641,7 @@ static enum ssl_hs_wait_t do_send_client_finished(SSL_HANDSHAKE *hs) {
}
static bool can_false_start(const SSL_HANDSHAKE *hs) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
// False Start bypasses the Finished check's downgrade protection. This can
// enable attacks where we send data under weaker settings than supported
@@ -1680,7 +1680,7 @@ static bool can_false_start(const SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_finish_flight(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl->session != nullptr) {
hs->state = state_finish_client_handshake;
return ssl_hs_ok;
@@ -1708,7 +1708,7 @@ static enum ssl_hs_wait_t do_finish_flight(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_session_ticket(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!hs->ticket_expected) {
hs->state = state_process_change_cipher_spec;
@@ -1786,7 +1786,7 @@ static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_server_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
enum ssl_hs_wait_t wait = ssl_get_finished(hs);
if (wait != ssl_hs_ok) {
return wait;
@@ -1802,7 +1802,7 @@ static enum ssl_hs_wait_t do_read_server_finished(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_finish_client_handshake(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl->s3->ech_status == ssl_ech_rejected) {
// Release the retry configs.
hs->ech_authenticated_reject = true;
+20 -20
View File
@@ -65,7 +65,7 @@ bool ssl_client_cipher_list_contains_cipher(
static bool negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert,
const SSL_CLIENT_HELLO *client_hello) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
assert(ssl->s3->version == 0);
CBS supported_versions, versions;
if (ssl_client_hello_get_extension(client_hello, &supported_versions,
@@ -158,7 +158,7 @@ static UniquePtr<STACK_OF(SSL_CIPHER)> ssl_parse_client_cipher_list(
static const SSL_CIPHER *choose_cipher(SSL_HANDSHAKE *hs,
const STACK_OF(SSL_CIPHER) *client_pref,
uint32_t mask_k, uint32_t mask_a) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
const STACK_OF(SSL_CIPHER) *prio, *allow;
// in_group_flags will either be NULL, or will point to an array of bytes
// which indicate equal-preference groups in the `prio` stack. See the
@@ -404,7 +404,7 @@ static bool is_probably_jdk11_with_tls13(const SSL_CLIENT_HELLO *client_hello) {
static bool decrypt_ech(SSL_HANDSHAKE *hs, uint8_t *out_alert,
const SSL_CLIENT_HELLO *client_hello) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
CBS body;
if (!ssl_client_hello_get_extension(client_hello, &body,
TLSEXT_TYPE_encrypted_client_hello)) {
@@ -482,7 +482,7 @@ static bool decrypt_ech(SSL_HANDSHAKE *hs, uint8_t *out_alert,
static bool extract_sni(SSL_HANDSHAKE *hs, uint8_t *out_alert,
const SSL_CLIENT_HELLO *client_hello) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
CBS sni;
if (!ssl_client_hello_get_extension(client_hello, &sni,
TLSEXT_TYPE_server_name)) {
@@ -532,7 +532,7 @@ static bool extract_sni(SSL_HANDSHAKE *hs, uint8_t *out_alert,
}
static enum ssl_hs_wait_t do_read_client_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
@@ -588,7 +588,7 @@ static enum ssl_hs_wait_t do_read_client_hello(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_client_hello_after_ech(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg_unused;
SSL_CLIENT_HELLO client_hello;
@@ -674,7 +674,7 @@ static enum ssl_hs_wait_t do_read_client_hello_after_ech(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_cert_callback(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// Call `cert_cb` to update server certificates if required.
if (hs->config->cert->cert_cb != nullptr) {
@@ -733,7 +733,7 @@ static enum ssl_hs_wait_t do_tls13(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
SSL_CLIENT_HELLO client_hello;
if (!hs->GetClientHello(&msg, &client_hello)) {
@@ -913,7 +913,7 @@ static void copy_suffix(Span<uint8_t> out, Span<const uint8_t> in) {
}
static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// We only accept ChannelIDs on connections with ECDHE in order to avoid a
// known attack while we fix ChannelID itself.
@@ -1003,7 +1003,7 @@ static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
ScopedCBB cbb;
if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
@@ -1114,7 +1114,7 @@ static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_send_server_key_exchange(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (hs->server_params.size() == 0) {
hs->state = state12_send_server_hello_done;
@@ -1184,7 +1184,7 @@ static enum ssl_hs_wait_t do_send_server_key_exchange(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_send_server_hello_done(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (hs->pending_hints != nullptr) {
return ssl_hs_hints_ready;
}
@@ -1221,7 +1221,7 @@ static enum ssl_hs_wait_t do_send_server_hello_done(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (hs->handback && hs->new_cipher->algorithm_mkey == SSL_kECDHE) {
return ssl_hs_handback;
@@ -1317,7 +1317,7 @@ static enum ssl_hs_wait_t do_verify_client_certificate(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_client_key_exchange(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_message;
@@ -1532,7 +1532,7 @@ static enum ssl_hs_wait_t do_read_client_key_exchange(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_client_certificate_verify(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// Only RSA and ECDSA client certificates are supported, so a
// CertificateVerify is required if and only if there's a client certificate.
@@ -1632,7 +1632,7 @@ static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_next_proto(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!hs->next_proto_neg_seen) {
hs->state = state12_read_channel_id;
@@ -1668,7 +1668,7 @@ static enum ssl_hs_wait_t do_read_next_proto(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!hs->channel_id_negotiated) {
hs->state = state12_read_client_finished;
@@ -1692,7 +1692,7 @@ static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
enum ssl_hs_wait_t wait = ssl_get_finished(hs);
if (wait != ssl_hs_ok) {
return wait;
@@ -1716,7 +1716,7 @@ static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (hs->ticket_expected) {
const SSL_SESSION *session;
@@ -1768,7 +1768,7 @@ static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_finish_server_handshake(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (hs->handback) {
return ssl_hs_handback;
+149 -136
View File
@@ -58,6 +58,7 @@
DECLARE_OPAQUE_STRUCT(ssl_credential_st, SSLCredential)
DECLARE_OPAQUE_STRUCT(ssl_ctx_st, SSLContext)
DECLARE_OPAQUE_STRUCT(ssl_st, SSLImpl)
DECLARE_OPAQUE_STRUCT(ssl_ech_keys_st, SSLECHKeys)
BSSL_NAMESPACE_BEGIN
@@ -186,11 +187,11 @@ bool ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert,
// ssl_has_final_version returns whether `ssl` has determined the final version.
// This may be used to distinguish the predictive 0-RTT version from the final
// one.
bool ssl_has_final_version(const SSL *ssl);
bool ssl_has_final_version(const SSLImpl *ssl);
// ssl_protocol_version returns `ssl`'s protocol version. It is an error to
// call this function before the version is determined.
uint16_t ssl_protocol_version(const SSL *ssl);
uint16_t ssl_protocol_version(const SSLImpl *ssl);
// Cipher suites.
@@ -716,7 +717,7 @@ struct DTLSWriteEpoch {
//
// TODO(davidben): Expose this as part of public API once the high-level
// buffer-free APIs are available.
size_t ssl_record_prefix_len(const SSL *ssl);
size_t ssl_record_prefix_len(const SSLImpl *ssl);
enum ssl_open_record_t {
ssl_open_record_success,
@@ -749,7 +750,7 @@ enum ssl_open_record_t {
//
// On failure or fatal alert, it returns `ssl_open_record_error` and sets
// `*out_alert` to an alert to emit, or zero if no alert should be emitted.
enum ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type,
enum ssl_open_record_t tls_open_record(SSLImpl *ssl, uint8_t *out_type,
Span<uint8_t> *out, size_t *out_consumed,
uint8_t *out_alert, Span<uint8_t> in);
@@ -757,7 +758,7 @@ enum ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type,
// `ssl_open_record_partial` if `in` was empty and sets `*out_consumed` to
// zero. The caller should read one packet and try again. On success,
// `*out_number` is set to the record number of the record.
enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type,
enum ssl_open_record_t dtls_open_record(SSLImpl *ssl, uint8_t *out_type,
DTLSRecordNumber *out_number,
Span<uint8_t> *out,
size_t *out_consumed,
@@ -765,7 +766,7 @@ enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type,
// ssl_needs_record_splitting returns one if `ssl`'s current outgoing cipher
// state needs record-splitting and zero otherwise.
bool ssl_needs_record_splitting(const SSL *ssl);
bool ssl_needs_record_splitting(const SSLImpl *ssl);
// tls_seal_record seals a new record of type `type` and body `in` and writes it
// to `out`. At most `max_out` bytes will be written. It returns true on success
@@ -778,36 +779,38 @@ bool ssl_needs_record_splitting(const SSL *ssl);
// bytes to `out`.
//
// `in` and `out` may not alias.
bool tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
uint8_t type, const uint8_t *in, size_t in_len);
bool tls_seal_record(SSLImpl *ssl, uint8_t *out, size_t *out_len,
size_t max_out, uint8_t type, const uint8_t *in,
size_t in_len);
// dtls_record_header_write_len returns the length of the record header that
// will be written at `epoch`.
size_t dtls_record_header_write_len(const SSL *ssl, uint16_t epoch);
size_t dtls_record_header_write_len(const SSLImpl *ssl, uint16_t epoch);
// dtls_max_seal_overhead returns the maximum overhead, in bytes, of sealing a
// record.
size_t dtls_max_seal_overhead(const SSL *ssl, uint16_t epoch);
size_t dtls_max_seal_overhead(const SSLImpl *ssl, uint16_t epoch);
// dtls_seal_prefix_len returns the number of bytes of prefix to reserve in
// front of the plaintext when sealing a record in-place.
size_t dtls_seal_prefix_len(const SSL *ssl, uint16_t epoch);
size_t dtls_seal_prefix_len(const SSLImpl *ssl, uint16_t epoch);
// dtls_seal_max_input_len returns the maximum number of input bytes that can
// fit in a record of up to `max_out` bytes, or zero if none may fit.
size_t dtls_seal_max_input_len(const SSL *ssl, uint16_t epoch, size_t max_out);
size_t dtls_seal_max_input_len(const SSLImpl *ssl, uint16_t epoch,
size_t max_out);
// dtls_get_read_epoch and dtls_get_write_epoch return the epoch corresponding
// to `epoch` or nullptr if there is none.
DTLSReadEpoch *dtls_get_read_epoch(const SSL *ssl, uint16_t epoch);
DTLSWriteEpoch *dtls_get_write_epoch(const SSL *ssl, uint16_t epoch);
DTLSReadEpoch *dtls_get_read_epoch(const SSLImpl *ssl, uint16_t epoch);
DTLSWriteEpoch *dtls_get_write_epoch(const SSLImpl *ssl, uint16_t epoch);
// dtls_seal_record implements `tls_seal_record` for DTLS. `epoch` selects which
// epoch's cipher state to use. Unlike `tls_seal_record`, `in` and `out` may
// alias but, if they do, `in` must be exactly `dtls_seal_prefix_len` bytes
// ahead of `out`. On success, `*out_number` is set to the record number of the
// record.
bool dtls_seal_record(SSL *ssl, DTLSRecordNumber *out_number, uint8_t *out,
bool dtls_seal_record(SSLImpl *ssl, DTLSRecordNumber *out_number, uint8_t *out,
size_t *out_len, size_t max_out, uint8_t type,
const uint8_t *in, size_t in_len, uint16_t epoch);
@@ -815,7 +818,7 @@ bool dtls_seal_record(SSL *ssl, DTLSRecordNumber *out_number, uint8_t *out,
// state. It returns one of `ssl_open_record_discard`, `ssl_open_record_error`,
// `ssl_open_record_close_notify`, or `ssl_open_record_fatal_alert` as
// appropriate.
enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert,
enum ssl_open_record_t ssl_process_alert(SSLImpl *ssl, uint8_t *out_alert,
Span<const uint8_t> in);
@@ -845,12 +848,12 @@ UniquePtr<EVP_PKEY> ssl_parse_peer_subject_public_key_info(
// ssl_pkey_supports_algorithm returns whether `pkey` may be used to sign
// `sigalg`.
bool ssl_pkey_supports_algorithm(const SSL *ssl, EVP_PKEY *pkey,
bool ssl_pkey_supports_algorithm(const SSLImpl *ssl, EVP_PKEY *pkey,
uint16_t sigalg, bool is_verify);
// ssl_public_key_verify verifies that the `signature` is valid for the public
// key `pkey` and input `in`, using the signature algorithm `sigalg`.
bool ssl_public_key_verify(SSL *ssl, Span<const uint8_t> signature,
bool ssl_public_key_verify(SSLImpl *ssl, Span<const uint8_t> signature,
uint16_t sigalg, EVP_PKEY *pkey,
Span<const uint8_t> in);
@@ -959,42 +962,42 @@ extern const uint8_t kJDK11DowngradeRandom[8];
// ssl_max_handshake_message_len returns the maximum number of bytes permitted
// in a handshake message for `ssl`.
size_t ssl_max_handshake_message_len(const SSL *ssl);
size_t ssl_max_handshake_message_len(const SSLImpl *ssl);
// tls_can_accept_handshake_data returns whether `ssl` is able to accept more
// data into handshake buffer.
bool tls_can_accept_handshake_data(const SSL *ssl, uint8_t *out_alert);
bool tls_can_accept_handshake_data(const SSLImpl *ssl, uint8_t *out_alert);
// tls_has_unprocessed_handshake_data returns whether there is buffered
// handshake data that has not been consumed by `get_message`.
bool tls_has_unprocessed_handshake_data(const SSL *ssl);
bool tls_has_unprocessed_handshake_data(const SSLImpl *ssl);
// tls_append_handshake_data appends `data` to the handshake buffer. It returns
// true on success and false on allocation failure.
bool tls_append_handshake_data(SSL *ssl, Span<const uint8_t> data);
bool tls_append_handshake_data(SSLImpl *ssl, Span<const uint8_t> data);
// dtls_has_unprocessed_handshake_data behaves like
// `tls_has_unprocessed_handshake_data` for DTLS.
bool dtls_has_unprocessed_handshake_data(const SSL *ssl);
bool dtls_has_unprocessed_handshake_data(const SSLImpl *ssl);
// tls_flush_pending_hs_data flushes any handshake plaintext data.
bool tls_flush_pending_hs_data(SSL *ssl);
bool tls_flush_pending_hs_data(SSLImpl *ssl);
// dtls_clear_outgoing_messages releases all buffered outgoing messages.
void dtls_clear_outgoing_messages(SSL *ssl);
void dtls_clear_outgoing_messages(SSLImpl *ssl);
// dtls_clear_unused_write_epochs releases any write epochs that are no longer
// needed.
void dtls_clear_unused_write_epochs(SSL *ssl);
void dtls_clear_unused_write_epochs(SSLImpl *ssl);
// Callbacks.
// ssl_do_info_callback calls `ssl`'s info callback, if set.
void ssl_do_info_callback(const SSL *ssl, int type, int value);
void ssl_do_info_callback(const SSLImpl *ssl, int type, int value);
// ssl_do_msg_callback calls `ssl`'s message callback, if set.
void ssl_do_msg_callback(const SSL *ssl, int is_write, int content_type,
void ssl_do_msg_callback(const SSLImpl *ssl, int is_write, int content_type,
Span<const uint8_t> in);
@@ -1059,19 +1062,19 @@ class SSLBuffer {
//
// It is an error to call `ssl_read_buffer_extend_to` in DTLS when the buffer is
// non-empty.
int ssl_read_buffer_extend_to(SSL *ssl, size_t len);
int ssl_read_buffer_extend_to(SSLImpl *ssl, size_t len);
// ssl_handle_open_record handles the result of passing `ssl->s3->read_buffer`
// to a record-processing function. If `ret` is a success or if the caller
// should retry, it returns one and sets `*out_retry`. Otherwise, it returns <=
// 0.
int ssl_handle_open_record(SSL *ssl, bool *out_retry, ssl_open_record_t ret,
int ssl_handle_open_record(SSLImpl *ssl, bool *out_retry, ssl_open_record_t ret,
size_t consumed, uint8_t alert);
// ssl_write_buffer_flush flushes the write buffer to the transport. It returns
// one on success and <= 0 on error. For DTLS, whether or not the write
// succeeds, the write buffer will be cleared.
int ssl_write_buffer_flush(SSL *ssl);
int ssl_write_buffer_flush(SSLImpl *ssl);
// Certificate functions.
@@ -1135,7 +1138,7 @@ UniquePtr<EVP_PKEY> ssl_cert_parse_pubkey(const CBS *in);
// it returns a newly-allocated `CRYPTO_BUFFER` list and advances
// `cbs`. Otherwise, it returns nullptr and sets `*out_alert` to an alert to
// send to the peer.
UniquePtr<STACK_OF(CRYPTO_BUFFER)> SSL_parse_CA_list(SSL *ssl,
UniquePtr<STACK_OF(CRYPTO_BUFFER)> SSL_parse_CA_list(SSLImpl *ssl,
uint8_t *out_alert,
CBS *cbs);
@@ -1182,7 +1185,7 @@ bool tls13_advance_key_schedule(SSL_HANDSHAKE *hs, Span<const uint8_t> in);
// tls13_set_traffic_key sets the read or write traffic keys to
// `traffic_secret`. The version and cipher suite are determined from `session`.
// It returns true on success and false on error.
bool tls13_set_traffic_key(SSL *ssl, enum ssl_encryption_level_t level,
bool tls13_set_traffic_key(SSLImpl *ssl, enum ssl_encryption_level_t level,
enum evp_aead_direction_t direction,
const SSL_SESSION *session,
Span<const uint8_t> traffic_secret);
@@ -1197,7 +1200,8 @@ bool tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs);
// tls13_rotate_traffic_key derives the next read or write traffic secret. It
// returns true on success and false on error.
bool tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction);
bool tls13_rotate_traffic_key(SSLImpl *ssl,
enum evp_aead_direction_t direction);
// tls13_derive_application_secrets derives the initial application data traffic
// and exporter secrets based on the handshake transcripts and `master_secret`.
@@ -1209,7 +1213,7 @@ bool tls13_derive_resumption_secret(SSL_HANDSHAKE *hs);
// tls13_export_keying_material provides an exporter interface to use the
// `exporter_secret`.
bool tls13_export_keying_material(const SSL *ssl, Span<uint8_t> out,
bool tls13_export_keying_material(const SSLImpl *ssl, Span<uint8_t> out,
Span<const uint8_t> secret,
std::string_view label,
Span<const uint8_t> context);
@@ -1349,7 +1353,7 @@ enum ssl_client_hello_type_t {
//
// This function is exported for fuzzing.
OPENSSL_EXPORT bool ssl_decode_client_hello_inner(
SSL *ssl, uint8_t *out_alert, Array<uint8_t> *out_client_hello_inner,
SSLImpl *ssl, uint8_t *out_alert, Array<uint8_t> *out_client_hello_inner,
Span<const uint8_t> encoded_client_hello_inner,
const SSL_CLIENT_HELLO *client_hello_outer);
@@ -1366,7 +1370,7 @@ bool ssl_client_hello_decrypt(SSL_HANDSHAKE *hs, uint8_t *out_alert,
// ssl_ech_confirmation_signal_hello_offset returns the offset of the ECH
// confirmation signal in a ServerHello message, including the handshake header.
size_t ssl_ech_confirmation_signal_hello_offset(const SSL *ssl);
size_t ssl_ech_confirmation_signal_hello_offset(const SSLImpl *ssl);
// ssl_ech_accept_confirmation computes the server's ECH acceptance signal,
// writing it to `out`. The transcript portion is the concatenation of
@@ -1766,12 +1770,12 @@ struct SSLPAKEShare {
};
struct SSL_HANDSHAKE {
explicit SSL_HANDSHAKE(SSL *ssl);
explicit SSL_HANDSHAKE(SSLImpl *ssl);
~SSL_HANDSHAKE();
static constexpr bool kAllowUniquePtr = true;
// ssl is a non-owning pointer to the parent `SSL` object.
SSL *ssl;
SSLImpl *ssl;
// config is a non-owning pointer to the handshake configuration.
SSL_CONFIG *config;
@@ -2162,11 +2166,11 @@ struct SSL_HANDSHAKE {
// so many tickets.
constexpr size_t kMaxTickets = 16;
UniquePtr<SSL_HANDSHAKE> ssl_handshake_new(SSL *ssl);
UniquePtr<SSL_HANDSHAKE> ssl_handshake_new(SSLImpl *ssl);
// ssl_check_message_type checks if `msg` has type `type`. If so it returns
// one. Otherwise, it sends an alert and returns zero.
bool ssl_check_message_type(SSL *ssl, const SSLMessage &msg, int type);
bool ssl_check_message_type(SSLImpl *ssl, const SSLMessage &msg, int type);
// ssl_run_handshake runs the TLS handshake. It returns one on success and <= 0
// on error. It sets `out_early_return` to one if we've completed the handshake
@@ -2189,11 +2193,11 @@ const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs);
// tls13_add_key_update queues a KeyUpdate message on `ssl`. `request_type` must
// be one of `SSL_KEY_UPDATE_REQUESTED` or `SSL_KEY_UPDATE_NOT_REQUESTED`.
bool tls13_add_key_update(SSL *ssl, int request_type);
bool tls13_add_key_update(SSLImpl *ssl, int request_type);
// tls13_post_handshake processes a post-handshake message. It returns true on
// success and false on failure.
bool tls13_post_handshake(SSL *ssl, const SSLMessage &msg);
bool tls13_post_handshake(SSLImpl *ssl, const SSLMessage &msg);
bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg,
bool allow_anonymous);
@@ -2213,8 +2217,9 @@ bool tls13_add_certificate(SSL_HANDSHAKE *hs);
enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs);
bool tls13_add_finished(SSL_HANDSHAKE *hs);
bool tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg);
UniquePtr<SSL_SESSION> tls13_create_session_with_ticket(SSL *ssl, CBS *body);
bool tls13_process_new_session_ticket(SSLImpl *ssl, const SSLMessage &msg);
UniquePtr<SSL_SESSION> tls13_create_session_with_ticket(SSLImpl *ssl,
CBS *body);
// ssl_setup_extension_permutation computes a ClientHello extension permutation
// for `hs`, if applicable. It returns true on success and false on error.
@@ -2467,13 +2472,13 @@ bool ssl_parse_flags_extension_response(const CBS *cbs, SSLFlags *out,
// ssl_log_secret logs `secret` with label `label`, if logging is enabled for
// `ssl`. It returns true on success and false on failure.
bool ssl_log_secret(const SSL *ssl, const char *label,
bool ssl_log_secret(const SSLImpl *ssl, const char *label,
Span<const uint8_t> secret);
// ClientHello functions.
bool ssl_parse_client_hello_with_trailing_data(const SSL *ssl, CBS *cbs,
bool ssl_parse_client_hello_with_trailing_data(const SSLImpl *ssl, CBS *cbs,
SSL_CLIENT_HELLO *out);
bool ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello,
@@ -2593,25 +2598,26 @@ struct CERT {
// `SSL_PROTOCOL_METHOD` abstracts between TLS and DTLS.
struct SSL_PROTOCOL_METHOD {
bool is_dtls;
bool (*ssl_new)(SSL *ssl);
void (*ssl_free)(SSL *ssl);
bool (*ssl_new)(SSLImpl *ssl);
void (*ssl_free)(SSLImpl *ssl);
// get_message sets `*out` to the current handshake message and returns true
// if one has been received. It returns false if more input is needed.
bool (*get_message)(const SSL *ssl, SSLMessage *out);
bool (*get_message)(const SSLImpl *ssl, SSLMessage *out);
// next_message is called to release the current handshake message.
void (*next_message)(SSL *ssl);
void (*next_message)(SSLImpl *ssl);
// has_unprocessed_handshake_data returns whether there is buffered
// handshake data that has not been consumed by `get_message`.
bool (*has_unprocessed_handshake_data)(const SSL *ssl);
bool (*has_unprocessed_handshake_data)(const SSLImpl *ssl);
// Use the `ssl_open_handshake` wrapper.
ssl_open_record_t (*open_handshake)(SSL *ssl, size_t *out_consumed,
ssl_open_record_t (*open_handshake)(SSLImpl *ssl, size_t *out_consumed,
uint8_t *out_alert, Span<uint8_t> in);
// Use the `ssl_open_change_cipher_spec` wrapper.
ssl_open_record_t (*open_change_cipher_spec)(SSL *ssl, size_t *out_consumed,
ssl_open_record_t (*open_change_cipher_spec)(SSLImpl *ssl,
size_t *out_consumed,
uint8_t *out_alert,
Span<uint8_t> in);
// Use the `ssl_open_app_data` wrapper.
ssl_open_record_t (*open_app_data)(SSL *ssl, Span<uint8_t> *out,
ssl_open_record_t (*open_app_data)(SSLImpl *ssl, Span<uint8_t> *out,
size_t *out_consumed, uint8_t *out_alert,
Span<uint8_t> in);
// write_app_data encrypts and writes `in` as application data. On success, it
@@ -2619,33 +2625,33 @@ struct SSL_PROTOCOL_METHOD {
// written. Otherwise, it returns <= 0 and sets `*out_needs_handshake` to
// whether the operation failed because the caller needs to drive the
// handshake.
int (*write_app_data)(SSL *ssl, bool *out_needs_handshake,
int (*write_app_data)(SSLImpl *ssl, bool *out_needs_handshake,
size_t *out_bytes_written, Span<const uint8_t> in);
int (*dispatch_alert)(SSL *ssl);
int (*dispatch_alert)(SSLImpl *ssl);
// init_message begins a new handshake message of type `type`. `cbb` is the
// root CBB to be passed into `finish_message`. `*body` is set to a child CBB
// the caller should write to. It returns true on success and false on error.
bool (*init_message)(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type);
bool (*init_message)(const SSLImpl *ssl, CBB *cbb, CBB *body, uint8_t type);
// finish_message finishes a handshake message. It sets `*out_msg` to the
// serialized message. It returns true on success and false on error.
bool (*finish_message)(const SSL *ssl, CBB *cbb, Array<uint8_t> *out_msg);
bool (*finish_message)(const SSLImpl *ssl, CBB *cbb, Array<uint8_t> *out_msg);
// add_message adds a handshake message to the pending flight. It returns
// true on success and false on error.
bool (*add_message)(SSL *ssl, Array<uint8_t> msg);
bool (*add_message)(SSLImpl *ssl, Array<uint8_t> msg);
// add_change_cipher_spec adds a ChangeCipherSpec record to the pending
// flight. It returns true on success and false on error.
bool (*add_change_cipher_spec)(SSL *ssl);
bool (*add_change_cipher_spec)(SSLImpl *ssl);
// finish_flight marks the pending flight as finished and ready to send.
// `flush` must be called to write it.
void (*finish_flight)(SSL *ssl);
void (*finish_flight)(SSLImpl *ssl);
// schedule_ack schedules a DTLS 1.3 ACK to be sent, without an ACK delay.
// `flush` must be called to write it.
void (*schedule_ack)(SSL *ssl);
void (*schedule_ack)(SSLImpl *ssl);
// flush writes any scheduled data to the transport. It returns one on success
// and <= 0 on error.
int (*flush)(SSL *ssl);
int (*flush)(SSLImpl *ssl);
// on_handshake_complete is called when the handshake is complete.
void (*on_handshake_complete)(SSL *ssl);
void (*on_handshake_complete)(SSLImpl *ssl);
// set_read_state sets `ssl`'s read cipher state and level to `aead_ctx` and
// `level`. In QUIC, `aead_ctx` is a placeholder object. In TLS 1.3,
// `traffic_secret` is the original traffic secret. This function returns true
@@ -2653,7 +2659,7 @@ struct SSL_PROTOCOL_METHOD {
//
// TODO(crbug.com/371998381): Take the traffic secrets as input and let the
// function create the SSLAEADContext.
bool (*set_read_state)(SSL *ssl, ssl_encryption_level_t level,
bool (*set_read_state)(SSLImpl *ssl, ssl_encryption_level_t level,
UniquePtr<SSLAEADContext> aead_ctx,
Span<const uint8_t> traffic_secret);
// set_write_state sets `ssl`'s write cipher state and level to `aead_ctx` and
@@ -2663,7 +2669,7 @@ struct SSL_PROTOCOL_METHOD {
//
// TODO(crbug.com/371998381): Take the traffic secrets as input and let the
// function create the SSLAEADContext.
bool (*set_write_state)(SSL *ssl, ssl_encryption_level_t level,
bool (*set_write_state)(SSLImpl *ssl, ssl_encryption_level_t level,
UniquePtr<SSLAEADContext> aead_ctx,
Span<const uint8_t> traffic_secret);
};
@@ -2672,12 +2678,13 @@ struct SSL_PROTOCOL_METHOD {
// ssl_open_handshake processes a record from `in` for reading a handshake
// message.
ssl_open_record_t ssl_open_handshake(SSL *ssl, size_t *out_consumed,
ssl_open_record_t ssl_open_handshake(SSLImpl *ssl, size_t *out_consumed,
uint8_t *out_alert, Span<uint8_t> in);
// ssl_open_change_cipher_spec processes a record from `in` for reading a
// ChangeCipherSpec.
ssl_open_record_t ssl_open_change_cipher_spec(SSL *ssl, size_t *out_consumed,
ssl_open_record_t ssl_open_change_cipher_spec(SSLImpl *ssl,
size_t *out_consumed,
uint8_t *out_alert,
Span<uint8_t> in);
@@ -2686,7 +2693,7 @@ ssl_open_record_t ssl_open_change_cipher_spec(SSL *ssl, size_t *out_consumed,
// input. If it encounters a post-handshake message, it returns
// `ssl_open_record_discard`. The caller should then retry, after processing any
// messages received with `get_message`.
ssl_open_record_t ssl_open_app_data(SSL *ssl, Span<uint8_t> *out,
ssl_open_record_t ssl_open_app_data(SSLImpl *ssl, Span<uint8_t> *out,
size_t *out_consumed, uint8_t *out_alert,
Span<uint8_t> in);
@@ -3345,11 +3352,11 @@ struct ALPSConfig {
struct SSL_CONFIG {
static constexpr bool kAllowUniquePtr = true;
explicit SSL_CONFIG(SSL *ssl_arg);
explicit SSL_CONFIG(SSLImpl *ssl_arg);
~SSL_CONFIG();
// ssl is a non-owning pointer to the parent `SSL` object.
SSL *const ssl = nullptr;
SSLImpl *const ssl = nullptr;
// conf_max_version is the maximum acceptable version configured by
// `SSL_set_max_proto_version`. Note this version is not normalized in DTLS
@@ -3604,7 +3611,7 @@ bool ssl_session_is_context_valid(const SSL_HANDSHAKE *hs,
// ssl_session_is_time_valid returns true if `session` is still valid and false
// if it has expired.
bool ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session);
bool ssl_session_is_time_valid(const SSLImpl *ssl, const SSL_SESSION *session);
// ssl_session_is_resumable returns whether `session` is resumable for `hs`.
bool ssl_session_is_resumable(const SSL_HANDSHAKE *hs,
@@ -3623,7 +3630,7 @@ const EVP_MD *ssl_session_get_digest(const SSL_SESSION *session);
// on the peer's certificate type) or a valid SHA-256 hash thereof.
bool ssl_session_has_peer_cred(const SSL_SESSION *session);
void ssl_set_session(SSL *ssl, SSL_SESSION *session);
void ssl_set_session(SSLImpl *ssl, SSL_SESSION *session);
// ssl_get_prev_session looks up the previous session based on `client_hello`.
// On success, it sets `*out_session` to the session or nullptr if none was
@@ -3652,74 +3659,77 @@ OPENSSL_EXPORT UniquePtr<SSL_SESSION> SSL_SESSION_dup(
// ssl_session_rebase_time updates `session`'s start time to the current time,
// adjusting the timeout so the expiration time is unchanged.
void ssl_session_rebase_time(SSL *ssl, SSL_SESSION *session);
void ssl_session_rebase_time(SSLImpl *ssl, SSL_SESSION *session);
// ssl_session_renew_timeout calls `ssl_session_rebase_time` and renews
// `session`'s timeout to `timeout` (measured from the current time). The
// renewal is clamped to the session's auth_timeout.
void ssl_session_renew_timeout(SSL *ssl, SSL_SESSION *session,
void ssl_session_renew_timeout(SSLImpl *ssl, SSL_SESSION *session,
uint32_t timeout);
void ssl_update_cache(SSL *ssl);
void ssl_update_cache(SSLImpl *ssl);
void ssl_send_alert(SSL *ssl, int level, int desc);
int ssl_send_alert_impl(SSL *ssl, int level, int desc);
bool tls_get_message(const SSL *ssl, SSLMessage *out);
ssl_open_record_t tls_open_handshake(SSL *ssl, size_t *out_consumed,
void ssl_send_alert(SSLImpl *ssl, int level, int desc);
int ssl_send_alert_impl(SSLImpl *ssl, int level, int desc);
bool tls_get_message(const SSLImpl *ssl, SSLMessage *out);
ssl_open_record_t tls_open_handshake(SSLImpl *ssl, size_t *out_consumed,
uint8_t *out_alert, Span<uint8_t> in);
void tls_next_message(SSL *ssl);
void tls_next_message(SSLImpl *ssl);
int tls_dispatch_alert(SSL *ssl);
ssl_open_record_t tls_open_app_data(SSL *ssl, Span<uint8_t> *out,
int tls_dispatch_alert(SSLImpl *ssl);
ssl_open_record_t tls_open_app_data(SSLImpl *ssl, Span<uint8_t> *out,
size_t *out_consumed, uint8_t *out_alert,
Span<uint8_t> in);
ssl_open_record_t tls_open_change_cipher_spec(SSL *ssl, size_t *out_consumed,
ssl_open_record_t tls_open_change_cipher_spec(SSLImpl *ssl,
size_t *out_consumed,
uint8_t *out_alert,
Span<uint8_t> in);
int tls_write_app_data(SSL *ssl, bool *out_needs_handshake,
int tls_write_app_data(SSLImpl *ssl, bool *out_needs_handshake,
size_t *out_bytes_written, Span<const uint8_t> in);
bool tls_new(SSL *ssl);
void tls_free(SSL *ssl);
bool tls_new(SSLImpl *ssl);
void tls_free(SSLImpl *ssl);
bool tls_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type);
bool tls_finish_message(const SSL *ssl, CBB *cbb, Array<uint8_t> *out_msg);
bool tls_add_message(SSL *ssl, Array<uint8_t> msg);
bool tls_add_change_cipher_spec(SSL *ssl);
int tls_flush(SSL *ssl);
bool tls_init_message(const SSLImpl *ssl, CBB *cbb, CBB *body, uint8_t type);
bool tls_finish_message(const SSLImpl *ssl, CBB *cbb, Array<uint8_t> *out_msg);
bool tls_add_message(SSLImpl *ssl, Array<uint8_t> msg);
bool tls_add_change_cipher_spec(SSLImpl *ssl);
int tls_flush(SSLImpl *ssl);
bool dtls1_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type);
bool dtls1_finish_message(const SSL *ssl, CBB *cbb, Array<uint8_t> *out_msg);
bool dtls1_add_message(SSL *ssl, Array<uint8_t> msg);
bool dtls1_add_change_cipher_spec(SSL *ssl);
void dtls1_finish_flight(SSL *ssl);
void dtls1_schedule_ack(SSL *ssl);
int dtls1_flush(SSL *ssl);
bool dtls1_init_message(const SSLImpl *ssl, CBB *cbb, CBB *body, uint8_t type);
bool dtls1_finish_message(const SSLImpl *ssl, CBB *cbb,
Array<uint8_t> *out_msg);
bool dtls1_add_message(SSLImpl *ssl, Array<uint8_t> msg);
bool dtls1_add_change_cipher_spec(SSLImpl *ssl);
void dtls1_finish_flight(SSLImpl *ssl);
void dtls1_schedule_ack(SSLImpl *ssl);
int dtls1_flush(SSLImpl *ssl);
// ssl_add_message_cbb finishes the handshake message in `cbb` and adds it to
// the pending flight. It returns true on success and false on error.
bool ssl_add_message_cbb(SSL *ssl, CBB *cbb);
bool ssl_add_message_cbb(SSLImpl *ssl, CBB *cbb);
// ssl_hash_message incorporates `msg` into the handshake hash. It returns true
// on success and false on allocation failure.
bool ssl_hash_message(SSL_HANDSHAKE *hs, const SSLMessage &msg);
ssl_open_record_t dtls1_process_ack(SSL *ssl, uint8_t *out_alert,
ssl_open_record_t dtls1_process_ack(SSLImpl *ssl, uint8_t *out_alert,
DTLSRecordNumber ack_record_number,
Span<const uint8_t> data);
ssl_open_record_t dtls1_open_app_data(SSL *ssl, Span<uint8_t> *out,
ssl_open_record_t dtls1_open_app_data(SSLImpl *ssl, Span<uint8_t> *out,
size_t *out_consumed, uint8_t *out_alert,
Span<uint8_t> in);
ssl_open_record_t dtls1_open_change_cipher_spec(SSL *ssl, size_t *out_consumed,
ssl_open_record_t dtls1_open_change_cipher_spec(SSLImpl *ssl,
size_t *out_consumed,
uint8_t *out_alert,
Span<uint8_t> in);
int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake,
int dtls1_write_app_data(SSLImpl *ssl, bool *out_needs_handshake,
size_t *out_bytes_written, Span<const uint8_t> in);
// dtls1_write_record sends a record. It returns one on success and <= 0 on
// error.
int dtls1_write_record(SSL *ssl, int type, Span<const uint8_t> in,
int dtls1_write_record(SSLImpl *ssl, int type, Span<const uint8_t> in,
uint16_t epoch);
bool dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr,
@@ -3733,28 +3743,28 @@ bool dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr,
// before failing the DTLS handshake.
#define DTLS1_MAX_TIMEOUTS 12
void dtls1_stop_timer(SSL *ssl);
void dtls1_stop_timer(SSLImpl *ssl);
unsigned int dtls1_min_mtu();
bool dtls1_new(SSL *ssl);
void dtls1_free(SSL *ssl);
bool dtls1_new(SSLImpl *ssl);
void dtls1_free(SSLImpl *ssl);
bool dtls1_process_handshake_fragments(SSL *ssl, uint8_t *out_alert,
bool dtls1_process_handshake_fragments(SSLImpl *ssl, uint8_t *out_alert,
DTLSRecordNumber record_number,
Span<const uint8_t> record);
bool dtls1_get_message(const SSL *ssl, SSLMessage *out);
ssl_open_record_t dtls1_open_handshake(SSL *ssl, size_t *out_consumed,
bool dtls1_get_message(const SSLImpl *ssl, SSLMessage *out);
ssl_open_record_t dtls1_open_handshake(SSLImpl *ssl, size_t *out_consumed,
uint8_t *out_alert, Span<uint8_t> in);
void dtls1_next_message(SSL *ssl);
int dtls1_dispatch_alert(SSL *ssl);
void dtls1_next_message(SSLImpl *ssl);
int dtls1_dispatch_alert(SSLImpl *ssl);
// tls1_configure_aead configures either the read or write direction AEAD (as
// determined by `direction`) using the keys generated by the TLS KDF. The
// `key_block_cache` argument is used to store the generated key block, if
// empty. Otherwise it's assumed that the key block is already contained within
// it. It returns true on success or false on error.
bool tls1_configure_aead(SSL *ssl, evp_aead_direction_t direction,
bool tls1_configure_aead(SSLImpl *ssl, evp_aead_direction_t direction,
Array<uint8_t> *key_block_cache,
const SSL_SESSION *session,
Span<const uint8_t> iv_override);
@@ -3832,19 +3842,19 @@ bool tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len);
bool tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs);
// ssl_can_write returns whether `ssl` is allowed to write.
bool ssl_can_write(const SSL *ssl);
bool ssl_can_write(const SSLImpl *ssl);
// ssl_can_read returns whether `ssl` is allowed to read.
bool ssl_can_read(const SSL *ssl);
bool ssl_can_read(const SSLImpl *ssl);
OPENSSL_timeval ssl_ctx_get_current_time(const SSLContext *ctx);
// ssl_reset_error_state resets state for `SSL_get_error`.
void ssl_reset_error_state(SSL *ssl);
void ssl_reset_error_state(SSLImpl *ssl);
// ssl_set_read_error sets `ssl`'s read half into an error state, saving the
// current state of the error queue.
void ssl_set_read_error(SSL *ssl);
void ssl_set_read_error(SSLImpl *ssl);
BSSL_NAMESPACE_END
@@ -4202,39 +4212,41 @@ class SSLContext : public ssl_ctx_st, public RefCounted<SSLContext> {
friend RefCounted;
~SSLContext();
};
BSSL_NAMESPACE_END
struct ssl_st {
explicit ssl_st(bssl::SSLContext *ctx_arg);
ssl_st(const ssl_st &) = delete;
ssl_st &operator=(const ssl_st &) = delete;
~ssl_st();
class SSLImpl : public ssl_st {
public:
static constexpr bool kAllowUniquePtr = true;
explicit SSLImpl(SSLContext *ctx_arg);
SSLImpl(const SSLImpl &) = delete;
SSLImpl &operator=(const SSLImpl &) = delete;
~SSLImpl();
// method is the method table corresponding to the current protocol (DTLS or
// TLS).
const bssl::SSL_PROTOCOL_METHOD *method = nullptr;
const SSL_PROTOCOL_METHOD *method = nullptr;
// config is a container for handshake configuration. Accesses to this field
// should check for nullptr, since configuration may be shed after the
// handshake completes. (If you have the `SSL_HANDSHAKE` object at hand, use
// that instead, and skip the null check.)
bssl::UniquePtr<bssl::SSL_CONFIG> config;
UniquePtr<SSL_CONFIG> config;
uint16_t max_send_fragment = 0;
// There are 2 BIO's even though they are normally both the same. This is so
// data can be read and written to different handlers
bssl::UniquePtr<BIO> rbio; // used by SSL_read
bssl::UniquePtr<BIO> wbio; // used by SSL_write
UniquePtr<BIO> rbio; // used by SSL_read
UniquePtr<BIO> wbio; // used by SSL_write
// do_handshake runs the handshake. On completion, it returns `ssl_hs_ok`.
// Otherwise, it returns a value corresponding to what operation is needed to
// progress.
bssl::ssl_hs_wait_t (*do_handshake)(bssl::SSL_HANDSHAKE *hs) = nullptr;
ssl_hs_wait_t (*do_handshake)(SSL_HANDSHAKE *hs) = nullptr;
bssl::SSL3_STATE *s3 = nullptr; // TLS variables
bssl::DTLS1_STATE *d1 = nullptr; // DTLS variables
SSL3_STATE *s3 = nullptr; // TLS variables
DTLS1_STATE *d1 = nullptr; // DTLS variables
// callback that allows applications to peek at protocol messages
void (*msg_callback)(int write_p, int version, int content_type,
@@ -4251,15 +4263,15 @@ struct ssl_st {
// session is the configured session to be offered by the client. This session
// is immutable.
bssl::UniquePtr<SSL_SESSION> session;
UniquePtr<SSL_SESSION> session;
void (*info_callback)(const SSL *ssl, int type, int value) = nullptr;
bssl::UniquePtr<bssl::SSLContext> ctx;
UniquePtr<SSLContext> ctx;
// session_ctx is the `SSLContext` used for the session cache and related
// settings.
bssl::UniquePtr<bssl::SSLContext> session_ctx;
UniquePtr<SSLContext> session_ctx;
// extra application data
CRYPTO_EX_DATA ex_data;
@@ -4267,7 +4279,7 @@ struct ssl_st {
uint32_t options = 0; // protocol behaviour
uint32_t mode = 0; // API behaviour
uint32_t max_cert_list = 0;
bssl::UniquePtr<char> hostname;
UniquePtr<char> hostname;
// quic_method is the method table corresponding to the QUIC hooks.
const SSL_QUIC_METHOD *quic_method = nullptr;
@@ -4291,6 +4303,7 @@ struct ssl_st {
// signal its sessions may be resumed across names in the server certificate.
bool resumption_across_names_enabled : 1;
};
BSSL_NAMESPACE_END
struct ssl_session_st : public bssl::RefCounted<ssl_session_st> {
explicit ssl_session_st(const bssl::SSL_X509_METHOD *method);
+16 -15
View File
@@ -39,7 +39,7 @@
BSSL_NAMESPACE_BEGIN
static bool add_record_to_flight(SSL *ssl, uint8_t type,
static bool add_record_to_flight(SSLImpl *ssl, uint8_t type,
Span<const uint8_t> in) {
// The caller should have flushed `pending_hs_data` first.
assert(!ssl->s3->pending_hs_data);
@@ -73,7 +73,7 @@ static bool add_record_to_flight(SSL *ssl, uint8_t type,
return true;
}
bool tls_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type) {
bool tls_init_message(const SSLImpl *ssl, CBB *cbb, CBB *body, uint8_t type) {
// Pick a modest size hint to save most of the `realloc` calls.
if (!CBB_init(cbb, 64) || //
!CBB_add_u8(cbb, type) || //
@@ -86,11 +86,11 @@ bool tls_init_message(const SSL *ssl, CBB *cbb, CBB *body, uint8_t type) {
return true;
}
bool tls_finish_message(const SSL *ssl, CBB *cbb, Array<uint8_t> *out_msg) {
bool tls_finish_message(const SSLImpl *ssl, CBB *cbb, Array<uint8_t> *out_msg) {
return CBBFinishArray(cbb, out_msg);
}
bool tls_add_message(SSL *ssl, Array<uint8_t> msg) {
bool tls_add_message(SSLImpl *ssl, Array<uint8_t> msg) {
// Pack handshake data into the minimal number of records. This avoids
// unnecessary encryption overhead, notably in TLS 1.3 where we send several
// encrypted messages in a row. For now, we do not do this for the null
@@ -146,7 +146,7 @@ bool tls_add_message(SSL *ssl, Array<uint8_t> msg) {
return true;
}
bool tls_flush_pending_hs_data(SSL *ssl) {
bool tls_flush_pending_hs_data(SSLImpl *ssl) {
if (!ssl->s3->pending_hs_data || ssl->s3->pending_hs_data->length == 0) {
return true;
}
@@ -167,7 +167,7 @@ bool tls_flush_pending_hs_data(SSL *ssl) {
return add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, data);
}
bool tls_add_change_cipher_spec(SSL *ssl) {
bool tls_add_change_cipher_spec(SSLImpl *ssl) {
if (SSL_is_quic(ssl)) {
return true;
}
@@ -184,7 +184,7 @@ bool tls_add_change_cipher_spec(SSL *ssl) {
return true;
}
int tls_flush(SSL *ssl) {
int tls_flush(SSLImpl *ssl) {
if (!tls_flush_pending_hs_data(ssl)) {
return -1;
}
@@ -255,7 +255,8 @@ int tls_flush(SSL *ssl) {
return 1;
}
static ssl_open_record_t read_v2_client_hello(SSL *ssl, size_t *out_consumed,
static ssl_open_record_t read_v2_client_hello(SSLImpl *ssl,
size_t *out_consumed,
Span<const uint8_t> in) {
*out_consumed = 0;
assert(in.size() >= SSL3_RT_HEADER_LENGTH);
@@ -376,7 +377,7 @@ static ssl_open_record_t read_v2_client_hello(SSL *ssl, size_t *out_consumed,
return ssl_open_record_success;
}
static bool parse_message(const SSL *ssl, SSLMessage *out,
static bool parse_message(const SSLImpl *ssl, SSLMessage *out,
size_t *out_bytes_needed) {
if (!ssl->s3->hs_buf) {
*out_bytes_needed = 4;
@@ -404,7 +405,7 @@ static bool parse_message(const SSL *ssl, SSLMessage *out,
return true;
}
bool tls_get_message(const SSL *ssl, SSLMessage *out) {
bool tls_get_message(const SSLImpl *ssl, SSLMessage *out) {
size_t unused;
if (!parse_message(ssl, out, &unused)) {
return false;
@@ -418,7 +419,7 @@ bool tls_get_message(const SSL *ssl, SSLMessage *out) {
return true;
}
bool tls_can_accept_handshake_data(const SSL *ssl, uint8_t *out_alert) {
bool tls_can_accept_handshake_data(const SSLImpl *ssl, uint8_t *out_alert) {
// If there is a complete message, the caller must have consumed it first.
SSLMessage msg;
size_t bytes_needed;
@@ -438,7 +439,7 @@ bool tls_can_accept_handshake_data(const SSL *ssl, uint8_t *out_alert) {
return true;
}
bool tls_has_unprocessed_handshake_data(const SSL *ssl) {
bool tls_has_unprocessed_handshake_data(const SSLImpl *ssl) {
size_t msg_len = 0;
if (ssl->s3->has_message) {
SSLMessage msg;
@@ -451,7 +452,7 @@ bool tls_has_unprocessed_handshake_data(const SSL *ssl) {
return ssl->s3->hs_buf && ssl->s3->hs_buf->length > msg_len;
}
bool tls_append_handshake_data(SSL *ssl, Span<const uint8_t> data) {
bool tls_append_handshake_data(SSLImpl *ssl, Span<const uint8_t> data) {
// Re-create the handshake buffer if needed.
if (!ssl->s3->hs_buf) {
ssl->s3->hs_buf.reset(BUF_MEM_new());
@@ -460,7 +461,7 @@ bool tls_append_handshake_data(SSL *ssl, Span<const uint8_t> data) {
BUF_MEM_append(ssl->s3->hs_buf.get(), data.data(), data.size());
}
ssl_open_record_t tls_open_handshake(SSL *ssl, size_t *out_consumed,
ssl_open_record_t tls_open_handshake(SSLImpl *ssl, size_t *out_consumed,
uint8_t *out_alert, Span<uint8_t> in) {
*out_consumed = 0;
// Bypass the record layer for the first message to handle V2ClientHello.
@@ -528,7 +529,7 @@ ssl_open_record_t tls_open_handshake(SSL *ssl, size_t *out_consumed,
return ssl_open_record_success;
}
void tls_next_message(SSL *ssl) {
void tls_next_message(SSLImpl *ssl) {
SSLMessage msg;
if (!tls_get_message(ssl, &msg) || //
!ssl->s3->hs_buf || //
+2 -2
View File
@@ -49,7 +49,7 @@ SSL3_STATE::SSL3_STATE()
SSL3_STATE::~SSL3_STATE() {}
bool tls_new(SSL *ssl) {
bool tls_new(SSLImpl *ssl) {
UniquePtr<SSL3_STATE> s3 = MakeUnique<SSL3_STATE>();
if (!s3) {
return false;
@@ -76,7 +76,7 @@ bool tls_new(SSL *ssl) {
return true;
}
void tls_free(SSL *ssl) {
void tls_free(SSLImpl *ssl) {
if (ssl->s3 == nullptr) {
return;
}
+10 -9
View File
@@ -32,10 +32,10 @@
BSSL_NAMESPACE_BEGIN
static int do_tls_write(SSL *ssl, size_t *out_bytes_written, uint8_t type,
static int do_tls_write(SSLImpl *ssl, size_t *out_bytes_written, uint8_t type,
Span<const uint8_t> in);
int tls_write_app_data(SSL *ssl, bool *out_needs_handshake,
int tls_write_app_data(SSLImpl *ssl, bool *out_needs_handshake,
size_t *out_bytes_written, Span<const uint8_t> in) {
assert(ssl_can_write(ssl));
assert(!ssl->s3->aead_write_ctx->is_null_cipher());
@@ -114,7 +114,7 @@ int tls_write_app_data(SSL *ssl, bool *out_needs_handshake,
//
// TODO(davidben): Is this alignment valuable? Record-splitting makes this a
// mess.
static size_t tls_seal_align_prefix_len(const SSL *ssl) {
static size_t tls_seal_align_prefix_len(const SSLImpl *ssl) {
size_t ret =
SSL3_RT_HEADER_LENGTH + ssl->s3->aead_write_ctx->ExplicitNonceLen();
if (ssl_needs_record_splitting(ssl)) {
@@ -127,7 +127,7 @@ static size_t tls_seal_align_prefix_len(const SSL *ssl) {
// do_tls_write writes an SSL record of the given type. On success, it sets
// `*out_bytes_written` to number of bytes successfully written and returns one.
// On error, it returns a value <= 0 from the underlying `BIO`.
static int do_tls_write(SSL *ssl, size_t *out_bytes_written, uint8_t type,
static int do_tls_write(SSLImpl *ssl, size_t *out_bytes_written, uint8_t type,
Span<const uint8_t> in) {
// If there is a pending write, the retry must be consistent.
if (!ssl->s3->pending_write.empty() &&
@@ -233,7 +233,7 @@ static int do_tls_write(SSL *ssl, size_t *out_bytes_written, uint8_t type,
return 1;
}
ssl_open_record_t tls_open_app_data(SSL *ssl, Span<uint8_t> *out,
ssl_open_record_t tls_open_app_data(SSLImpl *ssl, Span<uint8_t> *out,
size_t *out_consumed, uint8_t *out_alert,
Span<uint8_t> in) {
assert(ssl_can_read(ssl));
@@ -289,7 +289,8 @@ ssl_open_record_t tls_open_app_data(SSL *ssl, Span<uint8_t> *out,
return ssl_open_record_success;
}
ssl_open_record_t tls_open_change_cipher_spec(SSL *ssl, size_t *out_consumed,
ssl_open_record_t tls_open_change_cipher_spec(SSLImpl *ssl,
size_t *out_consumed,
uint8_t *out_alert,
Span<uint8_t> in) {
uint8_t type;
@@ -315,7 +316,7 @@ ssl_open_record_t tls_open_change_cipher_spec(SSL *ssl, size_t *out_consumed,
return ssl_open_record_success;
}
void ssl_send_alert(SSL *ssl, int level, int desc) {
void ssl_send_alert(SSLImpl *ssl, int level, int desc) {
// This function is called in response to a fatal error from the peer. Ignore
// any failures writing the alert and report only the original error. In
// particular, if the transport uses `SSL_write`, our existing error will be
@@ -332,7 +333,7 @@ void ssl_send_alert(SSL *ssl, int level, int desc) {
ERR_restore_state(err_state.get());
}
int ssl_send_alert_impl(SSL *ssl, int level, int desc) {
int ssl_send_alert_impl(SSLImpl *ssl, int level, int desc) {
// It is illegal to send an alert when we've already sent a closing one.
if (ssl->s3->write_shutdown != ssl_shutdown_none) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
@@ -360,7 +361,7 @@ int ssl_send_alert_impl(SSL *ssl, int level, int desc) {
return -1;
}
int tls_dispatch_alert(SSL *ssl) {
int tls_dispatch_alert(SSLImpl *ssl) {
if (SSL_is_quic(ssl)) {
if (!ssl->quic_method->send_alert(ssl, ssl->s3->quic_write_level,
ssl->s3->send_alert[1])) {
+7 -7
View File
@@ -116,7 +116,7 @@ void SSLBuffer::DiscardConsumed() {
}
}
static int dtls_read_buffer_next_packet(SSL *ssl) {
static int dtls_read_buffer_next_packet(SSLImpl *ssl) {
SSLBuffer *buf = &ssl->s3->read_buffer;
if (!buf->empty()) {
@@ -137,7 +137,7 @@ static int dtls_read_buffer_next_packet(SSL *ssl) {
return 1;
}
static int tls_read_buffer_extend_to(SSL *ssl, size_t len) {
static int tls_read_buffer_extend_to(SSLImpl *ssl, size_t len) {
SSLBuffer *buf = &ssl->s3->read_buffer;
if (len > buf->cap()) {
@@ -161,7 +161,7 @@ static int tls_read_buffer_extend_to(SSL *ssl, size_t len) {
return 1;
}
int ssl_read_buffer_extend_to(SSL *ssl, size_t len) {
int ssl_read_buffer_extend_to(SSLImpl *ssl, size_t len) {
// `ssl_read_buffer_extend_to` implicitly discards any consumed data.
ssl->s3->read_buffer.DiscardConsumed();
@@ -202,7 +202,7 @@ int ssl_read_buffer_extend_to(SSL *ssl, size_t len) {
return ret;
}
int ssl_handle_open_record(SSL *ssl, bool *out_retry, ssl_open_record_t ret,
int ssl_handle_open_record(SSLImpl *ssl, bool *out_retry, ssl_open_record_t ret,
size_t consumed, uint8_t alert) {
*out_retry = false;
if (ret != ssl_open_record_partial) {
@@ -255,7 +255,7 @@ static_assert(DTLS1_RT_MAX_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD +
0xffff,
"maximum DTLS write buffer is too large");
static int tls_write_buffer_flush(SSL *ssl) {
static int tls_write_buffer_flush(SSLImpl *ssl) {
SSLBuffer *buf = &ssl->s3->write_buffer;
while (!buf->empty()) {
size_t written;
@@ -269,7 +269,7 @@ static int tls_write_buffer_flush(SSL *ssl) {
return 1;
}
static int dtls_write_buffer_flush(SSL *ssl) {
static int dtls_write_buffer_flush(SSLImpl *ssl) {
SSLBuffer *buf = &ssl->s3->write_buffer;
if (buf->empty()) {
return 1;
@@ -288,7 +288,7 @@ static int dtls_write_buffer_flush(SSL *ssl) {
return 1;
}
int ssl_write_buffer_flush(SSL *ssl) {
int ssl_write_buffer_flush(SSLImpl *ssl) {
if (ssl->wbio == nullptr) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET);
return -1;
+33 -22
View File
@@ -405,7 +405,7 @@ bool ssl_cert_check_key_usage(const CBS *in, enum ssl_key_usage_t bit) {
return true;
}
UniquePtr<STACK_OF(CRYPTO_BUFFER)> SSL_parse_CA_list(SSL *ssl,
UniquePtr<STACK_OF(CRYPTO_BUFFER)> SSL_parse_CA_list(SSLImpl *ssl,
uint8_t *out_alert,
CBS *cbs) {
CRYPTO_BUFFER_POOL *const pool = ssl->ctx->pool.get();
@@ -542,10 +542,11 @@ using namespace bssl;
int SSL_set_chain_and_key(SSL *ssl, CRYPTO_BUFFER *const *certs,
size_t num_certs, EVP_PKEY *privkey,
const SSL_PRIVATE_KEY_METHOD *privkey_method) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
return 0;
}
return cert_set_chain_and_key(ssl->config->cert.get(), certs, num_certs,
return cert_set_chain_and_key(ssl_impl->config->cert.get(), certs, num_certs,
privkey, privkey_method);
}
@@ -557,11 +558,12 @@ int SSL_CTX_set_chain_and_key(SSL_CTX *ctx, CRYPTO_BUFFER *const *certs,
}
void SSL_certs_clear(SSL *ssl) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
return;
}
CERT *cert = ssl->config->cert.get();
CERT *cert = ssl_impl->config->cert.get();
cert->x509_method->cert_clear(cert);
cert->credentials.clear();
cert->legacy_credential->ClearCertAndKey();
@@ -572,10 +574,11 @@ const STACK_OF(CRYPTO_BUFFER) *SSL_CTX_get0_chain(const SSL_CTX *ctx) {
}
const STACK_OF(CRYPTO_BUFFER) *SSL_get0_chain(const SSL *ssl) {
if (!ssl->config) {
const auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
return nullptr;
}
return ssl->config->cert->legacy_credential->chain.get();
return ssl_impl->config->cert->legacy_credential->chain.get();
}
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len,
@@ -589,12 +592,13 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len,
}
int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
auto *ssl_impl = FromOpaque(ssl);
UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(der, der_len, nullptr));
if (!buffer || !ssl->config) {
if (!buffer || !ssl_impl->config) {
return 0;
}
return ssl_set_cert(ssl->config->cert.get(), std::move(buffer));
return ssl_set_cert(ssl_impl->config->cert.get(), std::move(buffer));
}
void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg),
@@ -603,10 +607,11 @@ void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg),
}
void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
return;
}
ssl_cert_set_cert_cb(ssl->config->cert.get(), cb, arg);
ssl_cert_set_cert_cb(ssl_impl->config->cert.get(), cb, arg);
}
const STACK_OF(CRYPTO_BUFFER) *SSL_get0_peer_certificates(const SSL *ssl) {
@@ -619,10 +624,11 @@ const STACK_OF(CRYPTO_BUFFER) *SSL_get0_peer_certificates(const SSL *ssl) {
}
const STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs(const SSL *ssl) {
if (ssl->s3->hs == nullptr) {
const auto *ssl_impl = FromOpaque(ssl);
if (ssl_impl->s3->hs == nullptr) {
return nullptr;
}
return ssl->s3->hs->ca_names.get();
return ssl_impl->s3->hs->ca_names.get();
}
int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list,
@@ -635,13 +641,14 @@ int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list,
int SSL_set_signed_cert_timestamp_list(SSL *ssl, const uint8_t *list,
size_t list_len) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
return 0;
}
UniquePtr<CRYPTO_BUFFER> buf(CRYPTO_BUFFER_new(list, list_len, nullptr));
return buf != nullptr &&
SSL_CREDENTIAL_set1_signed_cert_timestamp_list(
ssl->config->cert->legacy_credential.get(), buf.get());
ssl_impl->config->cert->legacy_credential.get(), buf.get());
}
int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response,
@@ -655,14 +662,15 @@ int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response,
int SSL_set_ocsp_response(SSL *ssl, const uint8_t *response,
size_t response_len) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
return 0;
}
UniquePtr<CRYPTO_BUFFER> buf(
CRYPTO_BUFFER_new(response, response_len, nullptr));
return buf != nullptr &&
SSL_CREDENTIAL_set1_ocsp_response(
ssl->config->cert->legacy_credential.get(), buf.get());
ssl_impl->config->cert->legacy_credential.get(), buf.get());
}
void SSL_CTX_set0_client_CAs(SSL_CTX *ctx, STACK_OF(CRYPTO_BUFFER) *name_list) {
@@ -672,18 +680,21 @@ void SSL_CTX_set0_client_CAs(SSL_CTX *ctx, STACK_OF(CRYPTO_BUFFER) *name_list) {
}
void SSL_set0_client_CAs(SSL *ssl, STACK_OF(CRYPTO_BUFFER) *name_list) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
// `SSL_set0_client_CAs` is expected to take ownership of `name_list`.
sk_CRYPTO_BUFFER_pop_free(name_list, CRYPTO_BUFFER_free);
return;
}
ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl->config.get());
ssl->config->client_CA.reset(name_list);
ssl_impl->ctx->x509_method->ssl_flush_cached_client_CA(
ssl_impl->config.get());
ssl_impl->config->client_CA.reset(name_list);
}
void SSL_set0_CA_names(SSL *ssl, STACK_OF(CRYPTO_BUFFER) *name_list) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
return;
}
ssl->config->CA_names.reset(name_list);
ssl_impl->config->CA_names.reset(name_list);
}
+6 -4
View File
@@ -668,8 +668,9 @@ int SSL_CTX_add1_credential(SSL_CTX *ctx, const SSL_CREDENTIAL *cred) {
}
int SSL_add1_credential(SSL *ssl, const SSL_CREDENTIAL *cred) {
auto *ssl_impl = FromOpaque(ssl);
auto *cred_impl = FromOpaque(cred);
if (ssl->config == nullptr) {
if (ssl_impl->config == nullptr) {
return 0;
}
@@ -677,14 +678,15 @@ int SSL_add1_credential(SSL *ssl, const SSL_CREDENTIAL *cred) {
OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return ssl->config->cert->credentials.Push(UpRef(cred_impl));
return ssl_impl->config->cert->credentials.Push(UpRef(cred_impl));
}
const SSL_CREDENTIAL *SSL_get0_selected_credential(const SSL *ssl) {
if (ssl->s3->hs == nullptr) {
auto *ssl_impl = FromOpaque(ssl);
if (ssl_impl->s3->hs == nullptr) {
return nullptr;
}
return ssl->s3->hs->credential.get();
return ssl_impl->s3->hs->credential.get();
}
int SSL_CREDENTIAL_get_ex_new_index(long argl, void *argp,
+10 -8
View File
@@ -130,6 +130,7 @@ int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out,
}
int SSL_use_certificate_file(SSL *ssl, const char *file, int type) {
SSLContext *ctx = FromOpaque(SSL_get_SSL_CTX(ssl));
UniquePtr<BIO> in(BIO_new_file(file, "rb"));
if (in == nullptr) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
@@ -143,9 +144,8 @@ int SSL_use_certificate_file(SSL *ssl, const char *file, int type) {
x.reset(d2i_X509_bio(in.get(), nullptr));
} else if (type == SSL_FILETYPE_PEM) {
reason_code = ERR_R_PEM_LIB;
x.reset(PEM_read_bio_X509(in.get(), nullptr,
ssl->ctx->default_passwd_callback,
ssl->ctx->default_passwd_callback_userdata));
x.reset(PEM_read_bio_X509(in.get(), nullptr, ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata));
} else {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
return 0;
@@ -160,6 +160,7 @@ int SSL_use_certificate_file(SSL *ssl, const char *file, int type) {
}
int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) {
SSLContext *ctx = FromOpaque(SSL_get_SSL_CTX(ssl));
UniquePtr<BIO> in(BIO_new_file(file, "rb"));
if (in == nullptr) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
@@ -174,8 +175,8 @@ int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) {
} else if (type == SSL_FILETYPE_PEM) {
reason_code = ERR_R_PEM_LIB;
rsa.reset(PEM_read_bio_RSAPrivateKey(
in.get(), nullptr, ssl->ctx->default_passwd_callback,
ssl->ctx->default_passwd_callback_userdata));
in.get(), nullptr, ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata));
} else {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
return 0;
@@ -189,6 +190,7 @@ int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) {
}
int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) {
SSLContext *ctx = FromOpaque(SSL_get_SSL_CTX(ssl));
UniquePtr<BIO> in(BIO_new_file(file, "rb"));
if (in == nullptr) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
@@ -199,9 +201,9 @@ int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) {
UniquePtr<EVP_PKEY> pkey;
if (type == SSL_FILETYPE_PEM) {
reason_code = ERR_R_PEM_LIB;
pkey.reset(PEM_read_bio_PrivateKey(
in.get(), nullptr, ssl->ctx->default_passwd_callback,
ssl->ctx->default_passwd_callback_userdata));
pkey.reset(PEM_read_bio_PrivateKey(in.get(), nullptr,
ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata));
} else if (type == SSL_FILETYPE_ASN1) {
reason_code = ERR_R_ASN1_LIB;
pkey.reset(d2i_PrivateKey_bio(in.get(), nullptr));
+520 -408
View File
File diff suppressed because it is too large Load Diff
+31 -20
View File
@@ -142,7 +142,7 @@ bssl::UniquePtr<EVP_PKEY> ssl_parse_peer_subject_public_key_info(
spki.data(), spki.size(), algs, std::size(algs)));
}
bool ssl_pkey_supports_algorithm(const SSL *ssl, EVP_PKEY *pkey,
bool ssl_pkey_supports_algorithm(const SSLImpl *ssl, EVP_PKEY *pkey,
uint16_t sigalg, bool is_verify) {
const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
if (alg == nullptr || EVP_PKEY_id(pkey) != alg->pkey_type) {
@@ -197,7 +197,7 @@ bool ssl_pkey_supports_algorithm(const SSL *ssl, EVP_PKEY *pkey,
return true;
}
static bool setup_ctx(SSL *ssl, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
static bool setup_ctx(SSLImpl *ssl, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
uint16_t sigalg, bool is_verify) {
if (!ssl_pkey_supports_algorithm(ssl, pkey, sigalg, is_verify)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
@@ -229,7 +229,7 @@ static bool setup_ctx(SSL *ssl, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
enum ssl_private_key_result_t ssl_private_key_sign(
SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out,
uint16_t sigalg, Span<const uint8_t> in) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
const SSLCredential *const cred = hs->credential.get();
Array<uint8_t> spki;
if (hs->provided_hints != nullptr || hs->pending_hints != nullptr) {
@@ -304,7 +304,7 @@ enum ssl_private_key_result_t ssl_private_key_sign(
return ssl_private_key_success;
}
bool ssl_public_key_verify(SSL *ssl, Span<const uint8_t> signature,
bool ssl_public_key_verify(SSLImpl *ssl, Span<const uint8_t> signature,
uint16_t sigalg, EVP_PKEY *pkey,
Span<const uint8_t> in) {
ScopedEVP_MD_CTX ctx;
@@ -325,7 +325,7 @@ enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs,
size_t *out_len,
size_t max_out,
Span<const uint8_t> in) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
const SSLCredential *const cred = hs->credential.get();
assert(!hs->can_release_private_key);
if (cred->key_method != nullptr) {
@@ -372,7 +372,7 @@ BSSL_NAMESPACE_END
using namespace bssl;
int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) {
if (rsa == nullptr || ssl->config == nullptr) {
if (rsa == nullptr || FromOpaque(ssl)->config == nullptr) {
OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -398,13 +398,14 @@ int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
}
int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
if (pkey == nullptr || ssl->config == nullptr) {
auto *ssl_impl = FromOpaque(ssl);
if (pkey == nullptr || ssl_impl->config == nullptr) {
OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
return SSL_CREDENTIAL_set1_private_key(
ssl->config->cert->legacy_credential.get(), pkey);
ssl_impl->config->cert->legacy_credential.get(), pkey);
}
int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der,
@@ -479,11 +480,12 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der,
void SSL_set_private_key_method(SSL *ssl,
const SSL_PRIVATE_KEY_METHOD *key_method) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
return;
}
BSSL_CHECK(SSL_CREDENTIAL_set_private_key_method(
ssl->config->cert->legacy_credential.get(), key_method));
ssl_impl->config->cert->legacy_credential.get(), key_method));
}
void SSL_CTX_set_private_key_method(SSL_CTX *ctx,
@@ -659,11 +661,12 @@ int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs,
int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs,
size_t num_prefs) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
return 0;
}
return SSL_CREDENTIAL_set1_signing_algorithm_prefs(
ssl->config->cert->legacy_credential.get(), prefs, num_prefs);
ssl_impl->config->cert->legacy_credential.get(), prefs, num_prefs);
}
static constexpr struct {
@@ -739,7 +742,8 @@ int SSL_CTX_set1_sigalgs(SSL_CTX *ctx, const int *values, size_t num_values) {
}
int SSL_set1_sigalgs(SSL *ssl, const int *values, size_t num_values) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -749,8 +753,10 @@ int SSL_set1_sigalgs(SSL *ssl, const int *values, size_t num_values) {
return 0;
}
if (!SSL_set_signing_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size()) ||
!SSL_set_verify_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size())) {
if (!SSL_set_signing_algorithm_prefs(ssl_impl, sigalgs.data(),
sigalgs.size()) ||
!SSL_set_verify_algorithm_prefs(ssl_impl, sigalgs.data(),
sigalgs.size())) {
return 0;
}
@@ -927,7 +933,8 @@ int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str) {
}
int SSL_set1_sigalgs_list(SSL *ssl, const char *str) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -937,8 +944,10 @@ int SSL_set1_sigalgs_list(SSL *ssl, const char *str) {
return 0;
}
if (!SSL_set_signing_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size()) ||
!SSL_set_verify_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size())) {
if (!SSL_set_signing_algorithm_prefs(ssl_impl, sigalgs.data(),
sigalgs.size()) ||
!SSL_set_verify_algorithm_prefs(ssl_impl, sigalgs.data(),
sigalgs.size())) {
return 0;
}
@@ -953,10 +962,12 @@ int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs,
int SSL_set_verify_algorithm_prefs(SSL *ssl, const uint16_t *prefs,
size_t num_prefs) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return set_sigalg_prefs(&ssl->config->verify_sigalgs, Span(prefs, num_prefs));
return set_sigalg_prefs(&ssl_impl->config->verify_sigalgs,
Span(prefs, num_prefs));
}
+20 -18
View File
@@ -157,7 +157,7 @@ UniquePtr<SSL_SESSION> SSL_SESSION_dup(const SSL_SESSION *session,
return new_session;
}
void ssl_session_rebase_time(SSL *ssl, SSL_SESSION *session) {
void ssl_session_rebase_time(SSLImpl *ssl, SSL_SESSION *session) {
OPENSSL_timeval now = ssl_ctx_get_current_time(ssl->ctx.get());
// To avoid overflows and underflows, if we've gone back in time, update the
@@ -185,7 +185,7 @@ void ssl_session_rebase_time(SSL *ssl, SSL_SESSION *session) {
}
}
void ssl_session_renew_timeout(SSL *ssl, SSL_SESSION *session,
void ssl_session_renew_timeout(SSLImpl *ssl, SSL_SESSION *session,
uint32_t timeout) {
// Rebase the timestamp relative to the current time so `timeout` is measured
// correctly.
@@ -219,7 +219,7 @@ const EVP_MD *ssl_session_get_digest(const SSL_SESSION *session) {
}
bool ssl_get_new_session(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl->mode & SSL_MODE_NO_SESSION_CREATION) {
OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_MAY_NOT_BE_CREATED);
return false;
@@ -401,7 +401,7 @@ static int ssl_encrypt_ticket_with_cipher_ctx(SSL_HANDSHAKE *hs, CBB *out,
static int ssl_encrypt_ticket_with_method(SSL_HANDSHAKE *hs, CBB *out,
const uint8_t *session_buf,
size_t session_len) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
const SSL_TICKET_AEAD_METHOD *method = ssl->session_ctx->ticket_aead_method;
const size_t max_overhead = method->max_overhead(ssl);
const size_t max_out = session_len + max_overhead;
@@ -469,7 +469,7 @@ bool ssl_session_is_context_valid(const SSL_HANDSHAKE *hs,
Span(session->sid_ctx) == hs->config->cert->sid_ctx;
}
bool ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) {
bool ssl_session_is_time_valid(const SSLImpl *ssl, const SSL_SESSION *session) {
if (session == nullptr) {
return false;
}
@@ -486,7 +486,7 @@ bool ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) {
bool ssl_session_is_resumable(const SSL_HANDSHAKE *hs,
const SSL_SESSION *session) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
return ssl_session_is_context_valid(hs, session) &&
// The session must have been created by the same type of end point as
// we're now using it with.
@@ -518,7 +518,7 @@ bool ssl_session_is_resumable(const SSL_HANDSHAKE *hs,
static enum ssl_hs_wait_t ssl_lookup_session(
SSL_HANDSHAKE *hs, UniquePtr<SSL_SESSION> *out_session,
Span<const uint8_t> session_id) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
out_session->reset();
if (session_id.empty() || session_id.size() > SSL_MAX_SSL_SESSION_ID_LENGTH) {
@@ -660,7 +660,7 @@ static bool remove_session(SSLContext *ctx, SSL_SESSION *session, bool lock) {
return found;
}
void ssl_set_session(SSL *ssl, SSL_SESSION *session) {
void ssl_set_session(SSLImpl *ssl, SSL_SESSION *session) {
if (ssl->session.get() == session) {
return;
}
@@ -767,7 +767,7 @@ static bool add_session_locked(SSLContext *ctx,
return true;
}
void ssl_update_cache(SSL *ssl) {
void ssl_update_cache(SSLImpl *ssl) {
SSLContext *ctx = ssl->session_ctx.get();
SSL_SESSION *session = ssl->s3->established_session.get();
int mode = SSL_is_server(ssl) ? SSL_SESS_CACHE_SERVER : SSL_SESS_CACHE_CLIENT;
@@ -1055,6 +1055,7 @@ SSL_SESSION *SSL_magic_pending_session_ptr() {
}
SSL_SESSION *SSL_get_session(const SSL *ssl) {
const auto *ssl_impl = FromOpaque(ssl);
// Once the initially handshake completes, we return the most recently
// established session. In particular, if there is a pending renegotiation, we
// do not return information about it until it completes.
@@ -1062,14 +1063,14 @@ SSL_SESSION *SSL_get_session(const SSL *ssl) {
// Code in the handshake must either use `hs->new_session` (if updating a
// partial session) or `ssl_handshake_session` (if trying to query properties
// consistently across TLS 1.2 resumption and other handshakes).
if (ssl->s3->established_session != nullptr) {
return ssl->s3->established_session.get();
if (ssl_impl->s3->established_session != nullptr) {
return ssl_impl->s3->established_session.get();
}
// Otherwise, we must be in the initial handshake.
SSL_HANDSHAKE *hs = ssl->s3->hs.get();
SSL_HANDSHAKE *hs = ssl_impl->s3->hs.get();
assert(hs != nullptr);
assert(!ssl->s3->initial_handshake_complete);
assert(!ssl_impl->s3->initial_handshake_complete);
// Return the 0-RTT session, if in the 0-RTT state. While the handshake has
// not actually completed, the public accessors all report properties as if
@@ -1117,14 +1118,15 @@ int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session) {
}
int SSL_set_session(SSL *ssl, SSL_SESSION *session) {
auto *ssl_impl = FromOpaque(ssl);
// SSL_set_session may only be called before the handshake has started.
if (ssl->s3->initial_handshake_complete || //
ssl->s3->hs == nullptr || //
ssl->s3->hs->state != 0) {
if (ssl_impl->s3->initial_handshake_complete || //
ssl_impl->s3->hs == nullptr || //
ssl_impl->s3->hs->state != 0) {
abort();
}
ssl_set_session(ssl, session);
ssl_set_session(ssl_impl, session);
return 1;
}
@@ -1228,7 +1230,7 @@ void SSL_CTX_set_resumption_across_names_enabled(SSL_CTX *ctx, int enabled) {
}
void SSL_set_resumption_across_names_enabled(SSL *ssl, int enabled) {
ssl->resumption_across_names_enabled = !!enabled;
FromOpaque(ssl)->resumption_across_names_enabled = !!enabled;
}
void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*cb)(const SSL *ssl,
+6 -3
View File
@@ -20,13 +20,16 @@
#include "internal.h"
using namespace bssl;
const char *SSL_state_string_long(const SSL *ssl) {
if (ssl->s3->hs == nullptr) {
const auto *ssl_impl = FromOpaque(ssl);
if (ssl_impl->s3->hs == nullptr) {
return "SSL negotiation finished successfully";
}
return ssl->server ? ssl_server_handshake_state(ssl->s3->hs.get())
: ssl_client_handshake_state(ssl->s3->hs.get());
return ssl_impl->server ? ssl_server_handshake_state(ssl_impl->s3->hs.get())
: ssl_client_handshake_state(ssl_impl->s3->hs.get());
}
const char *SSL_state_string(const SSL *ssl) { return "!!!!!!"; }
+46 -29
View File
@@ -704,12 +704,13 @@ TEST(SSLTest, DefaultCurves) {
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
ASSERT_TRUE(ssl);
EXPECT_THAT(ssl->config->supported_group_list,
EXPECT_THAT(FromOpaque(ssl.get())->config->supported_group_list,
Not(ElementsAreArray(kDefaults)));
// Setting an empty list restores the defaults.
ASSERT_TRUE(SSL_set1_group_ids(ssl.get(), nullptr, 0));
EXPECT_THAT(ssl->config->supported_group_list, ElementsAreArray(kDefaults));
EXPECT_THAT(FromOpaque(ssl.get())->config->supported_group_list,
ElementsAreArray(kDefaults));
ASSERT_TRUE(SSL_CTX_set1_group_ids(ctx.get(), nullptr, 0));
EXPECT_THAT(FromOpaque(ctx.get())->supported_group_list,
ElementsAreArray(kDefaults));
@@ -732,12 +733,13 @@ TEST(SSLTest, DefaultCurves) {
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
ASSERT_TRUE(ssl);
EXPECT_THAT(ssl->config->supported_group_list,
EXPECT_THAT(FromOpaque(ssl.get())->config->supported_group_list,
Not(ElementsAreArray(kDefaults)));
// Setting an empty list restores the defaults.
ASSERT_TRUE(SSL_set1_groups(ssl.get(), nullptr, 0));
EXPECT_THAT(ssl->config->supported_group_list, ElementsAreArray(kDefaults));
EXPECT_THAT(FromOpaque(ssl.get())->config->supported_group_list,
ElementsAreArray(kDefaults));
ASSERT_TRUE(SSL_CTX_set1_groups(ctx.get(), nullptr, 0));
EXPECT_THAT(FromOpaque(ctx.get())->supported_group_list,
ElementsAreArray(kDefaults));
@@ -832,7 +834,8 @@ TEST(SSLTest, SetClientKeyShares) {
ASSERT_TRUE(ctx);
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
ASSERT_TRUE(ssl);
ASSERT_FALSE(ssl->config->client_key_share_selections.has_value());
ASSERT_FALSE(
FromOpaque(ssl.get())->config->client_key_share_selections.has_value());
ASSERT_TRUE(SSL_set1_group_ids(ssl.get(), t.supported_groups.data(),
t.supported_groups.size()));
@@ -840,9 +843,11 @@ TEST(SSLTest, SetClientKeyShares) {
t.key_shares.size()),
t.expected_success);
if (t.expected_success) {
ASSERT_TRUE(ssl->config->client_key_share_selections.has_value());
EXPECT_THAT(ssl->config->client_key_share_selections.value(),
ElementsAreArray(t.key_shares));
ASSERT_TRUE(FromOpaque(ssl.get())
->config->client_key_share_selections.has_value());
EXPECT_THAT(
FromOpaque(ssl.get())->config->client_key_share_selections.value(),
ElementsAreArray(t.key_shares));
}
}
}
@@ -855,7 +860,8 @@ TEST(SSLTest, ClientKeySharesResetAfterChangingGroups) {
ASSERT_TRUE(ctx);
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
ASSERT_TRUE(ssl);
ASSERT_FALSE(ssl->config->client_key_share_selections.has_value());
ASSERT_FALSE(
FromOpaque(ssl.get())->config->client_key_share_selections.has_value());
// An initial groups list and key shares that are compatible.
const uint16_t kGroups1[] = {SSL_GROUP_X25519_MLKEM768, SSL_GROUP_X25519};
@@ -863,22 +869,27 @@ TEST(SSLTest, ClientKeySharesResetAfterChangingGroups) {
ASSERT_TRUE(SSL_set1_group_ids(ssl.get(), kGroups1, std::size(kGroups1)));
ASSERT_TRUE(
SSL_set1_client_key_shares(ssl.get(), kKeyShares, std::size(kKeyShares)));
ASSERT_TRUE(ssl->config->client_key_share_selections.has_value());
EXPECT_EQ(ssl->config->client_key_share_selections->size(), 2u);
ASSERT_TRUE(
FromOpaque(ssl.get())->config->client_key_share_selections.has_value());
EXPECT_EQ(FromOpaque(ssl.get())->config->client_key_share_selections->size(),
2u);
// A new groups list that is still compatible with the previously set key
// shares.
const uint16_t kGroups2[] = {SSL_GROUP_MLKEM1024, SSL_GROUP_X25519_MLKEM768,
SSL_GROUP_X25519};
ASSERT_TRUE(SSL_set1_group_ids(ssl.get(), kGroups2, std::size(kGroups2)));
ASSERT_TRUE(ssl->config->client_key_share_selections.has_value());
EXPECT_EQ(ssl->config->client_key_share_selections->size(), 2u);
ASSERT_TRUE(
FromOpaque(ssl.get())->config->client_key_share_selections.has_value());
EXPECT_EQ(FromOpaque(ssl.get())->config->client_key_share_selections->size(),
2u);
// A new groups list that is no longer compatible with the previously set key
// shares.
const uint16_t kGroups3[] = {SSL_GROUP_MLKEM1024, SSL_GROUP_X25519};
ASSERT_TRUE(SSL_set1_group_ids(ssl.get(), kGroups3, std::size(kGroups3)));
EXPECT_FALSE(ssl->config->client_key_share_selections.has_value());
EXPECT_FALSE(
FromOpaque(ssl.get())->config->client_key_share_selections.has_value());
}
TEST(SSLTest, ServerSupportedGroupsHint) {
@@ -957,7 +968,7 @@ TEST(SSLTest, ServerSupportedGroupsHint) {
ASSERT_TRUE(SSL_connect(ssl.get()));
std::vector<uint16_t> key_shares;
for (const auto &key_share : ssl->s3->hs->key_shares) {
for (const auto &key_share : FromOpaque(ssl.get())->s3->hs->key_shares) {
key_shares.push_back(key_share->GroupID());
}
EXPECT_THAT(key_shares, ElementsAreArray(t.expected_key_shares));
@@ -976,19 +987,22 @@ TEST(SSLTest, ServerHintOverridesClientKeyShareSelections) {
const uint16_t kKeyShares[] = {SSL_GROUP_SECP256R1};
ASSERT_TRUE(
SSL_set1_client_key_shares(ssl.get(), kKeyShares, std::size(kKeyShares)));
ASSERT_TRUE(ssl->config->client_key_share_selections.has_value());
EXPECT_THAT(ssl->config->client_key_share_selections.value(),
ElementsAreArray(kKeyShares));
ASSERT_TRUE(
FromOpaque(ssl.get())->config->client_key_share_selections.has_value());
EXPECT_THAT(
FromOpaque(ssl.get())->config->client_key_share_selections.value(),
ElementsAreArray(kKeyShares));
const uint16_t kServerHint[] = {SSL_GROUP_X25519};
ASSERT_TRUE(SSL_set1_server_supported_groups_hint(ssl.get(), kServerHint,
std::size(kServerHint)));
EXPECT_THAT(ssl->config->server_supported_groups_hint,
EXPECT_THAT(FromOpaque(ssl.get())->config->server_supported_groups_hint,
ElementsAreArray(kServerHint));
// The group predicted based on the server hint should win.
ASSERT_TRUE(SSL_connect(ssl.get()));
ASSERT_EQ(ssl->s3->hs->key_shares.size(), 1u);
EXPECT_EQ(kServerHint[0], ssl->s3->hs->key_shares[0]->GroupID());
ASSERT_EQ(FromOpaque(ssl.get())->s3->hs->key_shares.size(), 1u);
EXPECT_EQ(kServerHint[0],
FromOpaque(ssl.get())->s3->hs->key_shares[0]->GroupID());
}
TEST(SSLTest, ServerHintOverridesEmptyClientKeyShareSelections) {
@@ -1001,17 +1015,19 @@ TEST(SSLTest, ServerHintOverridesEmptyClientKeyShareSelections) {
ASSERT_TRUE(SSL_set1_group_ids(ssl.get(), kGroups, std::size(kGroups)));
ASSERT_TRUE(SSL_set1_client_key_shares(ssl.get(), nullptr, 0));
EXPECT_TRUE(ssl->config->client_key_share_selections->empty());
EXPECT_TRUE(
FromOpaque(ssl.get())->config->client_key_share_selections->empty());
const uint16_t kServerHint[] = {SSL_GROUP_X25519};
ASSERT_TRUE(SSL_set1_server_supported_groups_hint(ssl.get(), kServerHint,
std::size(kServerHint)));
EXPECT_THAT(ssl->config->server_supported_groups_hint,
EXPECT_THAT(FromOpaque(ssl.get())->config->server_supported_groups_hint,
ElementsAreArray(kServerHint));
// The group predicted based on the server hint should win.
ASSERT_TRUE(SSL_connect(ssl.get()));
ASSERT_EQ(ssl->s3->hs->key_shares.size(), 1u);
EXPECT_EQ(kServerHint[0], ssl->s3->hs->key_shares[0]->GroupID());
ASSERT_EQ(FromOpaque(ssl.get())->s3->hs->key_shares.size(), 1u);
EXPECT_EQ(kServerHint[0],
FromOpaque(ssl.get())->s3->hs->key_shares[0]->GroupID());
}
// kOpenSSLSession is a serialized SSL_SESSION.
@@ -2341,7 +2357,7 @@ TEST(SSLTest, SetGroupIdsWithFlags_DefaultGroups) {
// Should set the default groups, and corresponding default (zero) flags.
EXPECT_TRUE(
SSL_set1_group_ids_with_flags(server.get(), nullptr, kBogusFlags, 0));
EXPECT_THAT(server->config->supported_group_list,
EXPECT_THAT(FromOpaque(server.get())->config->supported_group_list,
ElementsAreArray(kDefaultGroups));
// Set up and run the handshake to show that the bogus "equal preference with
@@ -7192,12 +7208,13 @@ TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
};
// The default list of groups is used before applying the handoff.
EXPECT_THAT(server->config->supported_group_list,
EXPECT_THAT(FromOpaque(server.get())->config->supported_group_list,
ElementsAreArray({SSL_GROUP_X25519, SSL_GROUP_SECP256R1,
SSL_GROUP_SECP384R1}));
ASSERT_TRUE(SSL_apply_handoff(server.get(), handoff));
EXPECT_EQ(1u, server->config->supported_group_list.size());
EXPECT_EQ(SSL_GROUP_SECP256R1, server->config->supported_group_list[0]);
EXPECT_EQ(1u, FromOpaque(server.get())->config->supported_group_list.size());
EXPECT_EQ(SSL_GROUP_SECP256R1,
FromOpaque(server.get())->config->supported_group_list[0]);
}
TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
+22 -16
View File
@@ -243,7 +243,7 @@ bool ssl_get_version_range(const SSL_HANDSHAKE *hs, uint16_t *out_min_version,
return true;
}
static uint16_t ssl_version(const SSL *ssl) {
static uint16_t ssl_version(const SSLImpl *ssl) {
// In early data, we report the predicted version. Note it is possible that we
// have a predicted version and a *different* true version. This means 0-RTT
// has been rejected, but until the reject has reported to the application and
@@ -260,12 +260,12 @@ static uint16_t ssl_version(const SSL *ssl) {
return SSL_is_dtls(ssl) ? DTLS1_2_VERSION : TLS1_2_VERSION;
}
bool ssl_has_final_version(const SSL *ssl) {
bool ssl_has_final_version(const SSLImpl *ssl) {
return ssl->s3->version != 0 &&
(ssl->s3->hs == nullptr || !ssl->s3->hs->is_early_version);
}
uint16_t ssl_protocol_version(const SSL *ssl) {
uint16_t ssl_protocol_version(const SSLImpl *ssl) {
assert(ssl->s3->version != 0);
uint16_t version;
if (!ssl_protocol_version_from_wire(&version, ssl->s3->version)) {
@@ -278,7 +278,7 @@ uint16_t ssl_protocol_version(const SSL *ssl) {
}
bool ssl_supports_version(const SSL_HANDSHAKE *hs, uint16_t version) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
uint16_t protocol_version;
if (!ssl_method_supports_version(ssl->method, version) ||
!ssl_protocol_version_from_wire(&protocol_version, version) ||
@@ -369,41 +369,47 @@ uint16_t SSL_CTX_get_max_proto_version(const SSL_CTX *ctx) {
}
int SSL_set_min_proto_version(SSL *ssl, uint16_t version) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
return 0;
}
return set_min_version(ssl->method, &ssl->config->conf_min_version, version);
return set_min_version(ssl_impl->method, &ssl_impl->config->conf_min_version,
version);
}
int SSL_set_max_proto_version(SSL *ssl, uint16_t version) {
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
return 0;
}
return set_max_version(ssl->method, &ssl->config->conf_max_version, version);
return set_max_version(ssl_impl->method, &ssl_impl->config->conf_max_version,
version);
}
uint16_t SSL_get_min_proto_version(const SSL *ssl) {
if (!ssl->config) {
assert(ssl->config);
const auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
assert(ssl_impl->config);
return 0;
}
return ssl->config->conf_min_version;
return ssl_impl->config->conf_min_version;
}
uint16_t SSL_get_max_proto_version(const SSL *ssl) {
if (!ssl->config) {
assert(ssl->config);
const auto *ssl_impl = FromOpaque(ssl);
if (!ssl_impl->config) {
assert(ssl_impl->config);
return 0;
}
return ssl->config->conf_max_version;
return ssl_impl->config->conf_max_version;
}
int SSL_version(const SSL *ssl) {
return wire_version_to_api(ssl_version(ssl));
return wire_version_to_api(ssl_version(FromOpaque(ssl)));
}
const char *SSL_get_version(const SSL *ssl) {
return ssl_version_to_string(ssl_version(ssl));
return ssl_version_to_string(ssl_version(FromOpaque(ssl)));
}
size_t SSL_get_all_version_names(const char **out, size_t max_out) {
+137 -105
View File
@@ -36,7 +36,7 @@ BSSL_NAMESPACE_BEGIN
// check_ssl_x509_method asserts that `ssl` has the X509-based method
// installed. Calling an X509-based method on an `ssl` with a different method
// will likely misbehave and possibly crash or leak memory.
static void check_ssl_x509_method(const SSL *ssl) {
static void check_ssl_x509_method(const SSLImpl *ssl) {
assert(ssl == nullptr || ssl->ctx->x509_method == &ssl_crypto_x509_method);
}
@@ -211,7 +211,7 @@ static bool ssl_crypto_x509_session_verify_cert_chain(SSL_SESSION *session,
return false;
}
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLContext *ssl_ctx = ssl->ctx.get();
X509_STORE *verify_store = ssl_ctx->cert_store;
if (hs->config->cert->verify_store != nullptr) {
@@ -296,7 +296,7 @@ static void ssl_crypto_x509_ssl_config_free(SSL_CONFIG *cfg) {
static bool ssl_crypto_x509_ssl_auto_chain_if_needed(SSL_HANDSHAKE *hs) {
// Only build a chain if the feature isn't disabled, the legacy credential
// exists but has no intermediates configured.
SSL *ssl = hs->ssl;
SSLImpl *ssl = hs->ssl;
SSLCredential *cred = hs->config->cert->legacy_credential.get();
if ((ssl->mode & SSL_MODE_NO_AUTO_CHAIN) || !cred->IsComplete() ||
sk_CRYPTO_BUFFER_num(cred->chain.get()) != 1) {
@@ -374,11 +374,12 @@ BSSL_NAMESPACE_END
using namespace bssl;
X509 *SSL_get_peer_certificate(const SSL *ssl) {
check_ssl_x509_method(ssl);
if (ssl == nullptr) {
const auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (ssl_impl == nullptr) {
return nullptr;
}
SSL_SESSION *session = SSL_get_session(ssl);
SSL_SESSION *session = SSL_get_session(ssl_impl);
if (session == nullptr || session->x509_peer == nullptr) {
return nullptr;
}
@@ -387,23 +388,26 @@ X509 *SSL_get_peer_certificate(const SSL *ssl) {
}
STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) {
check_ssl_x509_method(ssl);
if (ssl == nullptr) {
const auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (ssl_impl == nullptr) {
return nullptr;
}
SSL_SESSION *session = SSL_get_session(ssl);
SSL_SESSION *session = SSL_get_session(ssl_impl);
if (session == nullptr) {
return nullptr;
}
// OpenSSL historically didn't include the leaf certificate in the returned
// certificate chain, but only for servers.
return ssl->server ? session->x509_chain_without_leaf : session->x509_chain;
return ssl_impl->server ? session->x509_chain_without_leaf
: session->x509_chain;
}
STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl) {
check_ssl_x509_method(ssl);
SSL_SESSION *session = SSL_get_session(ssl);
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
SSL_SESSION *session = SSL_get_session(ssl_impl);
if (session == nullptr) {
return nullptr;
}
@@ -418,11 +422,12 @@ int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) {
}
int SSL_set_purpose(SSL *ssl, int purpose) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return 0;
}
return X509_VERIFY_PARAM_set_purpose(ssl->config->param, purpose);
return X509_VERIFY_PARAM_set_purpose(ssl_impl->config->param, purpose);
}
int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) {
@@ -432,11 +437,12 @@ int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) {
}
int SSL_set_trust(SSL *ssl, int trust) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return 0;
}
return X509_VERIFY_PARAM_set_trust(ssl->config->param, trust);
return X509_VERIFY_PARAM_set_trust(ssl_impl->config->param, trust);
}
int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) {
@@ -446,11 +452,12 @@ int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) {
}
int SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return 0;
}
return X509_VERIFY_PARAM_set1(ssl->config->param, param);
return X509_VERIFY_PARAM_set1(ssl_impl->config->param, param);
}
X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) {
@@ -460,30 +467,33 @@ X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) {
}
X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
assert(ssl->config);
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
assert(ssl_impl->config);
return nullptr;
}
return ssl->config->param;
return ssl_impl->config->param;
}
int SSL_get_verify_depth(const SSL *ssl) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
assert(ssl->config);
const auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
assert(ssl_impl->config);
return 0;
}
return X509_VERIFY_PARAM_get_depth(ssl->config->param);
return X509_VERIFY_PARAM_get_depth(ssl_impl->config->param);
}
int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
assert(ssl->config);
const auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
assert(ssl_impl->config);
return nullptr;
}
return ssl->config->verify_callback;
return ssl_impl->config->verify_callback;
}
int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) {
@@ -507,22 +517,24 @@ int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
void SSL_set_verify(SSL *ssl, int mode,
int (*callback)(int ok, X509_STORE_CTX *store_ctx)) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return;
}
ssl->config->verify_mode = mode;
ssl_impl->config->verify_mode = mode;
if (callback != nullptr) {
ssl->config->verify_callback = callback;
ssl_impl->config->verify_callback = callback;
}
}
void SSL_set_verify_depth(SSL *ssl, int depth) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return;
}
X509_VERIFY_PARAM_set_depth(ssl->config->param, depth);
X509_VERIFY_PARAM_set_depth(ssl_impl->config->param, depth);
}
void SSL_CTX_set_cert_verify_callback(
@@ -561,8 +573,9 @@ int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file,
}
long SSL_get_verify_result(const SSL *ssl) {
check_ssl_x509_method(ssl);
SSL_SESSION *session = SSL_get_session(ssl);
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
SSL_SESSION *session = SSL_get_session(ssl_impl);
if (session == nullptr) {
return X509_V_ERR_INVALID_CALL;
}
@@ -597,11 +610,12 @@ static int ssl_use_certificate(CERT *cert, X509 *x) {
}
int SSL_use_certificate(SSL *ssl, X509 *x) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return 0;
}
return ssl_use_certificate(ssl->config->cert.get(), x);
return ssl_use_certificate(ssl_impl->config->cert.get(), x);
}
int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) {
@@ -639,12 +653,13 @@ static X509 *ssl_cert_get0_leaf(CERT *cert) {
}
X509 *SSL_get_certificate(const SSL *ssl) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
assert(ssl->config);
const auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
assert(ssl_impl->config);
return nullptr;
}
return ssl_cert_get0_leaf(ssl->config->cert.get());
return ssl_cert_get0_leaf(ssl_impl->config->cert.get());
}
X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
@@ -694,11 +709,12 @@ int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) {
}
int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return 0;
}
if (!ssl_cert_set1_chain(ssl->config->cert.get(), chain)) {
if (!ssl_cert_set1_chain(ssl_impl->config->cert.get(), chain)) {
return 0;
}
sk_X509_pop_free(chain, X509_free);
@@ -706,11 +722,12 @@ int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain) {
}
int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return 0;
}
return ssl_cert_set1_chain(ssl->config->cert.get(), chain);
return ssl_cert_set1_chain(ssl_impl->config->cert.get(), chain);
}
int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509) {
@@ -732,19 +749,21 @@ int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509) {
}
int SSL_add0_chain_cert(SSL *ssl, X509 *x509) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return 0;
}
return ssl_cert_add0_chain_cert(ssl->config->cert.get(), x509);
return ssl_cert_add0_chain_cert(ssl_impl->config->cert.get(), x509);
}
int SSL_add1_chain_cert(SSL *ssl, X509 *x509) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return 0;
}
return ssl_cert_add1_chain_cert(ssl->config->cert.get(), x509);
return ssl_cert_add1_chain_cert(ssl_impl->config->cert.get(), x509);
}
int SSL_CTX_clear_chain_certs(SSL_CTX *ctx) {
@@ -760,8 +779,9 @@ int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx) {
}
int SSL_clear_chain_certs(SSL *ssl) {
check_ssl_x509_method(ssl);
return SSL_set0_chain(ssl, nullptr);
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
return SSL_set0_chain(ssl_impl, nullptr);
}
// ssl_cert_cache_chain_certs fills in `cert->x509_chain` from elements 1.. of
@@ -812,17 +832,18 @@ int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx,
}
int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
assert(ssl->config);
const auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
assert(ssl_impl->config);
return 0;
}
if (!ssl_cert_cache_chain_certs(ssl->config->cert.get())) {
if (!ssl_cert_cache_chain_certs(ssl_impl->config->cert.get())) {
*out_chain = nullptr;
return 0;
}
*out_chain = ssl->config->cert->x509_chain;
*out_chain = ssl_impl->config->cert->x509_chain;
return 1;
}
@@ -886,12 +907,15 @@ static void set_client_CA_list(UniquePtr<STACK_OF(CRYPTO_BUFFER)> *ca_list,
}
void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return;
}
ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl->config.get());
set_client_CA_list(&ssl->config->client_CA, name_list, ssl->ctx->pool.get());
ssl_impl->ctx->x509_method->ssl_flush_cached_client_CA(
ssl_impl->config.get());
set_client_CA_list(&ssl_impl->config->client_CA, name_list,
ssl_impl->ctx->pool.get());
sk_X509_NAME_pop_free(name_list, X509_NAME_free);
}
@@ -934,9 +958,10 @@ static STACK_OF(X509_NAME) *buffer_names_to_x509(
}
STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
assert(ssl->config);
const auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
assert(ssl_impl->config);
return nullptr;
}
// For historical reasons, this function is used both to query configuration
@@ -944,21 +969,21 @@ STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl) {
// `ssl` is a client or server is not known until explicitly configured with
// `SSL_set_connect_state`. If `do_handshake` is NULL, `ssl` is in an
// indeterminate mode and `ssl->server` is unset.
if (ssl->do_handshake != nullptr && !ssl->server) {
if (ssl->s3->hs != nullptr) {
return buffer_names_to_x509(ssl->s3->hs->ca_names.get(),
&ssl->s3->hs->cached_x509_ca_names);
if (ssl_impl->do_handshake != nullptr && !ssl_impl->server) {
if (ssl_impl->s3->hs != nullptr) {
return buffer_names_to_x509(ssl_impl->s3->hs->ca_names.get(),
&ssl_impl->s3->hs->cached_x509_ca_names);
}
return nullptr;
}
if (ssl->config->client_CA != nullptr) {
if (ssl_impl->config->client_CA != nullptr) {
return buffer_names_to_x509(
ssl->config->client_CA.get(),
(STACK_OF(X509_NAME) **)&ssl->config->cached_x509_client_CA);
ssl_impl->config->client_CA.get(),
(STACK_OF(X509_NAME) **)&ssl_impl->config->cached_x509_client_CA);
}
return SSL_CTX_get_client_CA_list(ssl->ctx.get());
return SSL_CTX_get_client_CA_list(ssl_impl->ctx.get());
}
STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) {
@@ -1011,15 +1036,17 @@ static int add_client_CA(UniquePtr<STACK_OF(CRYPTO_BUFFER)> *names, X509 *x509,
}
int SSL_add_client_CA(SSL *ssl, X509 *x509) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return 0;
}
if (!add_client_CA(&ssl->config->client_CA, x509, ssl->ctx->pool.get())) {
if (!add_client_CA(&ssl_impl->config->client_CA, x509,
ssl_impl->ctx->pool.get())) {
return 0;
}
ssl_crypto_x509_ssl_flush_cached_client_CA(ssl->config.get());
ssl_crypto_x509_ssl_flush_cached_client_CA(ssl_impl->config.get());
return 1;
}
@@ -1035,17 +1062,18 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509) {
}
static int do_client_cert_cb(SSL *ssl, void *arg) {
auto *ssl_impl = FromOpaque(ssl);
// Should only be called during handshake, but check to be sure.
BSSL_CHECK(ssl->config);
BSSL_CHECK(ssl_impl->config);
if (ssl->config->cert->legacy_credential->IsComplete() ||
ssl->ctx->client_cert_cb == nullptr) {
if (ssl_impl->config->cert->legacy_credential->IsComplete() ||
ssl_impl->ctx->client_cert_cb == nullptr) {
return 1;
}
X509 *x509 = nullptr;
EVP_PKEY *pkey = nullptr;
int ret = ssl->ctx->client_cert_cb(ssl, &x509, &pkey);
int ret = ssl_impl->ctx->client_cert_cb(ssl_impl, &x509, &pkey);
if (ret < 0) {
return -1;
}
@@ -1053,8 +1081,8 @@ static int do_client_cert_cb(SSL *ssl, void *arg) {
UniquePtr<EVP_PKEY> free_pkey(pkey);
if (ret != 0) {
if (!SSL_use_certificate(ssl, x509) || //
!SSL_use_PrivateKey(ssl, pkey)) {
if (!SSL_use_certificate(ssl_impl, x509) || //
!SSL_use_PrivateKey(ssl_impl, pkey)) {
return 0;
}
}
@@ -1105,36 +1133,40 @@ int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) {
}
int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return 0;
}
return set_cert_store(&ssl->config->cert->verify_store, store, 0);
return set_cert_store(&ssl_impl->config->cert->verify_store, store, 0);
}
int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return 0;
}
return set_cert_store(&ssl->config->cert->verify_store, store, 1);
return set_cert_store(&ssl_impl->config->cert->verify_store, store, 1);
}
int SSL_set1_host(SSL *ssl, const char *hostname) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return 0;
}
return X509_VERIFY_PARAM_set1_host(ssl->config->param, hostname,
return X509_VERIFY_PARAM_set1_host(ssl_impl->config->param, hostname,
strlen(hostname));
}
void SSL_set_hostflags(SSL *ssl, unsigned flags) {
check_ssl_x509_method(ssl);
if (!ssl->config) {
auto *ssl_impl = FromOpaque(ssl);
check_ssl_x509_method(ssl_impl);
if (!ssl_impl->config) {
return;
}
X509_VERIFY_PARAM_set_hostflags(ssl->config->param, flags);
X509_VERIFY_PARAM_set_hostflags(ssl_impl->config->param, flags);
}
int SSL_alert_from_verify_result(long result) {
+25 -16
View File
@@ -47,7 +47,8 @@ bool tls1_prf(const EVP_MD *digest, Span<uint8_t> out,
seed2.data(), seed2.size());
}
static bool get_key_block_lengths(const SSL *ssl, size_t *out_mac_secret_len,
static bool get_key_block_lengths(const SSLImpl *ssl,
size_t *out_mac_secret_len,
size_t *out_key_len, size_t *out_iv_len,
const SSL_CIPHER *cipher) {
const EVP_AEAD *aead = nullptr;
@@ -72,7 +73,7 @@ static bool get_key_block_lengths(const SSL *ssl, size_t *out_mac_secret_len,
return true;
}
static bool generate_key_block(const SSL *ssl, Span<uint8_t> out,
static bool generate_key_block(const SSLImpl *ssl, Span<uint8_t> out,
const SSL_SESSION *session) {
const EVP_MD *digest = ssl_session_get_digest(session);
// Note this function assumes that `session`'s key material corresponds to
@@ -81,7 +82,7 @@ static bool generate_key_block(const SSL *ssl, Span<uint8_t> out,
ssl->s3->server_random, ssl->s3->client_random);
}
bool tls1_configure_aead(SSL *ssl, evp_aead_direction_t direction,
bool tls1_configure_aead(SSLImpl *ssl, evp_aead_direction_t direction,
Array<uint8_t> *key_block_cache,
const SSL_SESSION *session,
Span<const uint8_t> iv_override) {
@@ -149,7 +150,7 @@ bool tls1_generate_master_secret(SSL_HANDSHAKE *hs, Span<uint8_t> out,
Span<const uint8_t> premaster) {
BSSL_CHECK(out.size() == SSL3_MASTER_SECRET_SIZE);
const SSL *ssl = hs->ssl;
const SSLImpl *ssl = hs->ssl;
if (hs->extended_master_secret) {
uint8_t digests[EVP_MAX_MD_SIZE];
size_t digests_len;
@@ -173,14 +174,16 @@ BSSL_NAMESPACE_END
using namespace bssl;
size_t SSL_get_key_block_len(const SSL *ssl) {
const auto *ssl_impl = FromOpaque(ssl);
// See `SSL_generate_key_block`.
if (SSL_in_init(ssl) || ssl_protocol_version(ssl) > TLS1_2_VERSION) {
if (SSL_in_init(ssl_impl) ||
ssl_protocol_version(ssl_impl) > TLS1_2_VERSION) {
return 0;
}
size_t mac_secret_len, key_len, fixed_iv_len;
if (!get_key_block_lengths(ssl, &mac_secret_len, &key_len, &fixed_iv_len,
SSL_get_current_cipher(ssl))) {
if (!get_key_block_lengths(ssl_impl, &mac_secret_len, &key_len, &fixed_iv_len,
SSL_get_current_cipher(ssl_impl))) {
ERR_clear_error();
return 0;
}
@@ -189,27 +192,32 @@ size_t SSL_get_key_block_len(const SSL *ssl) {
}
int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) {
const auto *ssl_impl = FromOpaque(ssl);
// Which cipher state to use is ambiguous during a handshake. In particular,
// there are points where read and write states are from different epochs.
// During a handshake, before ChangeCipherSpec, the encryption states may not
// match |ssl->s3->client_random| and |ssl->s3->server_random|.
if (SSL_in_init(ssl) || ssl_protocol_version(ssl) > TLS1_2_VERSION) {
if (SSL_in_init(ssl_impl) ||
ssl_protocol_version(ssl_impl) > TLS1_2_VERSION) {
OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return generate_key_block(ssl, Span(out, out_len), SSL_get_session(ssl));
return generate_key_block(ssl_impl, Span(out, out_len),
SSL_get_session(ssl_impl));
}
int SSL_export_keying_material(const SSL *ssl, uint8_t *out, size_t out_len,
const char *label, size_t label_len,
const uint8_t *context, size_t context_len,
int use_context) {
const auto *ssl_impl = FromOpaque(ssl);
auto out_span = Span(out, out_len);
std::string_view label_sv(label, label_len);
// In TLS 1.3, the exporter may be used whenever the secret has been derived.
if (ssl->s3->version != 0 && ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
if (ssl->s3->exporter_secret.empty()) {
if (ssl_impl->s3->version != 0 &&
ssl_protocol_version(ssl_impl) >= TLS1_3_VERSION) {
if (ssl_impl->s3->exporter_secret.empty()) {
OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE);
return 0;
}
@@ -217,13 +225,14 @@ int SSL_export_keying_material(const SSL *ssl, uint8_t *out, size_t out_len,
context = nullptr;
context_len = 0;
}
return tls13_export_keying_material(ssl, out_span, ssl->s3->exporter_secret,
label_sv, Span(context, context_len));
return tls13_export_keying_material(ssl_impl, out_span,
ssl_impl->s3->exporter_secret, label_sv,
Span(context, context_len));
}
// Exporters may be used in False Start, where the handshake has progressed
// enough. Otherwise, they may not be used during a handshake.
if (SSL_in_init(ssl) && !SSL_in_false_start(ssl)) {
if (SSL_in_init(ssl_impl) && !SSL_in_false_start(ssl_impl)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE);
return 0;
}
@@ -241,8 +250,8 @@ int SSL_export_keying_material(const SSL *ssl, uint8_t *out, size_t out_len,
return 0;
}
OPENSSL_memcpy(seed.data(), ssl->s3->client_random, SSL3_RANDOM_SIZE);
OPENSSL_memcpy(seed.data() + SSL3_RANDOM_SIZE, ssl->s3->server_random,
OPENSSL_memcpy(seed.data(), ssl_impl->s3->client_random, SSL3_RANDOM_SIZE);
OPENSSL_memcpy(seed.data() + SSL3_RANDOM_SIZE, ssl_impl->s3->server_random,
SSL3_RANDOM_SIZE);
if (use_context) {
seed[2 * SSL3_RANDOM_SIZE] = static_cast<uint8_t>(context_len >> 8);
+9 -9
View File
@@ -104,7 +104,7 @@ bool tls13_get_cert_verify_signature_input(
bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg,
bool allow_anonymous) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
CBS body = msg.body;
bssl::UniquePtr<CRYPTO_BUFFER> decompressed;
@@ -364,7 +364,7 @@ bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg,
bool tls13_process_certificate_verify(SSL_HANDSHAKE *hs,
const SSLMessage &msg) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (hs->peer_pubkey == nullptr) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return false;
@@ -408,7 +408,7 @@ bool tls13_process_certificate_verify(SSL_HANDSHAKE *hs,
bool tls13_process_finished(SSL_HANDSHAKE *hs, const SSLMessage &msg,
bool use_saved_value) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
uint8_t verify_data_buf[EVP_MAX_MD_SIZE];
Span<const uint8_t> verify_data;
if (use_saved_value) {
@@ -437,7 +437,7 @@ bool tls13_process_finished(SSL_HANDSHAKE *hs, const SSLMessage &msg,
}
bool tls13_add_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
const SSLCredential *cred = hs->credential.get();
ScopedCBB cbb;
@@ -612,7 +612,7 @@ bool tls13_add_certificate(SSL_HANDSHAKE *hs) {
}
enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
assert(hs->signature_algorithm != 0);
ScopedCBB cbb;
CBB body;
@@ -656,7 +656,7 @@ enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) {
}
bool tls13_add_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
size_t verify_data_len;
uint8_t verify_data[EVP_MAX_MD_SIZE];
@@ -677,7 +677,7 @@ bool tls13_add_finished(SSL_HANDSHAKE *hs) {
return true;
}
bool tls13_add_key_update(SSL *ssl, int request_type) {
bool tls13_add_key_update(SSLImpl *ssl, int request_type) {
if (ssl->s3->key_update_pending) {
return true;
}
@@ -713,7 +713,7 @@ bool tls13_add_key_update(SSL *ssl, int request_type) {
return true;
}
static bool tls13_receive_key_update(SSL *ssl, const SSLMessage &msg) {
static bool tls13_receive_key_update(SSLImpl *ssl, const SSLMessage &msg) {
CBS body = msg.body;
uint8_t key_update_request;
if (!CBS_get_u8(&body, &key_update_request) || //
@@ -738,7 +738,7 @@ static bool tls13_receive_key_update(SSL *ssl, const SSLMessage &msg) {
return true;
}
bool tls13_post_handshake(SSL *ssl, const SSLMessage &msg) {
bool tls13_post_handshake(SSLImpl *ssl, const SSLMessage &msg) {
if (msg.type == SSL3_MT_NEW_SESSION_TICKET && !ssl->server) {
return tls13_process_new_session_ticket(ssl, msg);
}
+18 -17
View File
@@ -57,7 +57,7 @@ static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
// end_of_early_data closes the early data stream for `hs` and switches the
// encryption level to `level`. It returns true on success and false on error.
static bool close_early_data(SSL_HANDSHAKE *hs, ssl_encryption_level_t level) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
assert(hs->in_early_data);
// Note `can_early_write` may already be false if `SSL_write` exceeded the
@@ -182,7 +182,7 @@ static bool check_ech_confirmation(const SSL_HANDSHAKE *hs, bool *out_accepted,
}
static enum ssl_hs_wait_t do_read_hello_retry_request(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
assert(ssl->s3->version != 0);
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
@@ -383,7 +383,7 @@ static enum ssl_hs_wait_t do_send_second_client_hello(SSL_HANDSHAKE *hs) {
static bool check_session(const SSL_HANDSHAKE *hs, uint8_t *out_alert,
const SSL_SESSION *session) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
if (session->ssl_version != ssl->s3->version) {
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
@@ -407,7 +407,7 @@ static bool check_session(const SSL_HANDSHAKE *hs, uint8_t *out_alert,
static bool check_imported_psk(const SSL_HANDSHAKE *hs, uint8_t *out_alert,
const SSLImportedPSK &imported) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
const EVP_MD *md =
ssl_get_handshake_digest(ssl_protocol_version(ssl), hs->new_cipher);
if (imported.md != md || imported.protocol != ssl->s3->version) {
@@ -419,7 +419,7 @@ static bool check_imported_psk(const SSL_HANDSHAKE *hs, uint8_t *out_alert,
}
static bool using_certificate(const SSL_HANDSHAKE *hs) {
const SSL *const ssl = hs->ssl;
const SSLImpl *const ssl = hs->ssl;
// Resumption is not a certificate-based handshake.
if (ssl->s3->session_reused) {
return false;
@@ -432,7 +432,7 @@ static bool using_certificate(const SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_message;
@@ -663,7 +663,7 @@ static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_encrypted_extensions(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_message;
@@ -744,7 +744,7 @@ static enum ssl_hs_wait_t do_read_encrypted_extensions(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// CertificateRequest may only be sent in certificate-based handshakes.
if (!using_certificate(hs)) {
if (ssl->s3->session_reused && ssl->ctx->reverify_on_resume &&
@@ -816,7 +816,7 @@ static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_server_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_message;
@@ -838,7 +838,7 @@ static enum ssl_hs_wait_t do_read_server_certificate(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_server_certificate_verify(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_message;
@@ -879,7 +879,7 @@ static enum ssl_hs_wait_t do_server_certificate_reverify(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_server_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_message;
@@ -907,7 +907,7 @@ static enum ssl_hs_wait_t do_read_server_finished(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_send_end_of_early_data(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl->s3->early_data_accepted) {
// DTLS and QUIC omit the EndOfEarlyData message. See RFC 9001, section 8.3,
@@ -933,7 +933,7 @@ static enum ssl_hs_wait_t do_send_end_of_early_data(SSL_HANDSHAKE *hs) {
static enum ssl_hs_wait_t do_send_client_encrypted_extensions(
SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// For now, only one extension uses client EncryptedExtensions. This function
// may be generalized if others use it in the future.
if (hs->new_session->has_application_settings &&
@@ -984,7 +984,7 @@ static bool check_credential(SSL_HANDSHAKE *hs, const SSLCredential *cred,
}
static enum ssl_hs_wait_t do_send_client_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// The peer didn't request a certificate.
if (!hs->cert_request) {
@@ -1077,7 +1077,7 @@ static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_complete_second_flight(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
hs->can_release_private_key = true;
// Send a Channel ID assertion if necessary.
@@ -1215,7 +1215,7 @@ const char *tls13_client_handshake_state(SSL_HANDSHAKE *hs) {
return "TLS 1.3 client unknown";
}
bool tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg) {
bool tls13_process_new_session_ticket(SSLImpl *ssl, const SSLMessage &msg) {
if (ssl->s3->write_shutdown != ssl_shutdown_none) {
// Ignore tickets on shutdown. Callers tend to indiscriminately call
// `SSL_shutdown` before destroying an `SSL`, at which point calling the new
@@ -1239,7 +1239,8 @@ bool tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg) {
return true;
}
UniquePtr<SSL_SESSION> tls13_create_session_with_ticket(SSL *ssl, CBS *body) {
UniquePtr<SSL_SESSION> tls13_create_session_with_ticket(SSLImpl *ssl,
CBS *body) {
UniquePtr<SSL_SESSION> session = SSL_SESSION_dup(
ssl->s3->established_session.get(), SSL_SESSION_INCLUDE_NONAUTH);
if (!session) {
+8 -7
View File
@@ -177,7 +177,7 @@ static bool derive_secret(SSL_HANDSHAKE *hs,
return derive_secret_with_transcript(hs, out, hs->transcript, label);
}
bool tls13_set_traffic_key(SSL *ssl, enum ssl_encryption_level_t level,
bool tls13_set_traffic_key(SSLImpl *ssl, enum ssl_encryption_level_t level,
enum evp_aead_direction_t direction,
const SSL_SESSION *session,
Span<const uint8_t> traffic_secret) {
@@ -347,7 +347,7 @@ static const char kTLS13LabelClientApplicationTraffic[] = "c ap traffic";
static const char kTLS13LabelServerApplicationTraffic[] = "s ap traffic";
bool tls13_derive_early_secret(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// When offering ECH on the client, early data is associated with
// ClientHelloInner, not ClientHelloOuter.
const SSLTranscript &transcript = (!ssl->server && hs->selected_ech_config)
@@ -363,7 +363,7 @@ bool tls13_derive_early_secret(SSL_HANDSHAKE *hs) {
}
bool tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!derive_secret(hs, &hs->client_handshake_secret,
kTLS13LabelClientHandshakeTraffic) ||
!ssl_log_secret(ssl, "CLIENT_HANDSHAKE_TRAFFIC_SECRET",
@@ -379,7 +379,7 @@ bool tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) {
}
bool tls13_derive_application_secrets(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!derive_secret(hs, &hs->client_traffic_secret_0,
kTLS13LabelClientApplicationTraffic) ||
!ssl_log_secret(ssl, "CLIENT_TRAFFIC_SECRET_0",
@@ -398,7 +398,8 @@ bool tls13_derive_application_secrets(SSL_HANDSHAKE *hs) {
static const char kTLS13LabelApplicationTraffic[] = "traffic upd";
bool tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction) {
bool tls13_rotate_traffic_key(SSLImpl *ssl,
enum evp_aead_direction_t direction) {
InplaceVector<uint8_t, SSL_MAX_MD_SIZE> secret(
direction == evp_aead_open ? ssl->s3->read_traffic_secret
: ssl->s3->write_traffic_secret);
@@ -469,7 +470,7 @@ bool tls13_derive_session_psk(SSL_SESSION *session, Span<const uint8_t> nonce,
static const char kTLS13LabelExportKeying[] = "exporter";
bool tls13_export_keying_material(const SSL *ssl, Span<uint8_t> out,
bool tls13_export_keying_material(const SSLImpl *ssl, Span<uint8_t> out,
Span<const uint8_t> secret,
std::string_view label,
Span<const uint8_t> context) {
@@ -687,7 +688,7 @@ bool tls13_compare_imported_psk_identity(Span<const uint8_t> id,
CBS_len(&cbs) == 0;
}
size_t ssl_ech_confirmation_signal_hello_offset(const SSL *ssl) {
size_t ssl_ech_confirmation_signal_hello_offset(const SSLImpl *ssl) {
static_assert(ECH_CONFIRMATION_SIGNAL_LEN < SSL3_RANDOM_SIZE,
"the confirmation signal is a suffix of the random");
const size_t header_len =
+21 -21
View File
@@ -70,7 +70,7 @@ static bool resolve_pake_secret(SSL_HANDSHAKE *hs) {
static bool resolve_ecdhe_secret(SSL_HANDSHAKE *hs,
const SSL_CLIENT_HELLO *client_hello) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
const uint16_t group_id = hs->new_session->group_id;
bool found_key_share;
@@ -137,7 +137,7 @@ static int ssl_ext_supported_versions_add_serverhello(SSL_HANDSHAKE *hs,
}
static const SSL_CIPHER *choose_tls13_cipher(
const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) {
const SSLImpl *ssl, const SSL_CLIENT_HELLO *client_hello) {
CBS cipher_suites;
CBS_init(&cipher_suites, client_hello->cipher_suites,
client_hello->cipher_suites_len);
@@ -152,7 +152,7 @@ static const SSL_CIPHER *choose_tls13_cipher(
}
static bool add_new_session_tickets(SSL_HANDSHAKE *hs, bool *out_sent_tickets) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if ( // If the client doesn't accept resumption with PSK_DHE_KE, don't send a
// session ticket.
!hs->accept_psk_mode ||
@@ -325,7 +325,7 @@ static bool check_pake_credential(SSL_HANDSHAKE *hs,
static bool check_psk_credential(SSL_HANDSHAKE *hs, const SSLCredential *cred,
const std::optional<SSLOfferedPSKs> &psks) {
assert(cred->type == SSLCredentialType::kPreSharedKey);
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!psks) {
OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
return false;
@@ -357,7 +357,7 @@ static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
// the common handshake logic. Resolve the remaining non-resumption
// parameters. First, parse out another copy of the ClientHello and important
// extensions.
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
SSL_CLIENT_HELLO client_hello;
if (!hs->GetClientHello(&msg, &client_hello)) {
@@ -482,7 +482,7 @@ static enum ssl_ticket_aead_result_t select_session(
SSL_HANDSHAKE *hs, uint8_t *out_alert, UniquePtr<SSL_SESSION> *out_session,
int32_t *out_ticket_age_skew, bool *out_offered_ticket,
const SSLMessage &msg, const SSL_CLIENT_HELLO *client_hello) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
*out_session = nullptr;
CBS pre_shared_key;
@@ -595,7 +595,7 @@ static bool using_certificate(const SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
SSL_CLIENT_HELLO client_hello;
if (!hs->GetClientHello(&msg, &client_hello)) {
@@ -825,7 +825,7 @@ static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (hs->pending_hints != nullptr) {
return ssl_hs_hints_ready;
}
@@ -887,7 +887,7 @@ static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_second_client_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_message;
@@ -998,7 +998,7 @@ static enum ssl_hs_wait_t do_read_second_client_hello(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
Span<uint8_t> random(ssl->s3->server_random);
@@ -1147,7 +1147,7 @@ static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (hs->pending_hints != nullptr) {
return ssl_hs_hints_ready;
}
@@ -1169,7 +1169,7 @@ static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_send_half_rtt_ticket(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl->s3->early_data_accepted) {
// If accepting 0-RTT, we send tickets half-RTT. This gets the tickets on
@@ -1218,14 +1218,14 @@ static enum ssl_hs_wait_t do_send_half_rtt_ticket(SSL_HANDSHAKE *hs) {
return ssl_hs_flush;
}
static bool uses_end_of_early_data(const SSL *ssl) {
static bool uses_end_of_early_data(const SSLImpl *ssl) {
// DTLS and QUIC omit the EndOfEarlyData message. See RFC 9001, section 8.3,
// and RFC 9147, section 5.6.
return !SSL_is_quic(ssl) && !SSL_is_dtls(ssl);
}
static enum ssl_hs_wait_t do_read_second_client_flight(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (ssl->s3->early_data_accepted) {
if (!tls13_set_traffic_key(ssl, ssl_encryption_early_data, evp_aead_open,
hs->new_session.get(),
@@ -1255,7 +1255,7 @@ static enum ssl_hs_wait_t do_read_second_client_flight(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// In protocols that use EndOfEarlyData, we must consume the extra message and
// switch to client_handshake_secret after the early return.
if (uses_end_of_early_data(ssl)) {
@@ -1288,7 +1288,7 @@ static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) {
static enum ssl_hs_wait_t do_read_client_encrypted_extensions(
SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
// For now, only one extension uses client EncryptedExtensions. This function
// may be generalized if others use it in the future.
if (hs->new_session->has_application_settings &&
@@ -1344,7 +1344,7 @@ static enum ssl_hs_wait_t do_read_client_encrypted_extensions(
}
static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!hs->cert_request) {
if (!ssl->s3->session_reused) {
// OpenSSL returns X509_V_OK when no certificates are requested. This is
@@ -1378,7 +1378,7 @@ static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_client_certificate_verify(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!ssl_session_has_peer_cred(hs->new_session.get())) {
// Skip this state.
hs->tls13_state = state13_read_channel_id;
@@ -1412,7 +1412,7 @@ static enum ssl_hs_wait_t do_read_client_certificate_verify(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
if (!hs->channel_id_negotiated) {
hs->tls13_state = state13_read_client_finished;
return ssl_hs_ok;
@@ -1434,7 +1434,7 @@ static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
SSLMessage msg;
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_message;
@@ -1479,7 +1479,7 @@ static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) {
}
static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
SSLImpl *const ssl = hs->ssl;
bool sent_tickets;
if (!add_new_session_tickets(hs, &sent_tickets)) {
return ssl_hs_error;
+5 -5
View File
@@ -25,7 +25,7 @@
BSSL_NAMESPACE_BEGIN
static void tls_on_handshake_complete(SSL *ssl) {
static void tls_on_handshake_complete(SSLImpl *ssl) {
// The handshake should have released its final message.
assert(!ssl->s3->has_message);
@@ -40,7 +40,7 @@ static void tls_on_handshake_complete(SSL *ssl) {
}
}
static bool tls_set_read_state(SSL *ssl, ssl_encryption_level_t level,
static bool tls_set_read_state(SSLImpl *ssl, ssl_encryption_level_t level,
UniquePtr<SSLAEADContext> aead_ctx,
Span<const uint8_t> traffic_secret) {
// Cipher changes are forbidden if the current epoch has leftover data.
@@ -72,7 +72,7 @@ static bool tls_set_read_state(SSL *ssl, ssl_encryption_level_t level,
return true;
}
static bool tls_set_write_state(SSL *ssl, ssl_encryption_level_t level,
static bool tls_set_write_state(SSLImpl *ssl, ssl_encryption_level_t level,
UniquePtr<SSLAEADContext> aead_ctx,
Span<const uint8_t> traffic_secret) {
if (!tls_flush_pending_hs_data(ssl)) {
@@ -101,12 +101,12 @@ static bool tls_set_write_state(SSL *ssl, ssl_encryption_level_t level,
return true;
}
static void tls_finish_flight(SSL *ssl) {
static void tls_finish_flight(SSLImpl *ssl) {
// We don't track whether a flight is complete in TLS and instead always flush
// every queued message in `tls_flush`, whether the flight is complete or not.
}
static void tls_schedule_ack(SSL *ssl) {
static void tls_schedule_ack(SSLImpl *ssl) {
// TLS does not use ACKs.
}
+23 -20
View File
@@ -46,7 +46,7 @@ static const uint8_t kMaxWarningAlerts = 4;
// ssl_needs_record_splitting returns one if `ssl`'s current outgoing cipher
// state needs record-splitting and zero otherwise.
bool ssl_needs_record_splitting(const SSL *ssl) {
bool ssl_needs_record_splitting(const SSLImpl *ssl) {
return !CRYPTO_fuzzer_mode_enabled() &&
!ssl->s3->aead_write_ctx->is_null_cipher() &&
ssl_protocol_version(ssl) < TLS1_1_VERSION &&
@@ -54,12 +54,12 @@ bool ssl_needs_record_splitting(const SSL *ssl) {
SSL_CIPHER_is_block_cipher(ssl->s3->aead_write_ctx->cipher());
}
size_t ssl_record_prefix_len(const SSL *ssl) {
size_t ssl_record_prefix_len(const SSLImpl *ssl) {
assert(!SSL_is_dtls(ssl));
return SSL3_RT_HEADER_LENGTH + ssl->s3->aead_read_ctx->ExplicitNonceLen();
}
static ssl_open_record_t skip_early_data(SSL *ssl, uint8_t *out_alert,
static ssl_open_record_t skip_early_data(SSLImpl *ssl, uint8_t *out_alert,
size_t consumed) {
ssl->s3->early_data_skipped += consumed;
if (ssl->s3->early_data_skipped < consumed) {
@@ -75,7 +75,7 @@ static ssl_open_record_t skip_early_data(SSL *ssl, uint8_t *out_alert,
return ssl_open_record_discard;
}
static uint16_t tls_record_version(const SSL *ssl) {
static uint16_t tls_record_version(const SSLImpl *ssl) {
if (ssl->s3->version == 0) {
// Before the version is determined, outgoing records use TLS 1.0 for
// historical compatibility requirements.
@@ -88,7 +88,7 @@ static uint16_t tls_record_version(const SSL *ssl) {
: ssl->s3->version;
}
ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type,
ssl_open_record_t tls_open_record(SSLImpl *ssl, uint8_t *out_type,
Span<uint8_t> *out, size_t *out_consumed,
uint8_t *out_alert, Span<uint8_t> in) {
*out_consumed = 0;
@@ -263,7 +263,7 @@ ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type,
return ssl_open_record_success;
}
static bool do_seal_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out,
static bool do_seal_record(SSLImpl *ssl, uint8_t *out_prefix, uint8_t *out,
uint8_t *out_suffix, uint8_t type, const uint8_t *in,
const size_t in_len) {
SSLAEADContext *aead = ssl->s3->aead_write_ctx.get();
@@ -316,7 +316,7 @@ static bool do_seal_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out,
return true;
}
static size_t tls_seal_scatter_prefix_len(const SSL *ssl, uint8_t type,
static size_t tls_seal_scatter_prefix_len(const SSLImpl *ssl, uint8_t type,
size_t in_len) {
size_t ret = SSL3_RT_HEADER_LENGTH;
if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 &&
@@ -333,8 +333,9 @@ static size_t tls_seal_scatter_prefix_len(const SSL *ssl, uint8_t type,
return ret;
}
static bool tls_seal_scatter_suffix_len(const SSL *ssl, size_t *out_suffix_len,
uint8_t type, size_t in_len) {
static bool tls_seal_scatter_suffix_len(const SSLImpl *ssl,
size_t *out_suffix_len, uint8_t type,
size_t in_len) {
size_t extra_in_len = 0;
if (!ssl->s3->aead_write_ctx->is_null_cipher() &&
ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
@@ -361,9 +362,10 @@ static bool tls_seal_scatter_suffix_len(const SSL *ssl, size_t *out_suffix_len,
// returns one on success and zero on error. If enabled,
// `tls_seal_scatter_record` implements TLS 1.0 CBC 1/n-1 record splitting and
// may write two records concatenated.
static bool tls_seal_scatter_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out,
uint8_t *out_suffix, uint8_t type,
const uint8_t *in, size_t in_len) {
static bool tls_seal_scatter_record(SSLImpl *ssl, uint8_t *out_prefix,
uint8_t *out, uint8_t *out_suffix,
uint8_t type, const uint8_t *in,
size_t in_len) {
if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 &&
ssl_needs_record_splitting(ssl)) {
assert(ssl->s3->aead_write_ctx->ExplicitNonceLen() == 0);
@@ -406,7 +408,7 @@ static bool tls_seal_scatter_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out,
return do_seal_record(ssl, out_prefix, out, out_suffix, type, in, in_len);
}
bool tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len,
bool tls_seal_record(SSLImpl *ssl, uint8_t *out, size_t *out_len,
size_t max_out_len, uint8_t type, const uint8_t *in,
size_t in_len) {
if (buffers_alias(in, in_len, out, max_out_len)) {
@@ -440,7 +442,7 @@ bool tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len,
return true;
}
enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert,
enum ssl_open_record_t ssl_process_alert(SSLImpl *ssl, uint8_t *out_alert,
Span<const uint8_t> in) {
// Alerts records may not contain fragmented or multiple alerts.
if (in.size() != 2) {
@@ -502,19 +504,20 @@ BSSL_NAMESPACE_END
using namespace bssl;
size_t SSL_max_seal_overhead(const SSL *ssl) {
if (SSL_is_dtls(ssl)) {
const auto *ssl_impl = FromOpaque(ssl);
if (SSL_is_dtls(ssl_impl)) {
// TODO(crbug.com/381113363): Use the 0-RTT epoch if writing 0-RTT.
return dtls_max_seal_overhead(ssl, ssl->d1->write_epoch.epoch());
return dtls_max_seal_overhead(ssl_impl, ssl_impl->d1->write_epoch.epoch());
}
size_t ret = SSL3_RT_HEADER_LENGTH;
ret += ssl->s3->aead_write_ctx->MaxOverhead();
ret += ssl_impl->s3->aead_write_ctx->MaxOverhead();
// TLS 1.3 needs an extra byte for the encrypted record type.
if (!ssl->s3->aead_write_ctx->is_null_cipher() &&
ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
if (!ssl_impl->s3->aead_write_ctx->is_null_cipher() &&
ssl_protocol_version(ssl_impl) >= TLS1_3_VERSION) {
ret += 1;
}
if (ssl_needs_record_splitting(ssl)) {
if (ssl_needs_record_splitting(ssl_impl)) {
ret *= 2;
}
return ret;