external/boringssl: Sync to 9f0e7cb314ae64234b928fd379381ae9760a9a5f.
This includes the following changes:
https://boringssl.googlesource.com/boringssl/+log/f11ea19043f2b3ee42e4a76d0645914347e1a36e..9f0e7cb314ae64234b928fd379381ae9760a9a5f
Test: BoringSSL CTS Presubmits.
Change-Id: I9296845fe9db4baae2afc03328c5bc17f76a752f
diff --git a/src/ssl/dtls_record.cc b/src/ssl/dtls_record.cc
index 5e795fa..d348601 100644
--- a/src/ssl/dtls_record.cc
+++ b/src/ssl/dtls_record.cc
@@ -219,8 +219,8 @@
return ssl_open_record_discard;
}
- ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER,
- in.subspan(0, DTLS1_RT_HEADER_LENGTH));
+ Span<const uint8_t> header = in.subspan(0, DTLS1_RT_HEADER_LENGTH);
+ ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, header);
uint16_t epoch = (((uint16_t)sequence[0]) << 8) | sequence[1];
if (epoch != ssl->d1->r_epoch ||
@@ -235,7 +235,7 @@
// discard the body in-place.
if (!ssl->s3->aead_read_ctx->Open(
- out, type, version, sequence,
+ out, type, version, sequence, header,
MakeSpan(const_cast<uint8_t *>(CBS_data(&body)), CBS_len(&body)))) {
// Bad packets are silently dropped in DTLS. See section 4.2.1 of RFC 6347.
// Clear the error queue of any errors decryption may have added. Drop the
@@ -328,25 +328,25 @@
OPENSSL_memcpy(&out[5], &seq[2], 6);
size_t ciphertext_len;
- if (!aead->Seal(out + DTLS1_RT_HEADER_LENGTH, &ciphertext_len,
- max_out - DTLS1_RT_HEADER_LENGTH, type, record_version,
- &out[3] /* seq */, in, in_len) ||
- !ssl_record_sequence_update(&seq[2], 6)) {
- return 0;
- }
-
- if (ciphertext_len >= 1 << 16) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ if (!aead->CiphertextLen(&ciphertext_len, in_len, 0)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
return 0;
}
out[11] = ciphertext_len >> 8;
out[12] = ciphertext_len & 0xff;
+ Span<const uint8_t> header = MakeConstSpan(out, DTLS1_RT_HEADER_LENGTH);
+
+ size_t len_copy;
+ if (!aead->Seal(out + DTLS1_RT_HEADER_LENGTH, &len_copy,
+ max_out - DTLS1_RT_HEADER_LENGTH, type, record_version,
+ &out[3] /* seq */, header, in, in_len) ||
+ !ssl_record_sequence_update(&seq[2], 6)) {
+ return 0;
+ }
+ assert(ciphertext_len == len_copy);
*out_len = DTLS1_RT_HEADER_LENGTH + ciphertext_len;
-
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER,
- MakeSpan(out, DTLS1_RT_HEADER_LENGTH));
-
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, header);
return 1;
}
diff --git a/src/ssl/handoff.cc b/src/ssl/handoff.cc
index dd73c83..2cbbaeb 100644
--- a/src/ssl/handoff.cc
+++ b/src/ssl/handoff.cc
@@ -133,10 +133,6 @@
s3->session_reused ? ssl->session : s3->hs->new_session.get();
if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) ||
!CBB_add_asn1_uint64(&seq, kHandbackVersion) ||
- !CBB_add_asn1_uint64(&seq, ssl->version) ||
- !CBB_add_asn1_uint64(&seq, ssl->conf_max_version) ||
- !CBB_add_asn1_uint64(&seq, ssl->conf_min_version) ||
- !CBB_add_asn1_uint64(&seq, ssl->max_send_fragment) ||
!CBB_add_asn1_octet_string(&seq, s3->read_sequence,
sizeof(s3->read_sequence)) ||
!CBB_add_asn1_octet_string(&seq, s3->write_sequence,
@@ -148,7 +144,6 @@
!CBB_add_asn1_octet_string(&seq, read_iv, iv_len) ||
!CBB_add_asn1_octet_string(&seq, write_iv, iv_len) ||
!CBB_add_asn1_bool(&seq, s3->session_reused) ||
- !CBB_add_asn1_bool(&seq, s3->send_connection_binding) ||
!CBB_add_asn1_bool(&seq, s3->tlsext_channel_id_valid) ||
!ssl_session_serialize(session, &seq) ||
!CBB_add_asn1_octet_string(&seq, s3->next_proto_negotiated.data(),
@@ -160,14 +155,8 @@
hostname_len) ||
!CBB_add_asn1_octet_string(&seq, s3->tlsext_channel_id,
sizeof(s3->tlsext_channel_id)) ||
- !CBB_add_asn1_uint64(&seq, ssl->options) ||
- !CBB_add_asn1_uint64(&seq, ssl->mode) ||
- !CBB_add_asn1_uint64(&seq, ssl->max_cert_list) ||
- !CBB_add_asn1_bool(&seq, ssl->quiet_shutdown) ||
- !CBB_add_asn1_bool(&seq, ssl->tlsext_channel_id_enabled) ||
- !CBB_add_asn1_bool(&seq, ssl->retain_only_sha256_of_client_certs) ||
- !CBB_add_asn1_bool(&seq, ssl->token_binding_negotiated) ||
- !CBB_add_asn1_uint64(&seq, ssl->negotiated_token_binding_param) ||
+ !CBB_add_asn1_bool(&seq, ssl->s3->token_binding_negotiated) ||
+ !CBB_add_asn1_uint64(&seq, ssl->s3->negotiated_token_binding_param) ||
!CBB_add_asn1_bool(&seq, s3->hs->next_proto_neg_seen) ||
!CBB_add_asn1_bool(&seq, s3->hs->cert_request) ||
!CBB_add_asn1_bool(&seq, s3->hs->extended_master_secret) ||
@@ -191,16 +180,12 @@
}
SSL3_STATE *const s3 = ssl->s3;
- uint64_t handback_version, version, conf_max_version, conf_min_version,
- max_send_fragment, options, mode, max_cert_list,
- negotiated_token_binding_param, cipher;
+ uint64_t handback_version, negotiated_token_binding_param, cipher;
CBS seq, read_seq, write_seq, server_rand, client_rand, read_iv, write_iv,
next_proto, alpn, hostname, channel_id, transcript, key_share;
- int session_reused, send_connection_binding, channel_id_valid, quiet_shutdown,
- channel_id_enabled, retain_only_sha256, cert_request,
- extended_master_secret, ticket_expected, token_binding_negotiated,
- next_proto_neg_seen;
+ int session_reused, channel_id_valid, cert_request, extended_master_secret,
+ ticket_expected, token_binding_negotiated, next_proto_neg_seen;
SSL_SESSION *session = nullptr;
CBS handback_cbs(handback);
@@ -210,11 +195,7 @@
return false;
}
- if (!CBS_get_asn1_uint64(&seq, &version) ||
- !CBS_get_asn1_uint64(&seq, &conf_max_version) ||
- !CBS_get_asn1_uint64(&seq, &conf_min_version) ||
- !CBS_get_asn1_uint64(&seq, &max_send_fragment) ||
- !CBS_get_asn1(&seq, &read_seq, CBS_ASN1_OCTETSTRING) ||
+ if (!CBS_get_asn1(&seq, &read_seq, CBS_ASN1_OCTETSTRING) ||
CBS_len(&read_seq) != sizeof(s3->read_sequence) ||
!CBS_get_asn1(&seq, &write_seq, CBS_ASN1_OCTETSTRING) ||
CBS_len(&write_seq) != sizeof(s3->write_sequence) ||
@@ -229,7 +210,6 @@
!CBS_get_asn1(&seq, &read_iv, CBS_ASN1_OCTETSTRING) ||
!CBS_get_asn1(&seq, &write_iv, CBS_ASN1_OCTETSTRING) ||
!CBS_get_asn1_bool(&seq, &session_reused) ||
- !CBS_get_asn1_bool(&seq, &send_connection_binding) ||
!CBS_get_asn1_bool(&seq, &channel_id_valid)) {
return false;
}
@@ -253,12 +233,6 @@
CBS_len(&channel_id) != sizeof(s3->tlsext_channel_id) ||
!CBS_copy_bytes(&channel_id, s3->tlsext_channel_id,
sizeof(s3->tlsext_channel_id)) ||
- !CBS_get_asn1_uint64(&seq, &options) ||
- !CBS_get_asn1_uint64(&seq, &mode) ||
- !CBS_get_asn1_uint64(&seq, &max_cert_list) ||
- !CBS_get_asn1_bool(&seq, &quiet_shutdown) ||
- !CBS_get_asn1_bool(&seq, &channel_id_enabled) ||
- !CBS_get_asn1_bool(&seq, &retain_only_sha256) ||
!CBS_get_asn1_bool(&seq, &token_binding_negotiated) ||
!CBS_get_asn1_uint64(&seq, &negotiated_token_binding_param) ||
!CBS_get_asn1_bool(&seq, &next_proto_neg_seen) ||
@@ -277,21 +251,14 @@
return false;
}
- ssl->version = version;
- ssl->conf_max_version = conf_max_version;
- ssl->conf_min_version = conf_min_version;
- ssl->max_send_fragment = max_send_fragment;
+ ssl->version = session->ssl_version;
ssl->do_handshake = ssl_server_handshake;
ssl->server = true;
- ssl->options = options;
- ssl->mode = mode;
- ssl->max_cert_list = max_cert_list;
s3->have_version = true;
s3->hs->state = CBS_len(&transcript) == 0 ? state12_finish_server_handshake
: state12_read_client_certificate;
s3->session_reused = session_reused;
- s3->send_connection_binding = send_connection_binding;
s3->tlsext_channel_id_valid = channel_id_valid;
s3->next_proto_negotiated.CopyFrom(next_proto);
s3->alpn_selected.CopyFrom(alpn);
@@ -307,11 +274,8 @@
s3->hostname.reset(hostname_str);
}
- ssl->quiet_shutdown = quiet_shutdown;
- ssl->tlsext_channel_id_enabled = channel_id_enabled;
- ssl->retain_only_sha256_of_client_certs = retain_only_sha256;
- ssl->token_binding_negotiated = token_binding_negotiated;
- ssl->negotiated_token_binding_param =
+ s3->token_binding_negotiated = token_binding_negotiated;
+ s3->negotiated_token_binding_param =
static_cast<uint8_t>(negotiated_token_binding_param);
s3->hs->next_proto_neg_seen = next_proto_neg_seen;
s3->hs->wait = ssl_hs_flush;
diff --git a/src/ssl/handshake_client.cc b/src/ssl/handshake_client.cc
index 0b352c2..087645d 100644
--- a/src/ssl/handshake_client.cc
+++ b/src/ssl/handshake_client.cc
@@ -740,7 +740,7 @@
return ssl_hs_error;
}
- if (ssl->token_binding_negotiated &&
+ if (ssl->s3->token_binding_negotiated &&
(!hs->extended_master_secret || !ssl->s3->send_connection_binding)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI);
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
diff --git a/src/ssl/handshake_server.cc b/src/ssl/handshake_server.cc
index 5f2f41f..7ade8fc 100644
--- a/src/ssl/handshake_server.cc
+++ b/src/ssl/handshake_server.cc
@@ -334,7 +334,7 @@
SSL_HANDSHAKE *hs, const SSL_CLIENT_HELLO *client_hello,
const struct ssl_cipher_preference_list_st *server_pref) {
SSL *const ssl = hs->ssl;
- STACK_OF(SSL_CIPHER) *prio, *allow;
+ 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
// comment about |in_group_flags| in the |ssl_cipher_preference_list_st|
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index e884b63..f4dc96f 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -657,19 +657,26 @@
bool SuffixLen(size_t *out_suffix_len, size_t in_len,
size_t extra_in_len) const;
+ // CiphertextLen calculates the total ciphertext length written by
+ // |SealScatter| and writes it to |*out_len|. It returns true on success and
+ // false on error. |in_len| and |extra_in_len| should equal the argument of
+ // the same names passed to |SealScatter|.
+ bool CiphertextLen(size_t *out_len, size_t in_len, size_t extra_in_len) const;
+
// Open authenticates and decrypts |in| in-place. On success, it sets |*out|
// to the plaintext in |in| and returns true. Otherwise, it returns
// false. The output will always be |ExplicitNonceLen| bytes ahead of |in|.
bool Open(Span<uint8_t> *out, uint8_t type, uint16_t record_version,
- const uint8_t seqnum[8], Span<uint8_t> in);
+ const uint8_t seqnum[8], Span<const uint8_t> header,
+ Span<uint8_t> in);
// Seal encrypts and authenticates |in_len| bytes from |in| and writes the
// result to |out|. It returns true on success and false on error.
//
// If |in| and |out| alias then |out| + |ExplicitNonceLen| must be == |in|.
bool Seal(uint8_t *out, size_t *out_len, size_t max_out, uint8_t type,
- uint16_t record_version, const uint8_t seqnum[8], const uint8_t *in,
- size_t in_len);
+ uint16_t record_version, const uint8_t seqnum[8],
+ Span<const uint8_t> header, const uint8_t *in, size_t in_len);
// SealScatter encrypts and authenticates |in_len| bytes from |in| and splits
// the result between |out_prefix|, |out| and |out_suffix|. It returns one on
@@ -688,17 +695,20 @@
// alias anything.
bool SealScatter(uint8_t *out_prefix, uint8_t *out, uint8_t *out_suffix,
uint8_t type, uint16_t record_version,
- const uint8_t seqnum[8], const uint8_t *in, size_t in_len,
- const uint8_t *extra_in, size_t extra_in_len);
+ const uint8_t seqnum[8], Span<const uint8_t> header,
+ const uint8_t *in, size_t in_len, const uint8_t *extra_in,
+ size_t extra_in_len);
bool GetIV(const uint8_t **out_iv, size_t *out_iv_len) const;
private:
- // GetAdditionalData writes the additional data into |out| and returns the
- // number of bytes written.
- size_t GetAdditionalData(uint8_t out[13], uint8_t type,
- uint16_t record_version, const uint8_t seqnum[8],
- size_t plaintext_len, size_t ciphertext_len);
+ // GetAdditionalData returns the additional data, writing into |storage| if
+ // necessary.
+ Span<const uint8_t> GetAdditionalData(uint8_t storage[13], uint8_t type,
+ uint16_t record_version,
+ const uint8_t seqnum[8],
+ size_t plaintext_len,
+ Span<const uint8_t> header);
const SSL_CIPHER *cipher_;
ScopedEVP_AEAD_CTX ctx_;
@@ -717,6 +727,9 @@
// randomly generated, rather than derived from the sequence
// number.
bool random_variable_nonce_ : 1;
+ // xor_fixed_nonce_ is true if the fixed nonce should be XOR'd into the
+ // variable nonce rather than prepended.
+ bool xor_fixed_nonce_ : 1;
// omit_length_in_ad_ is true if the length should be omitted in the
// AEAD's ad parameter.
bool omit_length_in_ad_ : 1;
@@ -725,12 +738,8 @@
bool omit_version_in_ad_ : 1;
// omit_ad_ is true if the AEAD's ad parameter should be omitted.
bool omit_ad_ : 1;
- // tls13_ad_ is true if the AEAD's ad parameter should be based on the
- // TLS 1.3 format.
- bool tls13_ad_ : 1;
- // xor_fixed_nonce_ is true if the fixed nonce should be XOR'd into the
- // variable nonce rather than prepended.
- bool xor_fixed_nonce_ : 1;
+ // ad_is_header_ is true if the AEAD's ad parameter is the record header.
+ bool ad_is_header_ : 1;
};
@@ -2299,6 +2308,10 @@
// key_update_count is the number of consecutive KeyUpdates received.
uint8_t key_update_count = 0;
+ // The negotiated Token Binding key parameter. Only valid if
+ // |token_binding_negotiated| is set.
+ uint8_t negotiated_token_binding_param = 0;
+
// skip_early_data instructs the record layer to skip unexpected early data
// messages when 0RTT is rejected.
bool skip_early_data:1;
@@ -2348,6 +2361,9 @@
// fired, were it not a draft.
bool draft_downgrade:1;
+ // token_binding_negotiated is set if Token Binding was negotiated.
+ bool token_binding_negotiated:1;
+
// hs_buf is the buffer of handshake data to process.
UniquePtr<BUF_MEM> hs_buf;
@@ -2671,10 +2687,6 @@
uint8_t *token_binding_params;
size_t token_binding_params_len;
- // The negotiated Token Binding key parameter. Only valid if
- // |token_binding_negotiated| is set.
- uint8_t negotiated_token_binding_param;
-
// Contains the QUIC transport params that this endpoint will send.
uint8_t *quic_transport_params;
size_t quic_transport_params_len;
@@ -2706,9 +2718,6 @@
// we'll advertise support.
bool tlsext_channel_id_enabled:1;
- // token_binding_negotiated is set if Token Binding was negotiated.
- bool token_binding_negotiated:1;
-
// retain_only_sha256_of_client_certs is true if we should compute the SHA256
// hash of the peer's certificate and then discard it to save memory and
// session space. Only effective on the server side.
diff --git a/src/ssl/s3_lib.cc b/src/ssl/s3_lib.cc
index a3fc8d7..baa5a17 100644
--- a/src/ssl/s3_lib.cc
+++ b/src/ssl/s3_lib.cc
@@ -177,7 +177,8 @@
key_update_pending(false),
wpend_pending(false),
early_data_accepted(false),
- draft_downgrade(false) {}
+ draft_downgrade(false),
+ token_binding_negotiated(false) {}
SSL3_STATE::~SSL3_STATE() {}
diff --git a/src/ssl/ssl_aead_ctx.cc b/src/ssl/ssl_aead_ctx.cc
index e6b3ee9..363c959 100644
--- a/src/ssl/ssl_aead_ctx.cc
+++ b/src/ssl/ssl_aead_ctx.cc
@@ -40,11 +40,11 @@
is_dtls_(is_dtls_arg),
variable_nonce_included_in_record_(false),
random_variable_nonce_(false),
+ xor_fixed_nonce_(false),
omit_length_in_ad_(false),
omit_version_in_ad_(false),
omit_ad_(false),
- tls13_ad_(false),
- xor_fixed_nonce_(false) {
+ ad_is_header_(false) {
OPENSSL_memset(fixed_nonce_, 0, sizeof(fixed_nonce_));
}
@@ -136,7 +136,7 @@
aead_ctx->variable_nonce_len_ = 8;
aead_ctx->variable_nonce_included_in_record_ = false;
if (ssl_is_draft28(version)) {
- aead_ctx->tls13_ad_ = true;
+ aead_ctx->ad_is_header_ = true;
} else {
aead_ctx->omit_ad_ = true;
}
@@ -198,6 +198,22 @@
extra_in_len);
}
+bool SSLAEADContext::CiphertextLen(size_t *out_len, const size_t in_len,
+ const size_t extra_in_len) const {
+ size_t len;
+ if (!SuffixLen(&len, in_len, extra_in_len)) {
+ return false;
+ }
+ len += ExplicitNonceLen();
+ len += in_len;
+ if (len < in_len || len >= 0xffff) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return false;
+ }
+ *out_len = len;
+ return true;
+}
+
size_t SSLAEADContext::MaxOverhead() const {
return ExplicitNonceLen() +
(is_null_cipher() || FUZZER_MODE
@@ -205,38 +221,34 @@
: EVP_AEAD_max_overhead(EVP_AEAD_CTX_aead(ctx_.get())));
}
-size_t SSLAEADContext::GetAdditionalData(uint8_t out[13], uint8_t type,
- uint16_t record_version,
- const uint8_t seqnum[8],
- size_t plaintext_len,
- size_t ciphertext_len) {
- if (omit_ad_) {
- return 0;
+Span<const uint8_t> SSLAEADContext::GetAdditionalData(
+ uint8_t storage[13], uint8_t type, uint16_t record_version,
+ const uint8_t seqnum[8], size_t plaintext_len, Span<const uint8_t> header) {
+ if (ad_is_header_) {
+ return header;
}
- size_t len = 0;
- if (!tls13_ad_) {
- OPENSSL_memcpy(out, seqnum, 8);
- len += 8;
+ if (omit_ad_) {
+ return {};
}
- out[len++] = type;
+
+ OPENSSL_memcpy(storage, seqnum, 8);
+ size_t len = 8;
+ storage[len++] = type;
if (!omit_version_in_ad_) {
- out[len++] = static_cast<uint8_t>((record_version >> 8));
- out[len++] = static_cast<uint8_t>(record_version);
+ storage[len++] = static_cast<uint8_t>((record_version >> 8));
+ storage[len++] = static_cast<uint8_t>(record_version);
}
- if (tls13_ad_) {
- out[len++] = static_cast<uint8_t>((ciphertext_len >> 8));
- out[len++] = static_cast<uint8_t>(ciphertext_len);
- } else if (!omit_length_in_ad_) {
- out[len++] = static_cast<uint8_t>((plaintext_len >> 8));
- out[len++] = static_cast<uint8_t>(plaintext_len);
+ if (!omit_length_in_ad_) {
+ storage[len++] = static_cast<uint8_t>((plaintext_len >> 8));
+ storage[len++] = static_cast<uint8_t>(plaintext_len);
}
- return len;
+ return MakeConstSpan(storage, len);
}
bool SSLAEADContext::Open(Span<uint8_t> *out, uint8_t type,
uint16_t record_version, const uint8_t seqnum[8],
- Span<uint8_t> in) {
+ Span<const uint8_t> header, Span<uint8_t> in) {
if (is_null_cipher() || FUZZER_MODE) {
// Handle the initial NULL cipher.
*out = in;
@@ -255,9 +267,10 @@
}
plaintext_len = in.size() - overhead;
}
- uint8_t ad[13];
- size_t ad_len = GetAdditionalData(ad, type, record_version, seqnum,
- plaintext_len, in.size());
+
+ uint8_t ad_storage[13];
+ Span<const uint8_t> ad = GetAdditionalData(ad_storage, type, record_version,
+ seqnum, plaintext_len, header);
// Assemble the nonce.
uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
@@ -298,7 +311,8 @@
// Decrypt in-place.
size_t len;
if (!EVP_AEAD_CTX_open(ctx_.get(), in.data(), &len, in.size(), nonce,
- nonce_len, in.data(), in.size(), ad, ad_len)) {
+ nonce_len, in.data(), in.size(), ad.data(),
+ ad.size())) {
return false;
}
*out = in.subspan(0, len);
@@ -308,7 +322,8 @@
bool SSLAEADContext::SealScatter(uint8_t *out_prefix, uint8_t *out,
uint8_t *out_suffix, uint8_t type,
uint16_t record_version,
- const uint8_t seqnum[8], const uint8_t *in,
+ const uint8_t seqnum[8],
+ Span<const uint8_t> header, const uint8_t *in,
size_t in_len, const uint8_t *extra_in,
size_t extra_in_len) {
const size_t prefix_len = ExplicitNonceLen();
@@ -331,9 +346,9 @@
return true;
}
- uint8_t ad[13];
- size_t ad_len = GetAdditionalData(ad, type, record_version, seqnum, in_len,
- in_len + suffix_len);
+ uint8_t ad_storage[13];
+ Span<const uint8_t> ad = GetAdditionalData(ad_storage, type, record_version,
+ seqnum, in_len, header);
// Assemble the nonce.
uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
@@ -384,15 +399,15 @@
size_t written_suffix_len;
bool result = !!EVP_AEAD_CTX_seal_scatter(
ctx_.get(), out, out_suffix, &written_suffix_len, suffix_len, nonce,
- nonce_len, in, in_len, extra_in, extra_in_len, ad, ad_len);
+ nonce_len, in, in_len, extra_in, extra_in_len, ad.data(), ad.size());
assert(!result || written_suffix_len == suffix_len);
return result;
}
bool SSLAEADContext::Seal(uint8_t *out, size_t *out_len, size_t max_out_len,
uint8_t type, uint16_t record_version,
- const uint8_t seqnum[8], const uint8_t *in,
- size_t in_len) {
+ const uint8_t seqnum[8], Span<const uint8_t> header,
+ const uint8_t *in, size_t in_len) {
const size_t prefix_len = ExplicitNonceLen();
size_t suffix_len;
if (!SuffixLen(&suffix_len, in_len, 0)) {
@@ -410,7 +425,7 @@
}
if (!SealScatter(out, out + prefix_len, out + prefix_len + in_len, type,
- record_version, seqnum, in, in_len, 0, 0)) {
+ record_version, seqnum, header, in, in_len, 0, 0)) {
return false;
}
*out_len = prefix_len + in_len + suffix_len;
diff --git a/src/ssl/ssl_file.cc b/src/ssl/ssl_file.cc
index bafa64a..ca4b0be 100644
--- a/src/ssl/ssl_file.cc
+++ b/src/ssl/ssl_file.cc
@@ -165,6 +165,7 @@
}
// Check for duplicates.
+ sk_X509_NAME_sort(sk);
if (sk_X509_NAME_find(sk, NULL, xn)) {
continue;
}
@@ -223,6 +224,7 @@
}
// Check for duplicates.
+ sk_X509_NAME_sort(stack);
if (sk_X509_NAME_find(stack, NULL, xn)) {
continue;
}
diff --git a/src/ssl/ssl_key_share.cc b/src/ssl/ssl_key_share.cc
index 2a076c3..c7f6f88 100644
--- a/src/ssl/ssl_key_share.cc
+++ b/src/ssl/ssl_key_share.cc
@@ -248,11 +248,11 @@
UniquePtr<SSLKeyShare> SSLKeyShare::Create(CBS *in) {
uint64_t group;
- if (!CBS_get_asn1_uint64(in, &group)) {
+ if (!CBS_get_asn1_uint64(in, &group) || group > 0xffff) {
return nullptr;
}
- UniquePtr<SSLKeyShare> key_share = Create(static_cast<uint64_t>(group));
- if (!key_share->Deserialize(in)) {
+ UniquePtr<SSLKeyShare> key_share = Create(static_cast<uint16_t>(group));
+ if (!key_share || !key_share->Deserialize(in)) {
return nullptr;
}
return key_share;
diff --git a/src/ssl/ssl_lib.cc b/src/ssl/ssl_lib.cc
index 6312504..14fb0ff 100644
--- a/src/ssl/ssl_lib.cc
+++ b/src/ssl/ssl_lib.cc
@@ -2164,11 +2164,11 @@
}
int SSL_is_token_binding_negotiated(const SSL *ssl) {
- return ssl->token_binding_negotiated;
+ return ssl->s3->token_binding_negotiated;
}
uint8_t SSL_get_negotiated_token_binding_param(const SSL *ssl) {
- return ssl->negotiated_token_binding_param;
+ return ssl->s3->negotiated_token_binding_param;
}
size_t SSL_get0_certificate_types(SSL *ssl, const uint8_t **out_types) {
diff --git a/src/ssl/ssl_session.cc b/src/ssl/ssl_session.cc
index 34e7b31..bc2c14c 100644
--- a/src/ssl/ssl_session.cc
+++ b/src/ssl/ssl_session.cc
@@ -990,6 +990,10 @@
return session->tlsext_tick_lifetime_hint;
}
+const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *session) {
+ return session->cipher;
+}
+
SSL_SESSION *SSL_magic_pending_session_ptr(void) {
return (SSL_SESSION *)&g_pending_session_magic;
}
diff --git a/src/ssl/t1_lib.cc b/src/ssl/t1_lib.cc
index 97c0c4b..2d3a664 100644
--- a/src/ssl/t1_lib.cc
+++ b/src/ssl/t1_lib.cc
@@ -2528,8 +2528,8 @@
for (size_t i = 0; i < ssl->token_binding_params_len; ++i) {
if (param == ssl->token_binding_params[i]) {
- ssl->negotiated_token_binding_param = param;
- ssl->token_binding_negotiated = true;
+ ssl->s3->negotiated_token_binding_param = param;
+ ssl->s3->token_binding_negotiated = true;
return true;
}
}
@@ -2547,7 +2547,7 @@
uint8_t tb_param = ssl->token_binding_params[i];
for (uint8_t peer_param : peer_params) {
if (tb_param == peer_param) {
- ssl->negotiated_token_binding_param = tb_param;
+ ssl->s3->negotiated_token_binding_param = tb_param;
return true;
}
}
@@ -2587,14 +2587,14 @@
return true;
}
- ssl->token_binding_negotiated = true;
+ ssl->s3->token_binding_negotiated = true;
return true;
}
static bool ext_token_binding_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
- if (!ssl->token_binding_negotiated) {
+ if (!ssl->s3->token_binding_negotiated) {
return true;
}
@@ -2603,7 +2603,7 @@
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_u16(&contents, hs->negotiated_token_binding_version) ||
!CBB_add_u8_length_prefixed(&contents, ¶ms) ||
- !CBB_add_u8(¶ms, ssl->negotiated_token_binding_param) ||
+ !CBB_add_u8(¶ms, ssl->s3->negotiated_token_binding_param) ||
!CBB_flush(out)) {
return false;
}
@@ -3220,7 +3220,7 @@
static int ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (ssl->token_binding_negotiated &&
+ if (ssl->s3->token_binding_negotiated &&
!(SSL_get_secure_renegotiation_support(ssl) &&
SSL_get_extms_support(ssl))) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI);
diff --git a/src/ssl/tls13_client.cc b/src/ssl/tls13_client.cc
index aa05456..6e328b8 100644
--- a/src/ssl/tls13_client.cc
+++ b/src/ssl/tls13_client.cc
@@ -436,7 +436,7 @@
return ssl_hs_error;
}
if (ssl->s3->tlsext_channel_id_valid || hs->received_custom_extension ||
- ssl->token_binding_negotiated) {
+ ssl->s3->token_binding_negotiated) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION_ON_EARLY_DATA);
return ssl_hs_error;
}
diff --git a/src/ssl/tls13_server.cc b/src/ssl/tls13_server.cc
index 3bd6786..9d7f5e0 100644
--- a/src/ssl/tls13_server.cc
+++ b/src/ssl/tls13_server.cc
@@ -391,7 +391,7 @@
// Channel ID is incompatible with 0-RTT.
!ssl->s3->tlsext_channel_id_valid &&
// If Token Binding is negotiated, reject 0-RTT.
- !ssl->token_binding_negotiated &&
+ !ssl->s3->token_binding_negotiated &&
// Custom extensions is incompatible with 0-RTT.
hs->custom_extensions.received == 0 &&
// The negotiated ALPN must match the one in the ticket.
diff --git a/src/ssl/tls_record.cc b/src/ssl/tls_record.cc
index 3152e7a..a2e4a20 100644
--- a/src/ssl/tls_record.cc
+++ b/src/ssl/tls_record.cc
@@ -258,8 +258,8 @@
return ssl_open_record_partial;
}
- ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER,
- in.subspan(0, SSL3_RT_HEADER_LENGTH));
+ Span<const uint8_t> header = in.subspan(0, SSL3_RT_HEADER_LENGTH);
+ ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, header);
*out_consumed = in.size() - CBS_len(&cbs);
@@ -288,7 +288,7 @@
// Decrypt the body in-place.
if (!ssl->s3->aead_read_ctx->Open(
- out, type, version, ssl->s3->read_sequence,
+ out, type, version, ssl->s3->read_sequence, header,
MakeSpan(const_cast<uint8_t *>(CBS_data(&body)), CBS_len(&body)))) {
if (ssl->s3->skip_early_data && !ssl->s3->aead_read_ctx->is_null_cipher()) {
ERR_clear_error();
@@ -376,27 +376,22 @@
static int do_seal_record(SSL *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();
uint8_t *extra_in = NULL;
size_t extra_in_len = 0;
- if (!ssl->s3->aead_write_ctx->is_null_cipher() &&
- ssl->s3->aead_write_ctx->ProtocolVersion() >= TLS1_3_VERSION) {
+ if (!aead->is_null_cipher() &&
+ aead->ProtocolVersion() >= TLS1_3_VERSION) {
// TLS 1.3 hides the actual record type inside the encrypted data.
extra_in = &type;
extra_in_len = 1;
}
- size_t suffix_len;
- if (!ssl->s3->aead_write_ctx->SuffixLen(&suffix_len, in_len, extra_in_len)) {
+ size_t suffix_len, ciphertext_len;
+ if (!aead->SuffixLen(&suffix_len, in_len, extra_in_len) ||
+ !aead->CiphertextLen(&ciphertext_len, in_len, extra_in_len)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
return 0;
}
- size_t ciphertext_len =
- ssl->s3->aead_write_ctx->ExplicitNonceLen() + suffix_len;
- if (ciphertext_len + in_len < ciphertext_len) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
- return 0;
- }
- ciphertext_len += in_len;
assert(in == out || !buffers_alias(in, in_len, out, in_len));
assert(!buffers_alias(in, in_len, out_prefix, ssl_record_prefix_len(ssl)));
@@ -408,28 +403,27 @@
out_prefix[0] = type;
}
- uint16_t record_version = ssl->s3->aead_write_ctx->RecordVersion();
+ uint16_t record_version = aead->RecordVersion();
out_prefix[1] = record_version >> 8;
out_prefix[2] = record_version & 0xff;
out_prefix[3] = ciphertext_len >> 8;
out_prefix[4] = ciphertext_len & 0xff;
+ Span<const uint8_t> header = MakeSpan(out_prefix, SSL3_RT_HEADER_LENGTH);
- if (!ssl->s3->aead_write_ctx->SealScatter(
- out_prefix + SSL3_RT_HEADER_LENGTH, out, out_suffix, out_prefix[0],
- record_version, ssl->s3->write_sequence, in, in_len, extra_in,
- extra_in_len) ||
+ if (!aead->SealScatter(out_prefix + SSL3_RT_HEADER_LENGTH, out, out_suffix,
+ out_prefix[0], record_version, ssl->s3->write_sequence,
+ header, in, in_len, extra_in, extra_in_len) ||
!ssl_record_sequence_update(ssl->s3->write_sequence, 8)) {
return 0;
}
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER,
- MakeSpan(out_prefix, SSL3_RT_HEADER_LENGTH));
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, header);
return 1;
}
static size_t tls_seal_scatter_prefix_len(const SSL *ssl, uint8_t type,
- size_t in_len) {
+ size_t in_len) {
size_t ret = SSL3_RT_HEADER_LENGTH;
if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 &&
ssl_needs_record_splitting(ssl)) {