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