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>
diff --git a/fuzz/decode_client_hello_inner.cc b/fuzz/decode_client_hello_inner.cc index 42f9270..6291712 100644 --- a/fuzz/decode_client_hello_inner.cc +++ b/fuzz/decode_client_hello_inner.cc
@@ -47,7 +47,7 @@ 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; }
diff --git a/ssl/d1_both.cc b/ssl/d1_both.cc index 7b63d43..ccc2f52 100644 --- a/ssl/d1_both.cc +++ b/ssl/d1_both.cc
@@ -210,7 +210,7 @@ // 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 @@ // 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 @@ 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 @@ 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 @@ } } -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 @@ 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 @@ } } -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 @@ 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 @@ // 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 @@ 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 @@ }); } -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 @@ 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 @@ // 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 @@ 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 @@ // 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 @@ // 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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);
diff --git a/ssl/d1_lib.cc b/ssl/d1_lib.cc index f6f89ca..765fc16 100644 --- a/ssl/d1_lib.cc +++ b/ssl/d1_lib.cc
@@ -63,7 +63,7 @@ return true; } -bool dtls1_new(SSL *ssl) { +bool dtls1_new(SSLImpl *ssl) { if (!tls_new(ssl)) { return false; } @@ -77,7 +77,7 @@ return true; } -void dtls1_free(SSL *ssl) { +void dtls1_free(SSLImpl *ssl) { tls_free(ssl); if (ssl == nullptr) { @@ -124,7 +124,7 @@ 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 @@ 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 @@ } // 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_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 @@ return 0; } - return dtls1_flush(ssl); + return dtls1_flush(ssl_impl); }
diff --git a/ssl/d1_pkt.cc b/ssl/d1_pkt.cc index e09e479..e08ad80 100644 --- a/ssl/d1_pkt.cc +++ b/ssl/d1_pkt.cc
@@ -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 @@ 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 @@ 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 @@ 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 @@ 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) {
diff --git a/ssl/d1_srtp.cc b/ssl/d1_srtp.cc index ab1f73d..be2378a 100644 --- a/ssl/d1_srtp.cc +++ b/ssl/d1_srtp.cc
@@ -92,27 +92,29 @@ } 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) {
diff --git a/ssl/dtls_method.cc b/ssl/dtls_method.cc index 9a3c925..a35e192 100644 --- a/ssl/dtls_method.cc +++ b/ssl/dtls_method.cc
@@ -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 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 @@ 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 @@ 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;
diff --git a/ssl/dtls_record.cc b/ssl/dtls_record.cc index c0fe668..6b4292a 100644 --- a/ssl/dtls_record.cc +++ b/ssl/dtls_record.cc
@@ -56,7 +56,7 @@ } } -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 @@ : 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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);
diff --git a/ssl/encrypted_client_hello.cc b/ssl/encrypted_client_hello.cc index eacc375..46ba196 100644 --- a/ssl/encrypted_client_hello.cc +++ b/ssl/encrypted_client_hello.cc
@@ -90,7 +90,7 @@ 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 @@ } 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 @@ } 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 @@ 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 @@ 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_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_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; }
diff --git a/ssl/extensions.cc b/ssl/extensions.cc index 1f29be1..022714a 100644 --- a/ssl/extensions.cc +++ b/ssl/extensions.cc
@@ -115,10 +115,10 @@ } } -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 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 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 @@ } 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_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_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_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_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_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_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_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 @@ // 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 @@ 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_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_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_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 @@ // 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 @@ 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 @@ 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_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_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_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_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 @@ 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_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_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 @@ 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 @@ // 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 @@ // 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_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 @@ 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_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_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 @@ } 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 @@ 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_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_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_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_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 @@ 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) {
diff --git a/ssl/handoff.cc b/ssl/handoff.cc index b00514e..c8d9897 100644 --- a/ssl/handoff.cc +++ b/ssl/handoff.cc
@@ -80,8 +80,9 @@ 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 @@ 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_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 @@ // (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 @@ // 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 @@ 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_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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 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 @@ } 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 @@ return 0; } - ssl->s3->hs->provided_hints = std::move(hints_obj); + ssl_impl->s3->hs->provided_hints = std::move(hints_obj); return 1; }
diff --git a/ssl/handshake.cc b/ssl/handshake.cc index 09a1763..5103fe9 100644 --- a/ssl/handshake.cc +++ b/ssl/handshake.cc
@@ -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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ // 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 @@ } 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 @@ } 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 @@ } 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
diff --git a/ssl/handshake_client.cc b/ssl/handshake_client.cc index af70197..a4a53cd 100644 --- a/ssl/handshake_client.cc +++ b/ssl/handshake_client.cc
@@ -93,7 +93,7 @@ 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 @@ 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_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 @@ // 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 @@ } 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_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_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 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 @@ } 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_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_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_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_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_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 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 @@ "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_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_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 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 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_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_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_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;
diff --git a/ssl/handshake_server.cc b/ssl/handshake_server.cc index 2046db0..64ea061 100644 --- a/ssl/handshake_server.cc +++ b/ssl/handshake_server.cc
@@ -65,7 +65,7 @@ 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 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 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 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 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_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_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_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 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_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_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_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_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_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_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_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_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_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_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_finish_server_handshake(SSL_HANDSHAKE *hs) { - SSL *const ssl = hs->ssl; + SSLImpl *const ssl = hs->ssl; if (hs->handback) { return ssl_hs_handback;
diff --git a/ssl/internal.h b/ssl/internal.h index bdd6320..30b2269 100644 --- a/ssl/internal.h +++ b/ssl/internal.h
@@ -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 @@ // 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 @@ // // 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 @@ // // 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 @@ // `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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // // 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ // // 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 @@ // 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 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 @@ // 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 @@ // 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 @@ 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 @@ // 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 @@ // `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 @@ // 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 @@ // // 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 @@ // // 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 @@ // 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 @@ // 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 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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_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 @@ 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 @@ // 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 @@ 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 @@ // 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);
diff --git a/ssl/s3_both.cc b/ssl/s3_both.cc index c08e381..d885da9 100644 --- a/ssl/s3_both.cc +++ b/ssl/s3_both.cc
@@ -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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 || //
diff --git a/ssl/s3_lib.cc b/ssl/s3_lib.cc index a58242a..f1f88b9 100644 --- a/ssl/s3_lib.cc +++ b/ssl/s3_lib.cc
@@ -49,7 +49,7 @@ 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 @@ return true; } -void tls_free(SSL *ssl) { +void tls_free(SSLImpl *ssl) { if (ssl->s3 == nullptr) { return; }
diff --git a/ssl/s3_pkt.cc b/ssl/s3_pkt.cc index 6eb797f..2724e32 100644 --- a/ssl/s3_pkt.cc +++ b/ssl/s3_pkt.cc
@@ -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 @@ // // 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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])) {
diff --git a/ssl/ssl_buffer.cc b/ssl/ssl_buffer.cc index e6a2b04..9cb1298 100644 --- a/ssl/ssl_buffer.cc +++ b/ssl/ssl_buffer.cc
@@ -116,7 +116,7 @@ } } -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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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;
diff --git a/ssl/ssl_cert.cc b/ssl/ssl_cert.cc index 46ed23e..7455162 100644 --- a/ssl/ssl_cert.cc +++ b/ssl/ssl_cert.cc
@@ -405,7 +405,7 @@ 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 @@ 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 @@ } 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_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_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_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_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_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_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_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); }
diff --git a/ssl/ssl_credential.cc b/ssl/ssl_credential.cc index cd522d3..87bf24c 100644 --- a/ssl/ssl_credential.cc +++ b/ssl/ssl_credential.cc
@@ -668,8 +668,9 @@ } 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 @@ 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,
diff --git a/ssl/ssl_file.cc b/ssl/ssl_file.cc index 92143c3..c7d4645 100644 --- a/ssl/ssl_file.cc +++ b/ssl/ssl_file.cc
@@ -130,6 +130,7 @@ } 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 @@ 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_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 @@ } 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_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 @@ 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));
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc index fd287f5..e05f91b 100644 --- a/ssl/ssl_lib.cc +++ b/ssl/ssl_lib.cc
@@ -72,7 +72,7 @@ static ExDataClass g_ex_data_class_ssl(/*with_app_data=*/true); static ExDataClass g_ex_data_class_ssl_ctx(/*with_app_data=*/true); -void ssl_reset_error_state(SSL *ssl) { +void ssl_reset_error_state(SSLImpl *ssl) { // Functions which use `SSL_get_error` must reset I/O and error state on // entry. ssl->s3->rwstate = SSL_ERROR_NONE; @@ -80,12 +80,12 @@ ERR_clear_system_error(); } -void ssl_set_read_error(SSL *ssl) { +void ssl_set_read_error(SSLImpl *ssl) { ssl->s3->read_shutdown = ssl_shutdown_error; ssl->s3->read_error.reset(ERR_save_state()); } -static bool check_read_error(const SSL *ssl) { +static bool check_read_error(const SSLImpl *ssl) { if (ssl->s3->read_shutdown == ssl_shutdown_error) { ERR_restore_state(ssl->s3->read_error.get()); return false; @@ -93,15 +93,15 @@ return true; } -bool ssl_can_write(const SSL *ssl) { +bool ssl_can_write(const SSLImpl *ssl) { return !SSL_in_init(ssl) || ssl->s3->hs->can_early_write; } -bool ssl_can_read(const SSL *ssl) { +bool ssl_can_read(const SSLImpl *ssl) { return !SSL_in_init(ssl) || ssl->s3->hs->can_early_read; } -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) { *out_consumed = 0; if (!check_read_error(ssl)) { @@ -115,7 +115,8 @@ return ret; } -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) { *out_consumed = 0; @@ -131,7 +132,7 @@ return ret; } -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) { *out_consumed = 0; @@ -166,7 +167,7 @@ return true; } -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) { if (ssl->ctx->keylog_callback == nullptr) { return true; @@ -193,7 +194,7 @@ return true; } -void ssl_do_info_callback(const SSL *ssl, int type, int value) { +void ssl_do_info_callback(const SSLImpl *ssl, int type, int value) { void (*cb)(const SSL *ssl, int type, int value) = nullptr; if (ssl->info_callback != nullptr) { cb = ssl->info_callback; @@ -206,7 +207,7 @@ } } -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) { if (ssl->msg_callback == nullptr) { return; @@ -228,7 +229,7 @@ } ssl->msg_callback(is_write, version, content_type, in.data(), in.size(), - const_cast<SSL *>(ssl), ssl->msg_callback_arg); + const_cast<SSLImpl *>(ssl), ssl->msg_callback_arg); } OPENSSL_timeval ssl_ctx_get_current_time(const SSLContext *ctx) { @@ -273,7 +274,7 @@ FromOpaque(ctx)->handoff = on; } -static bool ssl_can_renegotiate(const SSL *ssl) { +static bool ssl_can_renegotiate(const SSLImpl *ssl) { if (ssl->server || SSL_is_dtls(ssl)) { return false; } @@ -304,7 +305,7 @@ return false; } -static void ssl_maybe_shed_handshake_config(SSL *ssl) { +static void ssl_maybe_shed_handshake_config(SSLImpl *ssl) { if (ssl->s3->hs != nullptr || // ssl->config == nullptr || // !ssl->config->shed_handshake_config || // @@ -316,35 +317,37 @@ } void SSL_set_handoff_mode(SSL *ssl, bool on) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return; } - ssl->config->handoff = on; + ssl_impl->config->handoff = on; } bool SSL_get_traffic_secrets(const SSL *ssl, Span<const uint8_t> *out_read_traffic_secret, Span<const uint8_t> *out_write_traffic_secret) { + const auto *ssl_impl = FromOpaque(ssl); // This API is not well-defined for DTLS, where multiple epochs may be alive // at once. Callers should use `SSL_get_dtls_*_traffic_secret` instead. In // QUIC, the application is already handed the traffic secret. - if (SSL_is_dtls(ssl) || SSL_is_quic(ssl)) { + if (SSL_is_dtls(ssl_impl) || SSL_is_quic(ssl_impl)) { OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return false; } - if (!ssl->s3->initial_handshake_complete) { + if (!ssl_impl->s3->initial_handshake_complete) { OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); return false; } - if (SSL_version(ssl) < TLS1_3_VERSION) { + if (SSL_version(ssl_impl) < TLS1_3_VERSION) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION); return false; } - *out_read_traffic_secret = ssl->s3->read_traffic_secret; - *out_write_traffic_secret = ssl->s3->write_traffic_secret; + *out_read_traffic_secret = ssl_impl->s3->read_traffic_secret; + *out_write_traffic_secret = ssl_impl->s3->write_traffic_secret; return true; } @@ -356,8 +359,9 @@ } void SSL_set_aes_hw_override_for_testing(SSL *ssl, bool override_value) { - ssl->config->aes_hw_override = true; - ssl->config->aes_hw_override_value = override_value; + auto *ssl_impl = FromOpaque(ssl); + ssl_impl->config->aes_hw_override = true; + ssl_impl->config->aes_hw_override_value = override_value; } BSSL_NAMESPACE_END @@ -467,7 +471,7 @@ } } -ssl_st::ssl_st(SSLContext *ctx_arg) +bssl::SSLImpl::SSLImpl(SSLContext *ctx_arg) : method(ctx_arg->method), max_send_fragment(ctx_arg->max_send_fragment), msg_callback(ctx_arg->msg_callback), @@ -484,7 +488,7 @@ CRYPTO_new_ex_data(&ex_data); } -ssl_st::~ssl_st() { +bssl::SSLImpl::~SSLImpl() { CRYPTO_free_ex_data(&g_ex_data_class_ssl, &ex_data); // `config` refers to `this`, so we must release it earlier. config.reset(); @@ -500,7 +504,7 @@ return nullptr; } - UniquePtr<SSL> ssl = MakeUnique<SSL>(ctx_impl); + UniquePtr<SSLImpl> ssl = MakeUnique<SSLImpl>(ctx_impl); if (ssl == nullptr) { return nullptr; } @@ -576,7 +580,7 @@ return ssl.release(); } -SSL_CONFIG::SSL_CONFIG(SSL *ssl_arg) +SSL_CONFIG::SSL_CONFIG(SSLImpl *ssl_arg) : ssl(ssl_arg), ech_grease_enabled(false), signed_cert_timestamps_enabled(false), @@ -599,21 +603,23 @@ } } -void SSL_free(SSL *ssl) { Delete(ssl); } +void SSL_free(SSL *ssl) { Delete(FromOpaque(ssl)); } void SSL_set_connect_state(SSL *ssl) { - ssl->server = false; - ssl->do_handshake = ssl_client_handshake; + auto *ssl_impl = FromOpaque(ssl); + ssl_impl->server = false; + ssl_impl->do_handshake = ssl_client_handshake; } void SSL_set_accept_state(SSL *ssl) { - ssl->server = true; - ssl->do_handshake = ssl_server_handshake; + auto *ssl_impl = FromOpaque(ssl); + ssl_impl->server = true; + ssl_impl->do_handshake = ssl_server_handshake; } -void SSL_set0_rbio(SSL *ssl, BIO *rbio) { ssl->rbio.reset(rbio); } +void SSL_set0_rbio(SSL *ssl, BIO *rbio) { FromOpaque(ssl)->rbio.reset(rbio); } -void SSL_set0_wbio(SSL *ssl, BIO *wbio) { ssl->wbio.reset(wbio); } +void SSL_set0_wbio(SSL *ssl, BIO *wbio) { FromOpaque(ssl)->wbio.reset(wbio); } void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) { // For historical reasons, this function has many different cases in ownership @@ -649,12 +655,13 @@ SSL_set0_wbio(ssl, wbio); } -BIO *SSL_get_rbio(const SSL *ssl) { return ssl->rbio.get(); } +BIO *SSL_get_rbio(const SSL *ssl) { return FromOpaque(ssl)->rbio.get(); } -BIO *SSL_get_wbio(const SSL *ssl) { return ssl->wbio.get(); } +BIO *SSL_get_wbio(const SSL *ssl) { return FromOpaque(ssl)->wbio.get(); } size_t SSL_quic_max_handshake_flight_len(const SSL *ssl, enum ssl_encryption_level_t level) { + const auto *ssl_impl = FromOpaque(ssl); // Limits flights to 16K by default when there are no large // (certificate-carrying) messages. static const size_t kDefaultLimit = 16384; @@ -666,18 +673,18 @@ // QUIC does not send EndOfEarlyData. return 0; case ssl_encryption_handshake: - if (ssl->server) { + if (ssl_impl->server) { // Servers may receive Certificate message if configured to request // client certificates. - if (!!(ssl->config->verify_mode & SSL_VERIFY_PEER) && - ssl->max_cert_list > kDefaultLimit) { - return ssl->max_cert_list; + if (!!(ssl_impl->config->verify_mode & SSL_VERIFY_PEER) && + ssl_impl->max_cert_list > kDefaultLimit) { + return ssl_impl->max_cert_list; } } else { // Clients may receive both Certificate message and a CertificateRequest // message. - if (2 * ssl->max_cert_list > kDefaultLimit) { - return 2 * ssl->max_cert_list; + if (2 * ssl_impl->max_cert_list > kDefaultLimit) { + return 2 * ssl_impl->max_cert_list; } } return kDefaultLimit; @@ -693,70 +700,74 @@ enum ssl_encryption_level_t SSL_quic_read_level(const SSL *ssl) { assert(SSL_is_quic(ssl)); - return ssl->s3->quic_read_level; + return FromOpaque(ssl)->s3->quic_read_level; } enum ssl_encryption_level_t SSL_quic_write_level(const SSL *ssl) { assert(SSL_is_quic(ssl)); - return ssl->s3->quic_write_level; + return FromOpaque(ssl)->s3->quic_write_level; } int SSL_provide_quic_data(SSL *ssl, enum ssl_encryption_level_t level, const uint8_t *data, size_t len) { - if (!SSL_is_quic(ssl)) { + auto *ssl_impl = FromOpaque(ssl); + if (!SSL_is_quic(ssl_impl)) { OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (level != ssl->s3->quic_read_level) { + if (level != ssl_impl->s3->quic_read_level) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED); return 0; } - size_t new_len = (ssl->s3->hs_buf ? ssl->s3->hs_buf->length : 0) + len; + size_t new_len = + (ssl_impl->s3->hs_buf ? ssl_impl->s3->hs_buf->length : 0) + len; if (new_len < len || - new_len > SSL_quic_max_handshake_flight_len(ssl, level)) { + new_len > SSL_quic_max_handshake_flight_len(ssl_impl, level)) { OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE); return 0; } - return tls_append_handshake_data(ssl, Span(data, len)); + return tls_append_handshake_data(ssl_impl, Span(data, len)); } int SSL_do_handshake(SSL *ssl) { - ssl_reset_error_state(ssl); + auto *ssl_impl = FromOpaque(ssl); + ssl_reset_error_state(ssl_impl); - if (ssl->do_handshake == nullptr) { + if (ssl_impl->do_handshake == nullptr) { OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_TYPE_NOT_SET); return -1; } - if (!SSL_in_init(ssl)) { + if (!SSL_in_init(ssl_impl)) { return 1; } // Run the handshake. - SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + SSL_HANDSHAKE *hs = ssl_impl->s3->hs.get(); bool early_return = false; int ret = ssl_run_handshake(hs, &early_return); ssl_do_info_callback( - ssl, ssl->server ? SSL_CB_ACCEPT_EXIT : SSL_CB_CONNECT_EXIT, ret); + ssl_impl, ssl_impl->server ? SSL_CB_ACCEPT_EXIT : SSL_CB_CONNECT_EXIT, + ret); if (ret <= 0) { return ret; } // Destroy the handshake object if the handshake has completely finished. if (!early_return) { - ssl->s3->hs.reset(); - ssl_maybe_shed_handshake_config(ssl); + ssl_impl->s3->hs.reset(); + ssl_maybe_shed_handshake_config(ssl_impl); } return 1; } int SSL_connect(SSL *ssl) { - if (ssl->do_handshake == nullptr) { + if (FromOpaque(ssl)->do_handshake == nullptr) { // Not properly initialized yet SSL_set_connect_state(ssl); } @@ -765,7 +776,7 @@ } int SSL_accept(SSL *ssl) { - if (ssl->do_handshake == nullptr) { + if (FromOpaque(ssl)->do_handshake == nullptr) { // Not properly initialized yet SSL_set_accept_state(ssl); } @@ -773,7 +784,7 @@ return SSL_do_handshake(ssl); } -static int ssl_do_post_handshake(SSL *ssl, const SSLMessage &msg) { +static int ssl_do_post_handshake(SSLImpl *ssl, const SSLMessage &msg) { if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { return tls13_post_handshake(ssl, msg); } @@ -810,33 +821,34 @@ } int SSL_process_quic_post_handshake(SSL *ssl) { - ssl_reset_error_state(ssl); + auto *ssl_impl = FromOpaque(ssl); + ssl_reset_error_state(ssl_impl); - if (!SSL_is_quic(ssl) || SSL_in_init(ssl)) { + if (!SSL_is_quic(ssl_impl) || SSL_in_init(ssl_impl)) { OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } // Replay post-handshake message errors. - if (!check_read_error(ssl)) { + if (!check_read_error(ssl_impl)) { return 0; } // Process any buffered post-handshake messages. SSLMessage msg; - while (ssl->method->get_message(ssl, &msg)) { + while (ssl_impl->method->get_message(ssl_impl, &msg)) { // Handle the post-handshake message and try again. - if (!ssl_do_post_handshake(ssl, msg)) { - ssl_set_read_error(ssl); + if (!ssl_do_post_handshake(ssl_impl, msg)) { + ssl_set_read_error(ssl_impl); return 0; } - ssl->method->next_message(ssl); + ssl_impl->method->next_message(ssl_impl); } return 1; } -static int ssl_read_impl(SSL *ssl) { +static int ssl_read_impl(SSLImpl *ssl) { ssl_reset_error_state(ssl); if (ssl->do_handshake == nullptr) { @@ -916,27 +928,29 @@ } int SSL_read(SSL *ssl, void *buf, int num) { - int ret = SSL_peek(ssl, buf, num); + auto *ssl_impl = FromOpaque(ssl); + int ret = SSL_peek(ssl_impl, buf, num); if (ret <= 0) { return ret; } // TODO(davidben): In DTLS, should the rest of the record be discarded? DTLS // is not a stream. See https://crbug.com/boringssl/65. - ssl->s3->pending_app_data = - ssl->s3->pending_app_data.subspan(static_cast<size_t>(ret)); - if (ssl->s3->pending_app_data.empty()) { - ssl->s3->read_buffer.DiscardConsumed(); + ssl_impl->s3->pending_app_data = + ssl_impl->s3->pending_app_data.subspan(static_cast<size_t>(ret)); + if (ssl_impl->s3->pending_app_data.empty()) { + ssl_impl->s3->read_buffer.DiscardConsumed(); } return ret; } int SSL_peek(SSL *ssl, void *buf, int num) { - if (SSL_is_quic(ssl)) { + auto *ssl_impl = FromOpaque(ssl); + if (SSL_is_quic(ssl_impl)) { OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; } - int ret = ssl_read_impl(ssl); + int ret = ssl_read_impl(ssl_impl); if (ret <= 0) { return ret; } @@ -944,20 +958,21 @@ return num; } size_t todo = - std::min(ssl->s3->pending_app_data.size(), static_cast<size_t>(num)); - OPENSSL_memcpy(buf, ssl->s3->pending_app_data.data(), todo); + std::min(ssl_impl->s3->pending_app_data.size(), static_cast<size_t>(num)); + OPENSSL_memcpy(buf, ssl_impl->s3->pending_app_data.data(), todo); return static_cast<int>(todo); } int SSL_write(SSL *ssl, const void *buf, int num) { - ssl_reset_error_state(ssl); + auto *ssl_impl = FromOpaque(ssl); + ssl_reset_error_state(ssl_impl); - if (SSL_is_quic(ssl)) { + if (SSL_is_quic(ssl_impl)) { OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; } - if (ssl->do_handshake == nullptr) { + if (ssl_impl->do_handshake == nullptr) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED); return -1; } @@ -967,8 +982,8 @@ bool needs_handshake = false; do { // If necessary, complete the handshake implicitly. - if (!ssl_can_write(ssl)) { - ret = SSL_do_handshake(ssl); + if (!ssl_can_write(ssl_impl)) { + ret = SSL_do_handshake(ssl_impl); if (ret < 0) { return ret; } @@ -982,43 +997,45 @@ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); return -1; } - ret = ssl->method->write_app_data( - ssl, &needs_handshake, &bytes_written, + ret = ssl_impl->method->write_app_data( + ssl_impl, &needs_handshake, &bytes_written, Span(static_cast<const uint8_t *>(buf), static_cast<size_t>(num))); } while (needs_handshake); return ret <= 0 ? ret : static_cast<int>(bytes_written); } int SSL_key_update(SSL *ssl, int request_type) { - ssl_reset_error_state(ssl); + auto *ssl_impl = FromOpaque(ssl); + ssl_reset_error_state(ssl_impl); - if (ssl->do_handshake == nullptr) { + if (ssl_impl->do_handshake == nullptr) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED); return 0; } - if (SSL_is_quic(ssl)) { + if (SSL_is_quic(ssl_impl)) { OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (!ssl->s3->initial_handshake_complete) { + if (!ssl_impl->s3->initial_handshake_complete) { OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); return 0; } - if (ssl_protocol_version(ssl) < TLS1_3_VERSION) { + if (ssl_protocol_version(ssl_impl) < TLS1_3_VERSION) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION); return 0; } - return tls13_add_key_update(ssl, request_type); + return tls13_add_key_update(ssl_impl, request_type); } int SSL_shutdown(SSL *ssl) { - ssl_reset_error_state(ssl); + auto *ssl_impl = FromOpaque(ssl); + ssl_reset_error_state(ssl_impl); - if (ssl->do_handshake == nullptr) { + if (ssl_impl->do_handshake == nullptr) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED); return -1; } @@ -1026,14 +1043,14 @@ // If we are in the middle of a handshake, silently succeed. Consumers often // call this function before `SSL_free`, whether the handshake succeeded or // not. We assume the caller has already handled failed handshakes. - if (SSL_in_init(ssl)) { + if (SSL_in_init(ssl_impl)) { return 1; } - if (ssl->quiet_shutdown) { + if (ssl_impl->quiet_shutdown) { // Do nothing if configured not to send a close_notify. - ssl->s3->write_shutdown = ssl_shutdown_close_notify; - ssl->s3->read_shutdown = ssl_shutdown_close_notify; + ssl_impl->s3->write_shutdown = ssl_shutdown_close_notify; + ssl_impl->s3->read_shutdown = ssl_shutdown_close_notify; return 1; } @@ -1041,75 +1058,80 @@ // waits for a close_notify to come in. Perform exactly one action and return // whether or not it succeeds. - if (ssl->s3->write_shutdown != ssl_shutdown_close_notify) { + if (ssl_impl->s3->write_shutdown != ssl_shutdown_close_notify) { // Send a close_notify. - if (ssl_send_alert_impl(ssl, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY) <= 0) { + if (ssl_send_alert_impl(ssl_impl, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY) <= + 0) { return -1; } - } else if (ssl->s3->alert_dispatch) { + } else if (ssl_impl->s3->alert_dispatch) { // Finish sending the close_notify. - if (ssl->method->dispatch_alert(ssl) <= 0) { + if (ssl_impl->method->dispatch_alert(ssl_impl) <= 0) { return -1; } - } else if (ssl->s3->read_shutdown != ssl_shutdown_close_notify) { - if (SSL_is_dtls(ssl)) { + } else if (ssl_impl->s3->read_shutdown != ssl_shutdown_close_notify) { + if (SSL_is_dtls(ssl_impl)) { // Bidirectional shutdown doesn't make sense for an unordered // transport. DTLS alerts also aren't delivered reliably, so we may even // time out because the peer never received our close_notify. Report to // the caller that the channel has fully shut down. - if (ssl->s3->read_shutdown == ssl_shutdown_error) { - ERR_restore_state(ssl->s3->read_error.get()); + if (ssl_impl->s3->read_shutdown == ssl_shutdown_error) { + ERR_restore_state(ssl_impl->s3->read_error.get()); return -1; } - ssl->s3->read_shutdown = ssl_shutdown_close_notify; + ssl_impl->s3->read_shutdown = ssl_shutdown_close_notify; } else { // Process records until an error, close_notify, or application data. - if (ssl_read_impl(ssl) > 0) { + if (ssl_read_impl(ssl_impl) > 0) { // We received some unexpected application data. OPENSSL_PUT_ERROR(SSL, SSL_R_APPLICATION_DATA_ON_SHUTDOWN); return -1; } - if (ssl->s3->read_shutdown != ssl_shutdown_close_notify) { + if (ssl_impl->s3->read_shutdown != ssl_shutdown_close_notify) { return -1; } } } // Return 0 for unidirectional shutdown and 1 for bidirectional shutdown. - return ssl->s3->read_shutdown == ssl_shutdown_close_notify; + return ssl_impl->s3->read_shutdown == ssl_shutdown_close_notify; } int SSL_send_fatal_alert(SSL *ssl, uint8_t alert) { - if (ssl->s3->alert_dispatch) { - if (ssl->s3->send_alert[0] != SSL3_AL_FATAL || - ssl->s3->send_alert[1] != alert) { + auto *ssl_impl = FromOpaque(ssl); + if (ssl_impl->s3->alert_dispatch) { + if (ssl_impl->s3->send_alert[0] != SSL3_AL_FATAL || + ssl_impl->s3->send_alert[1] != alert) { // We are already attempting to write a different alert. OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); return -1; } - return ssl->method->dispatch_alert(ssl); + return ssl_impl->method->dispatch_alert(ssl_impl); } - return ssl_send_alert_impl(ssl, SSL3_AL_FATAL, alert); + return ssl_send_alert_impl(ssl_impl, SSL3_AL_FATAL, alert); } int SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params, size_t params_len) { - return ssl->config && - ssl->config->quic_transport_params.CopyFrom(Span(params, params_len)); + auto *ssl_impl = FromOpaque(ssl); + return ssl_impl->config && ssl_impl->config->quic_transport_params.CopyFrom( + Span(params, params_len)); } void SSL_get_peer_quic_transport_params(const SSL *ssl, const uint8_t **out_params, size_t *out_params_len) { - *out_params = ssl->s3->peer_quic_transport_params.data(); - *out_params_len = ssl->s3->peer_quic_transport_params.size(); + const auto *ssl_impl = FromOpaque(ssl); + *out_params = ssl_impl->s3->peer_quic_transport_params.data(); + *out_params_len = ssl_impl->s3->peer_quic_transport_params.size(); } int SSL_set_quic_early_data_context(SSL *ssl, const uint8_t *context, size_t context_len) { - return ssl->config && ssl->config->quic_early_data_context.CopyFrom( - Span(context, context_len)); + auto *ssl_impl = FromOpaque(ssl); + return ssl_impl->config && ssl_impl->config->quic_early_data_context.CopyFrom( + Span(context, context_len)); } void SSL_CTX_set_early_data_enabled(SSL_CTX *ctx, int enabled) { @@ -1117,22 +1139,24 @@ } void SSL_set_early_data_enabled(SSL *ssl, int enabled) { - ssl->enable_early_data = !!enabled; + FromOpaque(ssl)->enable_early_data = !!enabled; } int SSL_in_early_data(const SSL *ssl) { - if (ssl->s3->hs == nullptr) { + const auto *ssl_impl = FromOpaque(ssl); + if (ssl_impl->s3->hs == nullptr) { return 0; } - return ssl->s3->hs->in_early_data; + return ssl_impl->s3->hs->in_early_data; } int SSL_early_data_accepted(const SSL *ssl) { - return ssl->s3->early_data_accepted; + return FromOpaque(ssl)->s3->early_data_accepted; } void SSL_reset_early_data_reject(SSL *ssl) { - SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + auto *ssl_impl = FromOpaque(ssl); + SSL_HANDSHAKE *hs = ssl_impl->s3->hs.get(); if (hs == nullptr || // hs->wait != ssl_hs_early_data_rejected) { abort(); @@ -1145,12 +1169,12 @@ // Discard any unfinished writes from the perspective of `SSL_write`'s // retry. The handshake will transparently flush out the pending record // (discarded by the server) to keep the framing correct. - ssl->s3->pending_write = {}; - ssl->s3->unreported_bytes_written = 0; + ssl_impl->s3->pending_write = {}; + ssl_impl->s3->unreported_bytes_written = 0; } enum ssl_early_data_reason_t SSL_get_early_data_reason(const SSL *ssl) { - return ssl->s3->early_data_reason; + return FromOpaque(ssl)->s3->early_data_reason; } const char *SSL_early_data_reason_string(enum ssl_early_data_reason_t reason) { @@ -1200,6 +1224,7 @@ } int SSL_get_error(const SSL *ssl, int ret_code) { + const auto *ssl_impl = FromOpaque(ssl); if (ret_code > 0) { return SSL_ERROR_NONE; } @@ -1215,7 +1240,7 @@ } if (ret_code == 0) { - if (ssl->s3->rwstate == SSL_ERROR_ZERO_RETURN) { + if (ssl_impl->s3->rwstate == SSL_ERROR_ZERO_RETURN) { return SSL_ERROR_ZERO_RETURN; } // An EOF was observed which violates the protocol, and the underlying @@ -1224,7 +1249,7 @@ return SSL_ERROR_SYSCALL; } - switch (ssl->s3->rwstate) { + switch (ssl_impl->s3->rwstate) { case SSL_ERROR_PENDING_SESSION: case SSL_ERROR_PENDING_CERTIFICATE: case SSL_ERROR_HANDOFF: @@ -1236,13 +1261,13 @@ case SSL_ERROR_WANT_CERTIFICATE_VERIFY: case SSL_ERROR_WANT_RENEGOTIATE: case SSL_ERROR_HANDSHAKE_HINTS_READY: - return ssl->s3->rwstate; + return ssl_impl->s3->rwstate; case SSL_ERROR_WANT_READ: { - if (SSL_is_quic(ssl)) { + if (SSL_is_quic(ssl_impl)) { return SSL_ERROR_WANT_READ; } - BIO *bio = SSL_get_rbio(ssl); + BIO *bio = SSL_get_rbio(ssl_impl); if (BIO_should_read(bio)) { return SSL_ERROR_WANT_READ; } @@ -1261,7 +1286,7 @@ } case SSL_ERROR_WANT_WRITE: { - BIO *bio = SSL_get_wbio(ssl); + BIO *bio = SSL_get_wbio(ssl_impl); if (BIO_should_write(bio)) { return SSL_ERROR_WANT_WRITE; } @@ -1345,16 +1370,18 @@ } uint32_t SSL_set_options(SSL *ssl, uint32_t options) { - ssl->options |= options; - return ssl->options; + auto *ssl_impl = FromOpaque(ssl); + ssl_impl->options |= options; + return ssl_impl->options; } uint32_t SSL_clear_options(SSL *ssl, uint32_t options) { - ssl->options &= ~options; - return ssl->options; + auto *ssl_impl = FromOpaque(ssl); + ssl_impl->options &= ~options; + return ssl_impl->options; } -uint32_t SSL_get_options(const SSL *ssl) { return ssl->options; } +uint32_t SSL_get_options(const SSL *ssl) { return FromOpaque(ssl)->options; } uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode) { auto *ctx_impl = FromOpaque(ctx); @@ -1371,16 +1398,18 @@ uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx) { return FromOpaque(ctx)->mode; } uint32_t SSL_set_mode(SSL *ssl, uint32_t mode) { - ssl->mode |= mode; - return ssl->mode; + auto *ssl_impl = FromOpaque(ssl); + ssl_impl->mode |= mode; + return ssl_impl->mode; } uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode) { - ssl->mode &= ~mode; - return ssl->mode; + auto *ssl_impl = FromOpaque(ssl); + ssl_impl->mode &= ~mode; + return ssl_impl->mode; } -uint32_t SSL_get_mode(const SSL *ssl) { return ssl->mode; } +uint32_t SSL_get_mode(const SSL *ssl) { return FromOpaque(ssl)->mode; } void SSL_CTX_set1_buffer_pool(SSL_CTX *ctx, CRYPTO_BUFFER_POOL *pool) { FromOpaque(ctx)->pool = UpRef(pool); @@ -1397,25 +1426,26 @@ int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out) { + const auto *ssl_impl = FromOpaque(ssl); *out_len = 0; OPENSSL_memset(out, 0, max_out); // tls-unique is not defined for TLS 1.3. - if (!ssl->s3->initial_handshake_complete || - ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + if (!ssl_impl->s3->initial_handshake_complete || + ssl_protocol_version(ssl_impl) >= TLS1_3_VERSION) { return 0; } // The tls-unique value is the first Finished message in the handshake, which // is the client's in a full handshake and the server's for a resumption. See // https://tools.ietf.org/html/rfc5929#section-3.1. - Span<const uint8_t> finished = ssl->s3->previous_client_finished; - if (ssl->session != nullptr) { + Span<const uint8_t> finished = ssl_impl->s3->previous_client_finished; + if (ssl_impl->session != nullptr) { // tls-unique is broken for resumed sessions unless EMS is used. - if (!ssl->session->extended_master_secret) { + if (!ssl_impl->session->extended_master_secret) { return 0; } - finished = ssl->s3->previous_server_finished; + finished = ssl_impl->s3->previous_server_finished; } *out_len = finished.size(); @@ -1445,20 +1475,23 @@ int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx, size_t sid_ctx_len) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; } - return set_session_id_context(ssl->config->cert.get(), sid_ctx, sid_ctx_len); + return set_session_id_context(ssl_impl->config->cert.get(), sid_ctx, + sid_ctx_len); } const uint8_t *SSL_get0_session_id_context(const SSL *ssl, size_t *out_len) { - if (!ssl->config) { - assert(ssl->config); + const auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { + assert(ssl_impl->config); *out_len = 0; return nullptr; } - *out_len = ssl->config->cert->sid_ctx.size(); - return ssl->config->cert->sid_ctx.data(); + *out_len = ssl_impl->config->cert->sid_ctx.size(); + return ssl_impl->config->cert->sid_ctx.data(); } int SSL_get_fd(const SSL *ssl) { return SSL_get_rfd(ssl); } @@ -1542,57 +1575,61 @@ } size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count) { - if (!ssl->s3->initial_handshake_complete || - ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + const auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->s3->initial_handshake_complete || + ssl_protocol_version(ssl_impl) >= TLS1_3_VERSION) { return 0; } - if (ssl->server) { - return copy_finished(buf, count, ssl->s3->previous_server_finished); + if (ssl_impl->server) { + return copy_finished(buf, count, ssl_impl->s3->previous_server_finished); } - return copy_finished(buf, count, ssl->s3->previous_client_finished); + return copy_finished(buf, count, ssl_impl->s3->previous_client_finished); } size_t SSL_get_peer_finished(const SSL *ssl, void *buf, size_t count) { - if (!ssl->s3->initial_handshake_complete || - ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + const auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->s3->initial_handshake_complete || + ssl_protocol_version(ssl_impl) >= TLS1_3_VERSION) { return 0; } - if (ssl->server) { - return copy_finished(buf, count, ssl->s3->previous_client_finished); + if (ssl_impl->server) { + return copy_finished(buf, count, ssl_impl->s3->previous_client_finished); } - return copy_finished(buf, count, ssl->s3->previous_server_finished); + return copy_finished(buf, count, ssl_impl->s3->previous_server_finished); } int SSL_get_verify_mode(const SSL *ssl) { - if (!ssl->config) { - assert(ssl->config); + const auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { + assert(ssl_impl->config); return -1; } - return ssl->config->verify_mode; + return ssl_impl->config->verify_mode; } int SSL_get_extms_support(const SSL *ssl) { + const auto *ssl_impl = FromOpaque(ssl); // TLS 1.3 does not require extended master secret and always reports as // supporting it. - if (ssl->s3->version == 0) { + if (ssl_impl->s3->version == 0) { return 0; } - if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + if (ssl_protocol_version(ssl_impl) >= TLS1_3_VERSION) { return 1; } // If the initial handshake completed, query the established session. - if (ssl->s3->established_session != nullptr) { - return ssl->s3->established_session->extended_master_secret; + if (ssl_impl->s3->established_session != nullptr) { + return ssl_impl->s3->established_session->extended_master_secret; } // Otherwise, query the in-progress handshake. - if (ssl->s3->hs != nullptr) { - return ssl->s3->hs->extended_master_secret; + if (ssl_impl->s3->hs != nullptr) { + return ssl_impl->s3->hs->extended_master_secret; } assert(0); return 0; @@ -1607,11 +1644,11 @@ int SSL_set_read_ahead(SSL *ssl, int yes) { return 1; } int SSL_pending(const SSL *ssl) { - return static_cast<int>(ssl->s3->pending_app_data.size()); + return static_cast<int>(FromOpaque(ssl)->s3->pending_app_data.size()); } int SSL_has_pending(const SSL *ssl) { - return SSL_pending(ssl) != 0 || !ssl->s3->read_buffer.empty(); + return SSL_pending(ssl) != 0 || !FromOpaque(ssl)->s3->read_buffer.empty(); } static bool has_cert_and_key(const SSLCredential *cred) { @@ -1637,13 +1674,14 @@ } int SSL_check_private_key(const SSL *ssl) { - if (!ssl->config) { + const auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; } // There is no need to actually check consistency because inconsistent values // can never be configured. - return has_cert_and_key(ssl->config->cert->legacy_credential.get()); + return has_cert_and_key(ssl_impl->config->cert->legacy_credential.get()); } long SSL_get_default_timeout(const SSL *ssl) { @@ -1651,51 +1689,52 @@ } int SSL_renegotiate(SSL *ssl) { + auto *ssl_impl = FromOpaque(ssl); // Caller-initiated renegotiation is not supported. - if (!ssl->s3->renegotiate_pending) { + if (!ssl_impl->s3->renegotiate_pending) { OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (!ssl_can_renegotiate(ssl)) { + if (!ssl_can_renegotiate(ssl_impl)) { OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); return 0; } // We should not have told the caller to release the private key. - assert(!SSL_can_release_private_key(ssl)); + assert(!SSL_can_release_private_key(ssl_impl)); // Renegotiation is only supported at quiescent points in the application // protocol, namely in HTTPS, just before reading the HTTP response. // Require the record-layer be idle and avoid complexities of sending a // handshake record while an application_data record is being written. - if (!ssl->s3->write_buffer.empty() || - ssl->s3->write_shutdown != ssl_shutdown_none) { + if (!ssl_impl->s3->write_buffer.empty() || + ssl_impl->s3->write_shutdown != ssl_shutdown_none) { OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); return 0; } // Begin a new handshake. - if (ssl->s3->hs != nullptr) { + if (ssl_impl->s3->hs != nullptr) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return 0; } - ssl->s3->hs = ssl_handshake_new(ssl); - if (ssl->s3->hs == nullptr) { + ssl_impl->s3->hs = ssl_handshake_new(ssl_impl); + if (ssl_impl->s3->hs == nullptr) { return 0; } - ssl->s3->renegotiate_pending = false; - ssl->s3->total_renegotiations++; + ssl_impl->s3->renegotiate_pending = false; + ssl_impl->s3->total_renegotiations++; return 1; } int SSL_renegotiate_pending(SSL *ssl) { - return SSL_in_init(ssl) && ssl->s3->initial_handshake_complete; + return SSL_in_init(ssl) && FromOpaque(ssl)->s3->initial_handshake_complete; } int SSL_total_renegotiations(const SSL *ssl) { - return ssl->s3->total_renegotiations; + return FromOpaque(ssl)->s3->total_renegotiations; } size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx) { @@ -1709,13 +1748,15 @@ FromOpaque(ctx)->max_cert_list = (uint32_t)max_cert_list; } -size_t SSL_get_max_cert_list(const SSL *ssl) { return ssl->max_cert_list; } +size_t SSL_get_max_cert_list(const SSL *ssl) { + return FromOpaque(ssl)->max_cert_list; +} void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list) { if (max_cert_list > kMaxHandshakeSize) { max_cert_list = kMaxHandshakeSize; } - ssl->max_cert_list = (uint32_t)max_cert_list; + FromOpaque(ssl)->max_cert_list = (uint32_t)max_cert_list; } int SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, size_t max_send_fragment) { @@ -1737,7 +1778,7 @@ if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) { max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; } - ssl->max_send_fragment = (uint16_t)max_send_fragment; + FromOpaque(ssl)->max_send_fragment = (uint16_t)max_send_fragment; return 1; } @@ -1746,16 +1787,17 @@ if (!SSL_is_dtls(ssl) || mtu < dtls1_min_mtu()) { return 0; } - ssl->d1->mtu = mtu; + FromOpaque(ssl)->d1->mtu = mtu; return 1; } int SSL_get_secure_renegotiation_support(const SSL *ssl) { - if (ssl->s3->version == 0) { + const auto *ssl_impl = FromOpaque(ssl); + if (ssl_impl->s3->version == 0) { return 0; } - return ssl_protocol_version(ssl) >= TLS1_3_VERSION || - ssl->s3->send_connection_binding; + return ssl_protocol_version(ssl_impl) >= TLS1_3_VERSION || + ssl_impl->s3->send_connection_binding; } size_t SSL_CTX_sess_number(const SSL_CTX *ctx) { @@ -1948,13 +1990,14 @@ int SSL_set1_group_ids_with_flags(SSL *ssl, const uint16_t *group_ids, const uint32_t *flags, size_t num_group_ids) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; } if (set_group_ids_and_flags(group_ids, flags, num_group_ids, - &ssl->config->supported_group_list, - &ssl->config->supported_group_list_flags)) { - clear_key_shares_if_invalid(ssl->config.get()); + &ssl_impl->config->supported_group_list, + &ssl_impl->config->supported_group_list_flags)) { + clear_key_shares_if_invalid(ssl_impl->config.get()); return 1; } return 0; @@ -1993,14 +2036,15 @@ } int SSL_set1_groups(SSL *ssl, const int *groups, size_t num_groups) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; } - if (ssl_nids_to_group_ids(&ssl->config->supported_group_list, + if (ssl_nids_to_group_ids(&ssl_impl->config->supported_group_list, Span(groups, num_groups)) && - ssl->config->supported_group_list_flags.Init( - ssl->config->supported_group_list.size())) { - clear_key_shares_if_invalid(ssl->config.get()); + ssl_impl->config->supported_group_list_flags.Init( + ssl_impl->config->supported_group_list.size())) { + clear_key_shares_if_invalid(ssl_impl->config.get()); return 1; } return 0; @@ -2054,13 +2098,14 @@ } int SSL_set1_groups_list(SSL *ssl, const char *groups) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; } - if (ssl_str_to_group_ids(&ssl->config->supported_group_list, groups) && - ssl->config->supported_group_list_flags.Init( - ssl->config->supported_group_list.size())) { - clear_key_shares_if_invalid(ssl->config.get()); + if (ssl_str_to_group_ids(&ssl_impl->config->supported_group_list, groups) && + ssl_impl->config->supported_group_list_flags.Init( + ssl_impl->config->supported_group_list.size())) { + clear_key_shares_if_invalid(ssl_impl->config.get()); return 1; } return 0; @@ -2085,29 +2130,31 @@ int SSL_set1_client_key_shares(SSL *ssl, const uint16_t *group_ids, size_t num_group_ids) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; } auto requested_key_shares = Span(group_ids, num_group_ids); if (!validate_key_shares(requested_key_shares, - ssl->config->supported_group_list)) { + ssl_impl->config->supported_group_list)) { return 0; } assert(requested_key_shares.size() <= kNumNamedGroups); - ssl->config->client_key_share_selections.emplace(); - ssl->config->client_key_share_selections->CopyFrom(requested_key_shares); + ssl_impl->config->client_key_share_selections.emplace(); + ssl_impl->config->client_key_share_selections->CopyFrom(requested_key_shares); return 1; } int SSL_set1_server_supported_groups_hint(SSL *ssl, const uint16_t *server_groups, size_t num_server_groups) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; } auto span = Span(server_groups, num_server_groups); - return ssl->config->server_supported_groups_hint.CopyFrom(span); + return ssl_impl->config->server_supported_groups_hint.CopyFrom(span); } int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh) { return 1; } @@ -2130,13 +2177,15 @@ if (ssl == nullptr) { return nullptr; } - if (ssl->config == nullptr) { - assert(ssl->config); + const auto *ssl_impl = FromOpaque(ssl); + if (ssl_impl->config == nullptr) { + assert(ssl_impl->config); return nullptr; } - return ssl->config->cipher_list ? ssl->config->cipher_list->ciphers.get() - : ssl->ctx->cipher_list->ciphers.get(); + return ssl_impl->config->cipher_list + ? ssl_impl->config->cipher_list->ciphers.get() + : ssl_impl->ctx->cipher_list->ciphers.get(); } const char *SSL_get_cipher_list(const SSL *ssl, int n) { @@ -2176,24 +2225,26 @@ } int SSL_set_cipher_list(SSL *ssl, const char *str) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; } - const bool has_aes_hw = ssl->config->aes_hw_override - ? ssl->config->aes_hw_override_value + const bool has_aes_hw = ssl_impl->config->aes_hw_override + ? ssl_impl->config->aes_hw_override_value : EVP_has_aes_hardware(); - return ssl_create_cipher_list(&ssl->config->cipher_list, has_aes_hw, str, + return ssl_create_cipher_list(&ssl_impl->config->cipher_list, has_aes_hw, str, false /* not strict */); } int SSL_set_strict_cipher_list(SSL *ssl, const char *str) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; } - const bool has_aes_hw = ssl->config->aes_hw_override - ? ssl->config->aes_hw_override_value + const bool has_aes_hw = ssl_impl->config->aes_hw_override + ? ssl_impl->config->aes_hw_override_value : EVP_has_aes_hardware(); - return ssl_create_cipher_list(&ssl->config->cipher_list, has_aes_hw, str, + return ssl_create_cipher_list(&ssl_impl->config->cipher_list, has_aes_hw, str, true /* strict */); } @@ -2202,13 +2253,14 @@ return nullptr; } + const auto *ssl_impl = FromOpaque(ssl); // Historically, `SSL_get_servername` was also the configuration getter // corresponding to `SSL_set_tlsext_host_name`. - if (ssl->hostname != nullptr) { - return ssl->hostname.get(); + if (ssl_impl->hostname != nullptr) { + return ssl_impl->hostname.get(); } - return ssl->s3->hostname.get(); + return ssl_impl->s3->hostname.get(); } int SSL_get_servername_type(const SSL *ssl) { @@ -2229,11 +2281,12 @@ void SSL_set_custom_verify( SSL *ssl, int mode, enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return; } - ssl->config->verify_mode = mode; - ssl->config->custom_verify_callback = callback; + ssl_impl->config->verify_mode = mode; + ssl_impl->config->custom_verify_callback = callback; } void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx) { @@ -2241,10 +2294,11 @@ } void SSL_enable_signed_cert_timestamps(SSL *ssl) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return; } - ssl->config->signed_cert_timestamps_enabled = true; + ssl_impl->config->signed_cert_timestamps_enabled = true; } void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx) { @@ -2252,16 +2306,18 @@ } void SSL_enable_ocsp_stapling(SSL *ssl) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return; } - ssl->config->ocsp_stapling_enabled = true; + ssl_impl->config->ocsp_stapling_enabled = true; } void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out, size_t *out_len) { SSL_SESSION *session = SSL_get_session(ssl); - if (ssl->server || !session || !session->signed_cert_timestamp_list) { + if (FromOpaque(ssl)->server || !session || + !session->signed_cert_timestamp_list) { *out_len = 0; *out = nullptr; return; @@ -2274,7 +2330,7 @@ void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out, size_t *out_len) { SSL_SESSION *session = SSL_get_session(ssl); - if (ssl->server || !session || !session->ocsp_response) { + if (FromOpaque(ssl)->server || !session || !session->ocsp_response) { *out_len = 0; *out = nullptr; return; @@ -2285,7 +2341,8 @@ } int SSL_set_tlsext_host_name(SSL *ssl, const char *name) { - ssl->hostname.reset(); + auto *ssl_impl = FromOpaque(ssl); + ssl_impl->hostname.reset(); if (name == nullptr) { return 1; } @@ -2295,8 +2352,8 @@ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME); return 0; } - ssl->hostname.reset(OPENSSL_strdup(name)); - if (ssl->hostname == nullptr) { + ssl_impl->hostname.reset(OPENSSL_strdup(name)); + if (ssl_impl->hostname == nullptr) { return 0; } return 1; @@ -2363,10 +2420,11 @@ void SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data, unsigned *out_len) { + const auto *ssl_impl = FromOpaque(ssl); // NPN protocols have one-byte lengths, so they must fit in `unsigned`. - assert(ssl->s3->next_proto_negotiated.size() <= UINT_MAX); - *out_data = ssl->s3->next_proto_negotiated.data(); - *out_len = static_cast<unsigned>(ssl->s3->next_proto_negotiated.size()); + assert(ssl_impl->s3->next_proto_negotiated.size() <= UINT_MAX); + *out_data = ssl_impl->s3->next_proto_negotiated.data(); + *out_len = static_cast<unsigned>(ssl_impl->s3->next_proto_negotiated.size()); } void SSL_CTX_set_next_protos_advertised_cb( @@ -2402,7 +2460,8 @@ int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, size_t protos_len) { // Note this function's return value is backwards. - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 1; } auto span = Span(protos, protos_len); @@ -2410,7 +2469,7 @@ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL_LIST); return 1; } - return ssl->config->alpn_client_proto_list.CopyFrom(span) ? 0 : 1; + return ssl_impl->config->alpn_client_proto_list.CopyFrom(span) ? 0 : 1; } void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, @@ -2425,11 +2484,12 @@ void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data, unsigned *out_len) { + const auto *ssl_impl = FromOpaque(ssl); Span<const uint8_t> protocol; - if (SSL_in_early_data(ssl) && !ssl->server) { - protocol = ssl->s3->hs->early_session->early_alpn; + if (SSL_in_early_data(ssl_impl) && !ssl_impl->server) { + protocol = ssl_impl->s3->hs->early_session->early_alpn; } else { - protocol = ssl->s3->alpn_selected; + protocol = ssl_impl->s3->alpn_selected; } // ALPN protocols have one-byte lengths, so they must fit in `unsigned`. assert(protocol.size() < UINT_MAX); @@ -2444,13 +2504,14 @@ int SSL_add_application_settings(SSL *ssl, const uint8_t *proto, size_t proto_len, const uint8_t *settings, size_t settings_len) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; } ALPSConfig config; if (!config.protocol.CopyFrom(Span(proto, proto_len)) || !config.settings.CopyFrom(Span(settings, settings_len)) || - !ssl->config->alps_configs.Push(std::move(config))) { + !ssl_impl->config->alps_configs.Push(std::move(config))) { return 0; } return 1; @@ -2472,10 +2533,11 @@ } void SSL_set_alps_use_new_codepoint(SSL *ssl, int use_new) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return; } - ssl->config->alps_use_new_codepoint = !!use_new; + ssl_impl->config->alps_use_new_codepoint = !!use_new; } int SSL_CTX_add_cert_compression_alg(SSL_CTX *ctx, uint16_t alg_id, @@ -2507,10 +2569,11 @@ } void SSL_set_tls_channel_id_enabled(SSL *ssl, int enabled) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return; } - ssl->config->channel_id_enabled = !!enabled; + ssl_impl->config->channel_id_enabled = !!enabled; } int SSL_enable_tls_channel_id(SSL *ssl) { @@ -2529,7 +2592,8 @@ } int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; } if (EVP_PKEY_get_ec_curve_nid(private_key) != NID_X9_62_prime256v1) { @@ -2537,22 +2601,24 @@ return 0; } - ssl->config->channel_id_private = UpRef(private_key); + ssl_impl->config->channel_id_private = UpRef(private_key); return 1; } size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out, size_t max_out) { - if (!ssl->s3->channel_id_valid) { + const auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->s3->channel_id_valid) { return 0; } - OPENSSL_memcpy(out, ssl->s3->channel_id, (max_out < 64) ? max_out : 64); + OPENSSL_memcpy(out, ssl_impl->s3->channel_id, (max_out < 64) ? max_out : 64); return 64; } size_t SSL_get0_certificate_types(const SSL *ssl, const uint8_t **out_types) { + const auto *ssl_impl = FromOpaque(ssl); Span<const uint8_t> types; - if (!ssl->server && ssl->s3->hs != nullptr) { - types = ssl->s3->hs->certificate_types; + if (!ssl_impl->server && ssl_impl->s3->hs != nullptr) { + types = ssl_impl->s3->hs->certificate_types; } *out_types = types.data(); return types.size(); @@ -2560,9 +2626,10 @@ size_t SSL_get0_peer_verify_algorithms(const SSL *ssl, const uint16_t **out_sigalgs) { + const auto *ssl_impl = FromOpaque(ssl); Span<const uint16_t> sigalgs; - if (ssl->s3->hs != nullptr) { - sigalgs = ssl->s3->hs->peer_sigalgs; + if (ssl_impl->s3->hs != nullptr) { + sigalgs = ssl_impl->s3->hs->peer_sigalgs; } *out_sigalgs = sigalgs.data(); return sigalgs.size(); @@ -2570,20 +2637,22 @@ size_t SSL_get0_peer_delegation_algorithms(const SSL *ssl, const uint16_t **out_sigalgs) { + const auto *ssl_impl = FromOpaque(ssl); Span<const uint16_t> sigalgs; - if (ssl->s3->hs != nullptr) { - sigalgs = ssl->s3->hs->peer_delegated_credential_sigalgs; + if (ssl_impl->s3->hs != nullptr) { + sigalgs = ssl_impl->s3->hs->peer_delegated_credential_sigalgs; } *out_sigalgs = sigalgs.data(); return sigalgs.size(); } EVP_PKEY *SSL_get_privatekey(const SSL *ssl) { - if (!ssl->config) { - assert(ssl->config); + const auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { + assert(ssl_impl->config); return nullptr; } - return ssl->config->cert->legacy_credential->privkey.get(); + return ssl_impl->config->cert->legacy_credential->privkey.get(); } EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) { @@ -2596,7 +2665,7 @@ } int SSL_session_reused(const SSL *ssl) { - return ssl->s3->session_reused || SSL_in_early_data(ssl); + return FromOpaque(ssl)->s3->session_reused || SSL_in_early_data(ssl); } const COMP_METHOD *SSL_get_current_compression(SSL *ssl) { return nullptr; } @@ -2614,54 +2683,59 @@ } void SSL_set_quiet_shutdown(SSL *ssl, int mode) { - ssl->quiet_shutdown = (mode != 0); + FromOpaque(ssl)->quiet_shutdown = (mode != 0); } -int SSL_get_quiet_shutdown(const SSL *ssl) { return ssl->quiet_shutdown; } +int SSL_get_quiet_shutdown(const SSL *ssl) { + return FromOpaque(ssl)->quiet_shutdown; +} void SSL_set_shutdown(SSL *ssl, int mode) { + auto *ssl_impl = FromOpaque(ssl); // It is an error to clear any bits that have already been set. (We can't try // to get a second close_notify or send two.) assert((SSL_get_shutdown(ssl) & mode) == SSL_get_shutdown(ssl)); if (mode & SSL_RECEIVED_SHUTDOWN && - ssl->s3->read_shutdown == ssl_shutdown_none) { - ssl->s3->read_shutdown = ssl_shutdown_close_notify; + ssl_impl->s3->read_shutdown == ssl_shutdown_none) { + ssl_impl->s3->read_shutdown = ssl_shutdown_close_notify; } if (mode & SSL_SENT_SHUTDOWN && - ssl->s3->write_shutdown == ssl_shutdown_none) { - ssl->s3->write_shutdown = ssl_shutdown_close_notify; + ssl_impl->s3->write_shutdown == ssl_shutdown_none) { + ssl_impl->s3->write_shutdown = ssl_shutdown_close_notify; } } int SSL_get_shutdown(const SSL *ssl) { + const auto *ssl_impl = FromOpaque(ssl); int ret = 0; - if (ssl->s3->read_shutdown != ssl_shutdown_none) { + if (ssl_impl->s3->read_shutdown != ssl_shutdown_none) { // Historically, OpenSSL set `SSL_RECEIVED_SHUTDOWN` on both close_notify // and fatal alert. ret |= SSL_RECEIVED_SHUTDOWN; } - if (ssl->s3->write_shutdown == ssl_shutdown_close_notify) { + if (ssl_impl->s3->write_shutdown == ssl_shutdown_close_notify) { // Historically, OpenSSL set `SSL_SENT_SHUTDOWN` on only close_notify. ret |= SSL_SENT_SHUTDOWN; } return ret; } -SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return ssl->ctx.get(); } +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return FromOpaque(ssl)->ctx.get(); } SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return nullptr; } - if (ssl->ctx.get() == ctx) { - return ssl->ctx.get(); + if (ssl_impl->ctx.get() == ctx) { + return ssl_impl->ctx.get(); } // One cannot change the X.509 callbacks during a connection. auto *ctx_impl = FromOpaque(ctx); - if (ssl->ctx->x509_method != ctx_impl->x509_method) { + if (ssl_impl->ctx->x509_method != ctx_impl->x509_method) { assert(0); return nullptr; } @@ -2671,21 +2745,21 @@ return nullptr; } - ssl->config->cert = std::move(new_cert); - ssl->ctx = UpRef(ctx_impl); - ssl->enable_early_data = ssl->ctx->enable_early_data; + ssl_impl->config->cert = std::move(new_cert); + ssl_impl->ctx = UpRef(ctx_impl); + ssl_impl->enable_early_data = ssl_impl->ctx->enable_early_data; - return ssl->ctx.get(); + return ssl_impl->ctx.get(); } void SSL_set_info_callback(SSL *ssl, void (*cb)(const SSL *ssl, int type, int value)) { - ssl->info_callback = cb; + FromOpaque(ssl)->info_callback = cb; } void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, int type, int value) { - return ssl->info_callback; + return FromOpaque(ssl)->info_callback; } int SSL_state(const SSL *ssl) { @@ -2717,10 +2791,11 @@ } int SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method) { - if (ssl->method->is_dtls) { + auto *ssl_impl = FromOpaque(ssl); + if (ssl_impl->method->is_dtls) { return 0; } - ssl->quic_method = quic_method; + ssl_impl->quic_method = quic_method; return 1; } @@ -2731,11 +2806,11 @@ } int SSL_set_ex_data(SSL *ssl, int idx, void *data) { - return CRYPTO_set_ex_data(&ssl->ex_data, idx, data); + return CRYPTO_set_ex_data(&FromOpaque(ssl)->ex_data, idx, data); } void *SSL_get_ex_data(const SSL *ssl, int idx) { - return CRYPTO_get_ex_data(&ssl->ex_data, idx); + return CRYPTO_get_ex_data(&FromOpaque(ssl)->ex_data, idx); } int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, @@ -2754,11 +2829,12 @@ } int SSL_want(const SSL *ssl) { + const auto *ssl_impl = FromOpaque(ssl); // Historically, OpenSSL did not track `SSL_ERROR_ZERO_RETURN` as an `rwstate` // value. We do, but map it back to `SSL_ERROR_NONE` to preserve the original // behavior. - return ssl->s3->rwstate == SSL_ERROR_ZERO_RETURN ? SSL_ERROR_NONE - : ssl->s3->rwstate; + return ssl_impl->s3->rwstate == SSL_ERROR_ZERO_RETURN ? SSL_ERROR_NONE + : ssl_impl->s3->rwstate; } void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, @@ -2806,21 +2882,24 @@ } int SSL_use_psk_identity_hint(SSL *ssl, const char *identity_hint) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; } - return use_psk_identity_hint(&ssl->config->psk_identity_hint, identity_hint); + return use_psk_identity_hint(&ssl_impl->config->psk_identity_hint, + identity_hint); } const char *SSL_get_psk_identity_hint(const SSL *ssl) { if (ssl == nullptr) { return nullptr; } - if (ssl->config == nullptr) { - assert(ssl->config); + const auto *ssl_impl = FromOpaque(ssl); + if (ssl_impl->config == nullptr) { + assert(ssl_impl->config); return nullptr; } - return ssl->config->psk_identity_hint.get(); + return ssl_impl->config->psk_identity_hint.get(); } const char *SSL_get_psk_identity(const SSL *ssl) { @@ -2838,10 +2917,11 @@ SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, unsigned max_identity_len, uint8_t *psk, unsigned max_psk_len)) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return; } - ssl->config->psk_client_callback = cb; + ssl_impl->config->psk_client_callback = cb; } void SSL_CTX_set_psk_client_callback( @@ -2855,10 +2935,11 @@ unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk, unsigned max_psk_len)) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return; } - ssl->config->psk_server_callback = cb; + ssl_impl->config->psk_server_callback = cb; } void SSL_CTX_set_psk_server_callback( @@ -2882,11 +2963,11 @@ void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)) { - ssl->msg_callback = cb; + FromOpaque(ssl)->msg_callback = cb; } void SSL_set_msg_callback_arg(SSL *ssl, void *arg) { - ssl->msg_callback_arg = arg; + FromOpaque(ssl)->msg_callback_arg = arg; } void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, @@ -2906,14 +2987,15 @@ } int SSL_can_release_private_key(const SSL *ssl) { - if (ssl_can_renegotiate(ssl)) { + const auto *ssl_impl = FromOpaque(ssl); + if (ssl_can_renegotiate(ssl_impl)) { // If the connection can renegotiate (client only), the private key may be // used in a future handshake. return 0; } // Otherwise, this is determined by the current handshake. - return !ssl->s3->hs || ssl->s3->hs->can_release_private_key; + return !ssl_impl->s3->hs || ssl_impl->s3->hs->can_release_private_key; } int SSL_is_init_finished(const SSL *ssl) { return !SSL_in_init(ssl); } @@ -2922,24 +3004,28 @@ // This returns false once all the handshake state has been finalized, to // allow callbacks and getters based on SSL_in_init to return the correct // values. - SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + const auto *ssl_impl = FromOpaque(ssl); + SSL_HANDSHAKE *hs = ssl_impl->s3->hs.get(); return hs != nullptr && !hs->handshake_finalized; } int SSL_in_false_start(const SSL *ssl) { - if (ssl->s3->hs == nullptr) { + const auto *ssl_impl = FromOpaque(ssl); + if (ssl_impl->s3->hs == nullptr) { return 0; } - return ssl->s3->hs->in_false_start; + return ssl_impl->s3->hs->in_false_start; } int SSL_cutthrough_complete(const SSL *ssl) { return SSL_in_false_start(ssl); } -int SSL_is_server(const SSL *ssl) { return ssl->server; } +int SSL_is_server(const SSL *ssl) { return FromOpaque(ssl)->server; } -int SSL_is_dtls(const SSL *ssl) { return ssl->method->is_dtls; } +int SSL_is_dtls(const SSL *ssl) { return FromOpaque(ssl)->method->is_dtls; } -int SSL_is_quic(const SSL *ssl) { return ssl->quic_method != nullptr; } +int SSL_is_quic(const SSL *ssl) { + return FromOpaque(ssl)->quic_method != nullptr; +} void SSL_CTX_set_select_certificate_cb( SSL_CTX *ctx, @@ -2957,12 +3043,13 @@ } void SSL_set_renegotiate_mode(SSL *ssl, enum ssl_renegotiate_mode_t mode) { - ssl->renegotiate_mode = mode; + auto *ssl_impl = FromOpaque(ssl); + ssl_impl->renegotiate_mode = mode; // Check if `ssl_can_renegotiate` has changed and the configuration may now be // shed. HTTP clients may initially allow renegotiation for HTTP/1.1, and then // disable after the handshake once the ALPN protocol is known to be HTTP/2. - ssl_maybe_shed_handshake_config(ssl); + ssl_maybe_shed_handshake_config(ssl_impl); } int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv, @@ -2974,9 +3061,10 @@ return 0; } + const auto *ssl_impl = FromOpaque(ssl); size_t write_iv_len; - if (!ssl->s3->aead_read_ctx->GetIV(out_read_iv, out_iv_len) || - !ssl->s3->aead_write_ctx->GetIV(out_write_iv, &write_iv_len) || + if (!ssl_impl->s3->aead_read_ctx->GetIV(out_read_iv, out_iv_len) || + !ssl_impl->s3->aead_write_ctx->GetIV(out_write_iv, &write_iv_len) || *out_iv_len != write_iv_len) { return 0; } @@ -2985,14 +3073,15 @@ } uint64_t SSL_get_read_sequence(const SSL *ssl) { + const auto *ssl_impl = FromOpaque(ssl); if (SSL_is_dtls(ssl)) { // TODO(crbug.com/42290608): This API should not be implemented for DTLS or // QUIC. In QUIC we do not maintain a sequence number. - const DTLSReadEpoch *read_epoch = &ssl->d1->read_epoch; + const DTLSReadEpoch *read_epoch = &ssl_impl->d1->read_epoch; return DTLSRecordNumber(read_epoch->epoch, read_epoch->bitmap.max_seq_num()) .combined(); } - return ssl->s3->read_sequence; + return ssl_impl->s3->read_sequence; } uint64_t SSL_get_write_sequence(const SSL *ssl) { @@ -3000,60 +3089,66 @@ // QUIC. In QUIC we do not maintain a sequence number. In DTLS, this API isn't // harmful per se, but the caller already needs to use a DTLS-specific API on // the read side. + const auto *ssl_impl = FromOpaque(ssl); if (SSL_is_dtls(ssl)) { - return ssl->d1->write_epoch.next_record.combined(); + return ssl_impl->d1->write_epoch.next_record.combined(); } - return ssl->s3->write_sequence; + return ssl_impl->s3->write_sequence; } int SSL_is_dtls_handshake_idle(const SSL *ssl) { BSSL_CHECK(SSL_is_dtls(ssl)); + const auto *ssl_impl = FromOpaque(ssl); return !SSL_in_init(ssl) && // No unacknowledged messages in DTLS 1.3. In DTLS 1.2, there no ACKs // and we currently never clear `outgoing_messages` on the side that // speaks last. - (ssl_protocol_version(ssl) < TLS1_3_VERSION || - ssl->d1->outgoing_messages.empty()) && + (ssl_protocol_version(ssl_impl) < TLS1_3_VERSION || + ssl_impl->d1->outgoing_messages.empty()) && // No partial or out-of-order messages. - std::all_of(std::begin(ssl->d1->incoming_messages), - std::end(ssl->d1->incoming_messages), + std::all_of(std::begin(ssl_impl->d1->incoming_messages), + std::end(ssl_impl->d1->incoming_messages), [](const auto &msg) { return msg == nullptr; }) && // Not trying to send a KeyUpdate. - !ssl->s3->key_update_pending && - ssl->d1->queued_key_update == bssl::QueuedKeyUpdate::kNone; + !ssl_impl->s3->key_update_pending && + ssl_impl->d1->queued_key_update == bssl::QueuedKeyUpdate::kNone; } uint32_t SSL_get_dtls_handshake_read_seq(const SSL *ssl) { BSSL_CHECK(SSL_is_dtls(ssl)); - return ssl->d1->handshake_read_overflow + const auto *ssl_impl = FromOpaque(ssl); + return ssl_impl->d1->handshake_read_overflow ? uint32_t{0x10000} - : uint32_t{ssl->d1->handshake_read_seq}; + : uint32_t{ssl_impl->d1->handshake_read_seq}; } uint32_t SSL_get_dtls_handshake_write_seq(const SSL *ssl) { BSSL_CHECK(SSL_is_dtls(ssl)); - return ssl->d1->handshake_write_overflow + const auto *ssl_impl = FromOpaque(ssl); + return ssl_impl->d1->handshake_write_overflow ? uint32_t{0x10000} - : uint32_t{ssl->d1->handshake_write_seq}; + : uint32_t{ssl_impl->d1->handshake_write_seq}; } uint16_t SSL_get_dtls_read_epoch(const SSL *ssl) { BSSL_CHECK(SSL_is_dtls(ssl)); + const auto *ssl_impl = FromOpaque(ssl); // Return the highest available epoch. - return ssl->d1->next_read_epoch ? ssl->d1->next_read_epoch->epoch - : ssl->d1->read_epoch.epoch; + return ssl_impl->d1->next_read_epoch ? ssl_impl->d1->next_read_epoch->epoch + : ssl_impl->d1->read_epoch.epoch; } uint16_t SSL_get_dtls_write_epoch(const SSL *ssl) { BSSL_CHECK(SSL_is_dtls(ssl)); - return ssl->d1->write_epoch.epoch(); + return FromOpaque(ssl)->d1->write_epoch.epoch(); } uint64_t SSL_get_dtls_read_sequence(const SSL *ssl, uint16_t epoch) { BSSL_CHECK(SSL_is_dtls(ssl)); - const DTLSReadEpoch *read_epoch = dtls_get_read_epoch(ssl, epoch); + const auto *ssl_impl = FromOpaque(ssl); + const DTLSReadEpoch *read_epoch = dtls_get_read_epoch(ssl_impl, epoch); if (read_epoch == nullptr) { return UINT64_MAX; } @@ -3071,7 +3166,8 @@ uint64_t SSL_get_dtls_write_sequence(const SSL *ssl, uint16_t epoch) { BSSL_CHECK(SSL_is_dtls(ssl)); - const DTLSWriteEpoch *write_epoch = dtls_get_write_epoch(ssl, epoch); + const auto *ssl_impl = FromOpaque(ssl); + const DTLSWriteEpoch *write_epoch = dtls_get_write_epoch(ssl_impl, epoch); if (write_epoch == nullptr) { return UINT64_MAX; } @@ -3080,7 +3176,7 @@ template <typename EpochState> static int get_dtls_traffic_secret( - const SSL *ssl, EpochState *(*get_epoch)(const SSL *, uint16_t), + const SSLImpl *ssl, EpochState *(*get_epoch)(const SSLImpl *, uint16_t), const uint8_t **out_data, size_t *out_len, uint16_t epoch) { BSSL_CHECK(SSL_is_dtls(ssl)); // This function only applies to encrypted DTLS 1.3 epochs. @@ -3100,14 +3196,14 @@ int SSL_get_dtls_read_traffic_secret(const SSL *ssl, const uint8_t **out_data, size_t *out_len, uint16_t epoch) { - return get_dtls_traffic_secret(ssl, dtls_get_read_epoch, out_data, out_len, - epoch); + return get_dtls_traffic_secret(FromOpaque(ssl), dtls_get_read_epoch, out_data, + out_len, epoch); } int SSL_get_dtls_write_traffic_secret(const SSL *ssl, const uint8_t **out_data, size_t *out_len, uint16_t epoch) { - return get_dtls_traffic_secret(ssl, dtls_get_write_epoch, out_data, out_len, - epoch); + return get_dtls_traffic_secret(FromOpaque(ssl), dtls_get_write_epoch, + out_data, out_len, epoch); } uint16_t SSL_get_peer_signature_algorithm(const SSL *ssl) { @@ -3120,29 +3216,32 @@ } size_t SSL_get_client_random(const SSL *ssl, uint8_t *out, size_t max_out) { + const auto *ssl_impl = FromOpaque(ssl); if (max_out == 0) { - return sizeof(ssl->s3->client_random); + return sizeof(ssl_impl->s3->client_random); } - if (max_out > sizeof(ssl->s3->client_random)) { - max_out = sizeof(ssl->s3->client_random); + if (max_out > sizeof(ssl_impl->s3->client_random)) { + max_out = sizeof(ssl_impl->s3->client_random); } - OPENSSL_memcpy(out, ssl->s3->client_random, max_out); + OPENSSL_memcpy(out, ssl_impl->s3->client_random, max_out); return max_out; } size_t SSL_get_server_random(const SSL *ssl, uint8_t *out, size_t max_out) { + const auto *ssl_impl = FromOpaque(ssl); if (max_out == 0) { - return sizeof(ssl->s3->server_random); + return sizeof(ssl_impl->s3->server_random); } - if (max_out > sizeof(ssl->s3->server_random)) { - max_out = sizeof(ssl->s3->server_random); + if (max_out > sizeof(ssl_impl->s3->server_random)) { + max_out = sizeof(ssl_impl->s3->server_random); } - OPENSSL_memcpy(out, ssl->s3->server_random, max_out); + OPENSSL_memcpy(out, ssl_impl->s3->server_random, max_out); return max_out; } uint16_t SSL_get_signature_algorithm_used(const SSL *ssl) { - SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + const auto *ssl_impl = FromOpaque(ssl); + SSL_HANDSHAKE *hs = ssl_impl->s3->hs.get(); if (hs == nullptr) { return 0; } @@ -3150,7 +3249,8 @@ } const SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl) { - SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + const auto *ssl_impl = FromOpaque(ssl); + SSL_HANDSHAKE *hs = ssl_impl->s3->hs.get(); if (hs == nullptr) { return nullptr; } @@ -3158,10 +3258,11 @@ } void SSL_set_retain_only_sha256_of_client_certs(SSL *ssl, int enabled) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return; } - ssl->config->retain_only_sha256_of_client_certs = !!enabled; + ssl_impl->config->retain_only_sha256_of_client_certs = !!enabled; } void SSL_CTX_set_retain_only_sha256_of_client_certs(SSL_CTX *ctx, int enabled) { @@ -3181,14 +3282,15 @@ } void SSL_set_permute_extensions(SSL *ssl, int enabled) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return; } - ssl->config->permute_extensions = !!enabled; + ssl_impl->config->permute_extensions = !!enabled; } int32_t SSL_get_ticket_age_skew(const SSL *ssl) { - return ssl->s3->ticket_age_skew; + return FromOpaque(ssl)->s3->ticket_age_skew; } void SSL_CTX_set_false_start_allowed_without_alpn(SSL_CTX *ctx, int allowed) { @@ -3196,32 +3298,36 @@ } int SSL_used_hello_retry_request(const SSL *ssl) { - return ssl->s3->used_hello_retry_request; + return FromOpaque(ssl)->s3->used_hello_retry_request; } void SSL_set_shed_handshake_config(SSL *ssl, int enable) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return; } - ssl->config->shed_handshake_config = !!enable; + ssl_impl->config->shed_handshake_config = !!enable; } void SSL_set_jdk11_workaround(SSL *ssl, int enable) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return; } - ssl->config->jdk11_workaround = !!enable; + ssl_impl->config->jdk11_workaround = !!enable; } void SSL_set_quic_use_legacy_codepoint(SSL *ssl, int use_legacy) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return; } - ssl->config->quic_use_legacy_codepoint = !!use_legacy; + ssl_impl->config->quic_use_legacy_codepoint = !!use_legacy; } int SSL_clear(SSL *ssl) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; // SSL_clear may not be used after shedding config. } @@ -3229,8 +3335,8 @@ // established session to be offered the next time around. wpa_supplicant // depends on this behavior, so emulate it. UniquePtr<SSL_SESSION> session; - if (!ssl->server && ssl->s3->established_session != nullptr) { - session = UpRef(ssl->s3->established_session); + if (!ssl_impl->server && ssl_impl->s3->established_session != nullptr) { + session = UpRef(ssl_impl->s3->established_session); } // The ssl->d1->mtu is simultaneously configuration (preserved across @@ -3238,17 +3344,17 @@ // // TODO(davidben): Avoid this. unsigned mtu = 0; - if (ssl->d1 != nullptr) { - mtu = ssl->d1->mtu; + if (ssl_impl->d1 != nullptr) { + mtu = ssl_impl->d1->mtu; } - ssl->method->ssl_free(ssl); - if (!ssl->method->ssl_new(ssl)) { + ssl_impl->method->ssl_free(ssl_impl); + if (!ssl_impl->method->ssl_new(ssl_impl)) { return 0; } if (SSL_is_dtls(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { - ssl->d1->mtu = mtu; + ssl_impl->d1->mtu = mtu; } if (session != nullptr) { @@ -3307,9 +3413,10 @@ SSL_SESSION *SSL_process_tls13_new_session_ticket(SSL *ssl, const uint8_t *buf, size_t buf_len) { - if (SSL_in_init(ssl) || // - ssl_protocol_version(ssl) != TLS1_3_VERSION || // - ssl->server) { + auto *ssl_impl = FromOpaque(ssl); + if (SSL_in_init(ssl_impl) || // + ssl_protocol_version(ssl_impl) != TLS1_3_VERSION || // + ssl_impl->server) { // Only TLS 1.3 clients are supported. OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return nullptr; @@ -3325,7 +3432,8 @@ return nullptr; } - UniquePtr<SSL_SESSION> session = tls13_create_session_with_ticket(ssl, &body); + UniquePtr<SSL_SESSION> session = + tls13_create_session_with_ticket(ssl_impl, &body); if (!session) { // `tls13_create_session_with_ticket` puts the correct error. return nullptr; @@ -3345,22 +3453,24 @@ } int SSL_set_tlsext_status_type(SSL *ssl, int type) { - if (!ssl->config) { + auto *ssl_impl = FromOpaque(ssl); + if (!ssl_impl->config) { return 0; } - ssl->config->ocsp_stapling_enabled = type == TLSEXT_STATUSTYPE_ocsp; + ssl_impl->config->ocsp_stapling_enabled = type == TLSEXT_STATUSTYPE_ocsp; return 1; } int SSL_get_tlsext_status_type(const SSL *ssl) { - if (ssl->server) { - SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + const auto *ssl_impl = FromOpaque(ssl); + if (ssl_impl->server) { + SSL_HANDSHAKE *hs = ssl_impl->s3->hs.get(); return hs != nullptr && hs->ocsp_stapling_requested ? TLSEXT_STATUSTYPE_ocsp : TLSEXT_STATUSTYPE_nothing; } - return ssl->config != nullptr && ssl->config->ocsp_stapling_enabled + return ssl_impl->config != nullptr && ssl_impl->config->ocsp_stapling_enabled ? TLSEXT_STATUSTYPE_ocsp : TLSEXT_STATUSTYPE_nothing; } @@ -3469,7 +3579,7 @@ SSL_CTX_set_verify_algorithm_prefs(ctx, kSigAlgs, std::size(kSigAlgs)); } -static int Configure(SSL *ssl) { +static int Configure(SSLImpl *ssl) { ssl->config->compliance_policy = ssl_compliance_policy_fips_202205; // See `Configure(SSL_CTX)`, above, for reasoning. @@ -3513,7 +3623,7 @@ SSL_CTX_set_verify_algorithm_prefs(ctx, kSigAlgs, std::size(kSigAlgs)); } -static int Configure(SSL *ssl) { +static int Configure(SSLImpl *ssl) { ssl->config->compliance_policy = ssl_compliance_policy_wpa3_192_202304; return SSL_set_min_proto_version(ssl, TLS1_2_VERSION) && @@ -3533,7 +3643,7 @@ return 1; } -static int Configure(SSL *ssl) { +static int Configure(SSLImpl *ssl) { ssl->config->compliance_policy = ssl_compliance_policy_cnsa_202407; return 1; } @@ -3573,7 +3683,7 @@ SSL_CTX_set_verify_algorithm_prefs(ctx, kSigAlgs, std::size(kSigAlgs)); } -static int Configure(SSL *ssl) { +static int Configure(SSLImpl *ssl) { ssl->config->compliance_policy = ssl_compliance_policy_cnsa1_202603; return SSL_set_min_proto_version(ssl, TLS1_2_VERSION) && @@ -3610,7 +3720,7 @@ SSL_CTX_set_verify_algorithm_prefs(ctx, kSigAlgs, std::size(kSigAlgs)); } -static int Configure(SSL *ssl) { +static int Configure(SSLImpl *ssl) { ssl->config->compliance_policy = ssl_compliance_policy_cnsa2_202603; return SSL_set_min_proto_version(ssl, TLS1_3_VERSION) && @@ -3646,34 +3756,36 @@ } int SSL_set_compliance_policy(SSL *ssl, enum ssl_compliance_policy_t policy) { + auto *ssl_impl = FromOpaque(ssl); switch (policy) { case ssl_compliance_policy_fips_202205: - return fips202205::Configure(ssl); + return fips202205::Configure(ssl_impl); case ssl_compliance_policy_wpa3_192_202304: - return wpa202304::Configure(ssl); + return wpa202304::Configure(ssl_impl); case ssl_compliance_policy_cnsa_202407: - return cnsa202407::Configure(ssl); + return cnsa202407::Configure(ssl_impl); case ssl_compliance_policy_cnsa1_202603: - return cnsa1_202603::Configure(ssl); + return cnsa1_202603::Configure(ssl_impl); case ssl_compliance_policy_cnsa2_202603: - return cnsa2_202603::Configure(ssl); + return cnsa2_202603::Configure(ssl_impl); default: return 0; } } enum ssl_compliance_policy_t SSL_get_compliance_policy(const SSL *ssl) { - return ssl->config->compliance_policy; + return FromOpaque(ssl)->config->compliance_policy; } int SSL_peer_matched_trust_anchor(const SSL *ssl) { - return ssl->s3->hs != nullptr && ssl->s3->hs->peer_matched_trust_anchor; + return FromOpaque(ssl)->s3->hs != nullptr && + FromOpaque(ssl)->s3->hs->peer_matched_trust_anchor; } void SSL_get0_peer_available_trust_anchors(const SSL *ssl, const uint8_t **out, size_t *out_len) { Span<const uint8_t> ret; - if (SSL_HANDSHAKE *hs = ssl->s3->hs.get(); hs != nullptr) { + if (SSL_HANDSHAKE *hs = FromOpaque(ssl)->s3->hs.get(); hs != nullptr) { ret = hs->peer_available_trust_anchors; } *out = ret.data(); @@ -3692,7 +3804,7 @@ int SSL_set1_available_trust_anchors(SSL *ssl, const uint8_t *ids, size_t ids_len) { - if (!ssl->config) { + if (!FromOpaque(ssl)->config) { return 0; } auto span = Span(ids, ids_len); @@ -3700,7 +3812,7 @@ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TRUST_ANCHOR_LIST); return 0; } - return ssl->config->cert->available_trust_anchors.CopyFrom(span); + return FromOpaque(ssl)->config->cert->available_trust_anchors.CopyFrom(span); } int SSL_CTX_set1_requested_trust_anchors(SSL_CTX *ctx, const uint8_t *ids, @@ -3720,7 +3832,7 @@ int SSL_set1_requested_trust_anchors(SSL *ssl, const uint8_t *ids, size_t ids_len) { - if (!ssl->config) { + if (!FromOpaque(ssl)->config) { return 0; } auto span = Span(ids, ids_len); @@ -3732,7 +3844,7 @@ if (!copy.CopyFrom(span)) { return 0; } - ssl->config->requested_trust_anchors = std::move(copy); + FromOpaque(ssl)->config->requested_trust_anchors = std::move(copy); return 1; } @@ -3776,10 +3888,10 @@ int SSL_set1_accepted_peer_cert_types(SSL *ssl, const uint8_t *values, size_t num_values) { - if (!ssl->config) { + if (!FromOpaque(ssl)->config) { return 0; } - return set1_cert_types(&ssl->config->accepted_peer_cert_types, + return set1_cert_types(&FromOpaque(ssl)->config->accepted_peer_cert_types, Span(values, num_values)); } @@ -3792,10 +3904,10 @@ int SSL_set1_available_client_cert_types(SSL *ssl, const uint8_t *values, size_t num_values) { - if (!ssl->config) { + if (!FromOpaque(ssl)->config) { return 0; } - return set1_cert_types(&ssl->config->available_client_cert_types, + return set1_cert_types(&FromOpaque(ssl)->config->available_client_cert_types, Span(values, num_values)); } @@ -3814,21 +3926,21 @@ } void SSL_set_server_padding_request(SSL *ssl, uint16_t num_bytes) { - if (!ssl->config) { + if (!FromOpaque(ssl)->config) { return; } - ssl->config->server_padding_request = num_bytes; + FromOpaque(ssl)->config->server_padding_request = num_bytes; } void SSL_set_server_padding_enabled(SSL *ssl, int enabled) { - if (!ssl->config) { + if (!FromOpaque(ssl)->config) { return; } - ssl->config->server_padding_enabled = enabled; + FromOpaque(ssl)->config->server_padding_enabled = enabled; } int SSL_server_sent_requested_padding(const SSL *ssl) { - return ssl->s3->server_sent_requested_padding; + return FromOpaque(ssl)->s3->server_sent_requested_padding; }
diff --git a/ssl/ssl_privkey.cc b/ssl/ssl_privkey.cc index 4e43717..ae7c9bb 100644 --- a/ssl/ssl_privkey.cc +++ b/ssl/ssl_privkey.cc
@@ -142,7 +142,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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_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 @@ 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_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_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 @@ 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_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 @@ 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_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)); }
diff --git a/ssl/ssl_session.cc b/ssl/ssl_session.cc index 6c94441..4be8b58 100644 --- a/ssl/ssl_session.cc +++ b/ssl/ssl_session.cc
@@ -157,7 +157,7 @@ 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_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 @@ } 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_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 @@ 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_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 @@ 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 @@ 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 @@ 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_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 @@ // 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_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_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,
diff --git a/ssl/ssl_stat.cc b/ssl/ssl_stat.cc index 6201df9..84d26cc 100644 --- a/ssl/ssl_stat.cc +++ b/ssl/ssl_stat.cc
@@ -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 "!!!!!!"; }
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc index 9c8101c..f9ba6a9 100644 --- a/ssl/ssl_test.cc +++ b/ssl/ssl_test.cc
@@ -704,12 +704,13 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ }; // 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) {
diff --git a/ssl/ssl_versions.cc b/ssl/ssl_versions.cc index b5d8f6b..f8d9a9c 100644 --- a/ssl/ssl_versions.cc +++ b/ssl/ssl_versions.cc
@@ -243,7 +243,7 @@ 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 @@ 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 @@ } 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 @@ } 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) {
diff --git a/ssl/ssl_x509.cc b/ssl/ssl_x509.cc index baa7037..31b401f 100644 --- a/ssl/ssl_x509.cc +++ b/ssl/ssl_x509.cc
@@ -36,7 +36,7 @@ // 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 @@ 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 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 @@ 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 @@ } 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_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_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_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_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 @@ 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 @@ } 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 @@ } 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 @@ } 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_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_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_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_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_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 @@ } 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 @@ } 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 @@ // `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 @@ } 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 @@ } 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 @@ 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_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) {
diff --git a/ssl/t1_enc.cc b/ssl/t1_enc.cc index 7c691dc..44504a8 100644 --- a/ssl/t1_enc.cc +++ b/ssl/t1_enc.cc
@@ -47,7 +47,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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);
diff --git a/ssl/tls13_both.cc b/ssl/tls13_both.cc index 62a2a70..68c5ea2 100644 --- a/ssl/tls13_both.cc +++ b/ssl/tls13_both.cc
@@ -104,7 +104,7 @@ 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_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_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_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 @@ } 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 @@ } 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 @@ 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 @@ 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 @@ 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); }
diff --git a/ssl/tls13_client.cc b/ssl/tls13_client.cc index 36bb436..f134ebb 100644 --- a/ssl/tls13_client.cc +++ b/ssl/tls13_client.cc
@@ -57,7 +57,7 @@ // 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 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 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_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 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 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_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_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_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_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_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_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_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 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_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 @@ 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 @@ 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) {
diff --git a/ssl/tls13_enc.cc b/ssl/tls13_enc.cc index e0ae282..84c0249 100644 --- a/ssl/tls13_enc.cc +++ b/ssl/tls13_enc.cc
@@ -177,7 +177,7 @@ 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 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_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_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 @@ 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 @@ 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 @@ 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 =
diff --git a/ssl/tls13_server.cc b/ssl/tls13_server.cc index d09aa53..94de72d 100644 --- a/ssl/tls13_server.cc +++ b/ssl/tls13_server.cc
@@ -70,7 +70,7 @@ 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 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 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_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 @@ // 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 @@ 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 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_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_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_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_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_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 @@ 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_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_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_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_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_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_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_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;
diff --git a/ssl/tls_method.cc b/ssl/tls_method.cc index 0e5d918..a2e4dcf 100644 --- a/ssl/tls_method.cc +++ b/ssl/tls_method.cc
@@ -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 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 @@ 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 @@ 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. }
diff --git a/ssl/tls_record.cc b/ssl/tls_record.cc index 90c79f7..f77d84b 100644 --- a/ssl/tls_record.cc +++ b/ssl/tls_record.cc
@@ -46,7 +46,7 @@ // 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 @@ 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 @@ 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 @@ : 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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;