summaryrefslogtreecommitdiff
path: root/src/ssl/internal.h
diff options
context:
space:
mode:
authorSergey Volnov <volnov@google.com>2021-07-23 12:29:55 +0000
committerSergey Volnov <volnov@google.com>2021-07-23 12:29:55 +0000
commit62b47fae9dba725737229b6d3421558d771f0bdd (patch)
tree2ff121f1dae706d8e23f32b0c0706b4931b7602d /src/ssl/internal.h
parentd03f4c0ac5663fb300b1f40f1059c4194dd0652a (diff)
downloadboringssl-62b47fae9dba725737229b6d3421558d771f0bdd.tar.gz
Revert "external/boringssl: Sync to 7a817f48bafee508b2d23ad278f892ee1cb32b91."
This reverts commit d03f4c0ac5663fb300b1f40f1059c4194dd0652a. Reason for revert: Investigating b/194282044 Change-Id: I168d73caae2cbc83921133cd47aef37d3bce8c37
Diffstat (limited to 'src/ssl/internal.h')
-rw-r--r--src/ssl/internal.h572
1 files changed, 137 insertions, 435 deletions
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 3b7326ae..b3b75405 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -152,9 +152,7 @@
#include <utility>
#include <openssl/aead.h>
-#include <openssl/curve25519.h>
#include <openssl/err.h>
-#include <openssl/hpke.h>
#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/span.h>
@@ -163,7 +161,6 @@
#include "../crypto/err/internal.h"
#include "../crypto/internal.h"
-#include "../crypto/lhash/internal.h"
#if defined(OPENSSL_WINDOWS)
@@ -279,9 +276,9 @@ class Array {
T &operator[](size_t i) { return data_[i]; }
T *begin() { return data_; }
- const T *begin() const { return data_; }
+ const T *cbegin() const { return data_; }
T *end() { return data_ + size_; }
- const T *end() const { return data_ + size_; }
+ const T *cend() const { return data_ + size_; }
void Reset() { Reset(nullptr, 0); }
@@ -381,8 +378,6 @@ class GrowableArray {
return *this;
}
- const T *data() const { return array_.data(); }
- T *data() { return array_.data(); }
size_t size() const { return size_; }
bool empty() const { return size_ == 0; }
@@ -390,9 +385,9 @@ class GrowableArray {
T &operator[](size_t i) { return array_[i]; }
T *begin() { return array_.data(); }
- const T *begin() const { return array_.data(); }
+ const T *cbegin() const { return array_.data(); }
T *end() { return array_.data() + size_; }
- const T *end() const { return array_.data() + size_; }
+ const T *cend() const { return array_.data() + size_; }
void clear() {
size_ = 0;
@@ -489,17 +484,15 @@ bool ssl_get_version_range(const SSL_HANDSHAKE *hs, uint16_t *out_min_version,
uint16_t *out_max_version);
// ssl_supports_version returns whether |hs| supports |version|.
-bool ssl_supports_version(const SSL_HANDSHAKE *hs, uint16_t version);
+bool ssl_supports_version(SSL_HANDSHAKE *hs, uint16_t version);
// ssl_method_supports_version returns whether |method| supports |version|.
bool ssl_method_supports_version(const SSL_PROTOCOL_METHOD *method,
uint16_t version);
// ssl_add_supported_versions writes the supported versions of |hs| to |cbb|, in
-// decreasing preference order. The version list is filtered to those whose
-// protocol version is at least |extra_min_version|.
-bool ssl_add_supported_versions(const SSL_HANDSHAKE *hs, CBB *cbb,
- uint16_t extra_min_version);
+// decreasing preference order.
+bool ssl_add_supported_versions(SSL_HANDSHAKE *hs, CBB *cbb);
// ssl_negotiate_version negotiates a common version based on |hs|'s preferences
// and the peer preference list in |peer_versions|. On success, it returns true
@@ -682,9 +675,6 @@ class SSLTranscript {
SSLTranscript();
~SSLTranscript();
- SSLTranscript(SSLTranscript &&other) = default;
- SSLTranscript &operator=(SSLTranscript &&other) = default;
-
// Init initializes the handshake transcript. If called on an existing
// transcript, it resets the transcript and hash. It returns true on success
// and false on failure.
@@ -706,9 +696,9 @@ class SSLTranscript {
// the transcript. It returns true on success and false on failure. If the
// handshake buffer is still present, |digest| may be any supported digest.
// Otherwise, |digest| must match the transcript hash.
- bool CopyToHashContext(EVP_MD_CTX *ctx, const EVP_MD *digest) const;
+ bool CopyToHashContext(EVP_MD_CTX *ctx, const EVP_MD *digest);
- Span<const uint8_t> buffer() const {
+ Span<const uint8_t> buffer() {
return MakeConstSpan(reinterpret_cast<const uint8_t *>(buffer_->data),
buffer_->length);
}
@@ -731,14 +721,14 @@ class SSLTranscript {
// GetHash writes the handshake hash to |out| which must have room for at
// least |DigestLen| bytes. On success, it returns true and sets |*out_len| to
// the number of bytes written. Otherwise, it returns false.
- bool GetHash(uint8_t *out, size_t *out_len) const;
+ bool GetHash(uint8_t *out, size_t *out_len);
// GetFinishedMAC computes the MAC for the Finished message into the bytes
// pointed by |out| and writes the number of bytes to |*out_len|. |out| must
// have room for |EVP_MAX_MD_SIZE| bytes. It returns true on success and false
// on failure.
bool GetFinishedMAC(uint8_t *out, size_t *out_len, const SSL_SESSION *session,
- bool from_server) const;
+ bool from_server);
private:
// buffer_, if non-null, contains the handshake transcript.
@@ -1076,10 +1066,6 @@ class SSLKeyShare {
// |Serialize|.
static UniquePtr<SSLKeyShare> Create(CBS *in);
- // Serializes writes the group ID and private key, in a format that can be
- // read by |Create|.
- bool Serialize(CBB *out);
-
// GroupID returns the group ID.
virtual uint16_t GroupID() const PURE_VIRTUAL;
@@ -1104,13 +1090,13 @@ class SSLKeyShare {
virtual bool Finish(Array<uint8_t> *out_secret, uint8_t *out_alert,
Span<const uint8_t> peer_key) PURE_VIRTUAL;
- // SerializePrivateKey writes the private key to |out|, returning true if
- // successful and false otherwise. It should be called after |Offer|.
- virtual bool SerializePrivateKey(CBB *out) { return false; }
+ // Serialize writes the state of the key exchange to |out|, returning true if
+ // successful and false otherwise.
+ virtual bool Serialize(CBB *out) { return false; }
- // DeserializePrivateKey initializes the state of the key exchange from |in|,
- // returning true if successful and false otherwise.
- virtual bool DeserializePrivateKey(CBS *in) { return false; }
+ // Deserialize initializes the state of the key exchange from |in|, returning
+ // true if successful and false otherwise. It is called by |Create|.
+ virtual bool Deserialize(CBS *in) { return false; }
};
struct NamedGroup {
@@ -1366,10 +1352,9 @@ bool ssl_on_certificate_selected(SSL_HANDSHAKE *hs);
bool tls13_init_key_schedule(SSL_HANDSHAKE *hs, Span<const uint8_t> psk);
// tls13_init_early_key_schedule initializes the handshake hash and key
-// derivation state from |session| for use with 0-RTT. It returns one on success
-// and zero on error.
-bool tls13_init_early_key_schedule(SSL_HANDSHAKE *hs,
- const SSL_SESSION *session);
+// derivation state from the resumption secret and incorporates the PSK to
+// derive the early secrets. It returns one on success and zero on error.
+bool tls13_init_early_key_schedule(SSL_HANDSHAKE *hs, Span<const uint8_t> psk);
// tls13_advance_key_schedule incorporates |in| into the key schedule with
// HKDF-Extract. It returns true on success and false on error.
@@ -1422,184 +1407,25 @@ bool tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len,
// on failure.
bool tls13_derive_session_psk(SSL_SESSION *session, Span<const uint8_t> nonce);
-// tls13_write_psk_binder calculates the PSK binder value over |transcript| and
-// |msg|, and replaces the last bytes of |msg| with the resulting value. It
-// returns true on success, and false on failure. If |out_binder_len| is
-// non-NULL, it sets |*out_binder_len| to the length of the value computed.
-bool tls13_write_psk_binder(const SSL_HANDSHAKE *hs,
- const SSLTranscript &transcript, Span<uint8_t> msg,
- size_t *out_binder_len);
+// tls13_write_psk_binder calculates the PSK binder value and replaces the last
+// bytes of |msg| with the resulting value. It returns true on success, and
+// false on failure.
+bool tls13_write_psk_binder(SSL_HANDSHAKE *hs, Span<uint8_t> msg);
// tls13_verify_psk_binder verifies that the handshake transcript, truncated up
// to the binders has a valid signature using the value of |session|'s
// resumption secret. It returns true on success, and false on failure.
-bool tls13_verify_psk_binder(const SSL_HANDSHAKE *hs,
- const SSL_SESSION *session, const SSLMessage &msg,
- CBS *binders);
-
-
-// Encrypted ClientHello.
-
-struct ECHConfig {
- static constexpr bool kAllowUniquePtr = true;
- // raw contains the serialized ECHConfig.
- Array<uint8_t> raw;
- // The following fields alias into |raw|.
- Span<const uint8_t> public_key;
- Span<const uint8_t> public_name;
- Span<const uint8_t> cipher_suites;
- uint16_t kem_id = 0;
- uint16_t maximum_name_length = 0;
- uint8_t config_id = 0;
-};
-
-class ECHServerConfig {
- public:
- static constexpr bool kAllowUniquePtr = true;
- ECHServerConfig() = default;
- ECHServerConfig(const ECHServerConfig &other) = delete;
- ECHServerConfig &operator=(ECHServerConfig &&) = delete;
-
- // Init parses |ech_config| as an ECHConfig and saves a copy of |key|.
- // It returns true on success and false on error.
- bool Init(Span<const uint8_t> ech_config, const EVP_HPKE_KEY *key,
- bool is_retry_config);
-
- // SetupContext sets up |ctx| for a new connection, given the specified
- // HPKE ciphersuite and encapsulated KEM key. It returns true on success and
- // false on error. This function may only be called on an initialized object.
- bool SetupContext(EVP_HPKE_CTX *ctx, uint16_t kdf_id, uint16_t aead_id,
- Span<const uint8_t> enc) const;
-
- const ECHConfig &ech_config() const { return ech_config_; }
- bool is_retry_config() const { return is_retry_config_; }
-
- private:
- ECHConfig ech_config_;
- ScopedEVP_HPKE_KEY key_;
- bool is_retry_config_ = false;
-};
-
-enum ssl_client_hello_type_t {
- ssl_client_hello_unencrypted,
- ssl_client_hello_inner,
- ssl_client_hello_outer,
-};
-
-// ssl_decode_client_hello_inner recovers the full ClientHelloInner from the
-// EncodedClientHelloInner |encoded_client_hello_inner| by replacing its
-// outer_extensions extension with the referenced extensions from the
-// ClientHelloOuter |client_hello_outer|. If successful, it writes the recovered
-// ClientHelloInner to |out_client_hello_inner|. It returns true on success and
-// false on failure.
-OPENSSL_EXPORT bool ssl_decode_client_hello_inner(
- SSL *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_decrypt attempts to decrypt the given |payload| into
-// |out_encoded_client_hello_inner|. The decrypted value should be an
-// EncodedClientHelloInner. It returns false if any fatal errors occur and true
-// otherwise, regardless of whether the decrypt was successful. It sets
-// |out_encoded_client_hello_inner| to true if the decryption fails, and false
-// otherwise.
-bool ssl_client_hello_decrypt(EVP_HPKE_CTX *hpke_ctx,
- Array<uint8_t> *out_encoded_client_hello_inner,
- bool *out_is_decrypt_error,
- const SSL_CLIENT_HELLO *client_hello_outer,
- uint16_t kdf_id, uint16_t aead_id,
- uint8_t config_id, Span<const uint8_t> enc,
- Span<const uint8_t> payload);
-
-#define ECH_CONFIRMATION_SIGNAL_LEN 8
-
-// 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);
-
-// ssl_ech_accept_confirmation computes the server's ECH acceptance signal,
-// writing it to |out|. The signal is computed by concatenating |transcript|
-// with |server_hello|. This function handles the fact that eight bytes of
-// |server_hello| need to be replaced with zeros before hashing. It returns true
-// on success, and false on failure.
-bool ssl_ech_accept_confirmation(const SSL_HANDSHAKE *hs, Span<uint8_t> out,
- const SSLTranscript &transcript,
- Span<const uint8_t> server_hello);
-
-// ssl_is_valid_ech_public_name returns true if |public_name| is a valid ECH
-// public name and false otherwise. It is exported for testing.
-OPENSSL_EXPORT bool ssl_is_valid_ech_public_name(
- Span<const uint8_t> public_name);
-
-// ssl_is_valid_ech_config_list returns true if |ech_config_list| is a valid
-// ECHConfigList structure and false otherwise.
-bool ssl_is_valid_ech_config_list(Span<const uint8_t> ech_config_list);
-
-// ssl_select_ech_config selects an ECHConfig and associated parameters to offer
-// on the client and updates |hs|. It returns true on success, whether an
-// ECHConfig was found or not, and false on internal error. On success, the
-// encapsulated key is written to |out_enc| and |*out_enc_len| is set to the
-// number of bytes written. If the function did not select an ECHConfig, the
-// encapsulated key is the empty string.
-bool ssl_select_ech_config(SSL_HANDSHAKE *hs, Span<uint8_t> out_enc,
- size_t *out_enc_len);
-
-// ssl_ech_extension_body_length returns the length of the body of a ClientHello
-// ECH extension that encrypts |in_len| bytes with |aead| and an 'enc' value of
-// length |enc_len|. The result does not include the four-byte extension header.
-size_t ssl_ech_extension_body_length(const EVP_HPKE_AEAD *aead, size_t enc_len,
- size_t in_len);
-
-// ssl_encrypt_client_hello constructs a new ClientHelloInner, adds it to the
-// inner transcript, and encrypts for inclusion in the ClientHelloOuter. |enc|
-// is the encapsulated key to include in the extension. It returns true on
-// success and false on error. If not offering ECH, |enc| is ignored and the
-// function will compute a GREASE ECH extension if necessary, and otherwise
-// return success while doing nothing.
-//
-// Encrypting the ClientHelloInner incorporates all extensions in the
-// ClientHelloOuter, so all other state necessary for |ssl_add_client_hello|
-// must already be computed.
-bool ssl_encrypt_client_hello(SSL_HANDSHAKE *hs, Span<const uint8_t> enc);
-
-
-// Delegated credentials.
-
-// This structure stores a delegated credential (DC) as defined by
-// draft-ietf-tls-subcerts-03.
-struct DC {
- static constexpr bool kAllowUniquePtr = true;
- ~DC();
-
- // Dup returns a copy of this DC and takes references to |raw| and |pkey|.
- UniquePtr<DC> Dup();
-
- // Parse parses the delegated credential stored in |in|. If successful it
- // returns the parsed structure, otherwise it returns |nullptr| and sets
- // |*out_alert|.
- static UniquePtr<DC> Parse(CRYPTO_BUFFER *in, uint8_t *out_alert);
+bool tls13_verify_psk_binder(SSL_HANDSHAKE *hs, SSL_SESSION *session,
+ const SSLMessage &msg, CBS *binders);
- // raw is the delegated credential encoded as specified in draft-ietf-tls-
- // subcerts-03.
- UniquePtr<CRYPTO_BUFFER> raw;
- // expected_cert_verify_algorithm is the signature scheme of the DC public
- // key.
- uint16_t expected_cert_verify_algorithm = 0;
+// Encrypted Client Hello.
- // pkey is the public key parsed from |public_key|.
- UniquePtr<EVP_PKEY> pkey;
-
- private:
- friend DC* New<DC>();
- DC();
-};
-
-// ssl_signing_with_dc returns true if the peer has indicated support for
-// delegated credentials and this host has sent a delegated credential in
-// response. If this is true then we've committed to using the DC in the
-// handshake.
-bool ssl_signing_with_dc(const SSL_HANDSHAKE *hs);
+// tls13_ech_accept_confirmation computes the server's ECH acceptance signal,
+// writing it to |out|. It returns true on success, and false on failure.
+bool tls13_ech_accept_confirmation(
+ SSL_HANDSHAKE *hs, bssl::Span<uint8_t> out,
+ bssl::Span<const uint8_t> server_hello_ech_conf);
// Handshake functions.
@@ -1614,6 +1440,7 @@ enum ssl_hs_wait_t {
ssl_hs_handoff,
ssl_hs_handback,
ssl_hs_x509_lookup,
+ ssl_hs_channel_id_lookup,
ssl_hs_private_key_operation,
ssl_hs_pending_session,
ssl_hs_pending_ticket,
@@ -1622,7 +1449,6 @@ enum ssl_hs_wait_t {
ssl_hs_read_end_of_early_data,
ssl_hs_read_change_cipher_spec,
ssl_hs_certificate_verify,
- ssl_hs_hints_ready,
};
enum ssl_grease_index_t {
@@ -1632,14 +1458,12 @@ enum ssl_grease_index_t {
ssl_grease_extension2,
ssl_grease_version,
ssl_grease_ticket_extension,
- ssl_grease_ech_config_id,
- ssl_grease_last_index = ssl_grease_ech_config_id,
+ ssl_grease_last_index = ssl_grease_ticket_extension,
};
enum tls12_server_hs_state_t {
state12_start_accept = 0,
state12_read_client_hello,
- state12_read_client_hello_after_ech,
state12_select_certificate,
state12_tls13,
state12_select_parameters,
@@ -1691,30 +1515,46 @@ enum handback_t {
handback_max_value = handback_tls13,
};
-// SSL_HANDSHAKE_HINTS contains handshake hints for a connection. See
-// |SSL_request_handshake_hints| and related functions.
-struct SSL_HANDSHAKE_HINTS {
+
+// Delegated credentials.
+
+// This structure stores a delegated credential (DC) as defined by
+// draft-ietf-tls-subcerts-03.
+struct DC {
static constexpr bool kAllowUniquePtr = true;
+ ~DC();
- Array<uint8_t> server_random;
+ // Dup returns a copy of this DC and takes references to |raw| and |pkey|.
+ UniquePtr<DC> Dup();
- uint16_t key_share_group_id = 0;
- Array<uint8_t> key_share_public_key;
- Array<uint8_t> key_share_secret;
+ // Parse parses the delegated credential stored in |in|. If successful it
+ // returns the parsed structure, otherwise it returns |nullptr| and sets
+ // |*out_alert|.
+ static UniquePtr<DC> Parse(CRYPTO_BUFFER *in, uint8_t *out_alert);
- uint16_t signature_algorithm = 0;
- Array<uint8_t> signature_input;
- Array<uint8_t> signature_spki;
- Array<uint8_t> signature;
+ // raw is the delegated credential encoded as specified in draft-ietf-tls-
+ // subcerts-03.
+ UniquePtr<CRYPTO_BUFFER> raw;
- Array<uint8_t> decrypted_psk;
- bool ignore_psk = false;
+ // expected_cert_verify_algorithm is the signature scheme of the DC public
+ // key.
+ uint16_t expected_cert_verify_algorithm = 0;
+
+ // pkey is the public key parsed from |public_key|.
+ UniquePtr<EVP_PKEY> pkey;
- uint16_t cert_compression_alg_id = 0;
- Array<uint8_t> cert_compression_input;
- Array<uint8_t> cert_compression_output;
+ private:
+ friend DC* New<DC>();
+ DC();
};
+// ssl_signing_with_dc returns true if the peer has indicated support for
+// delegated credentials and this host has sent a delegated credential in
+// response. If this is true then we've committed to using the DC in the
+// handshake.
+bool ssl_signing_with_dc(const SSL_HANDSHAKE *hs);
+
+
struct SSL_HANDSHAKE {
explicit SSL_HANDSHAKE(SSL *ssl);
~SSL_HANDSHAKE();
@@ -1759,21 +1599,7 @@ struct SSL_HANDSHAKE {
public:
void ResizeSecrets(size_t hash_len);
- // GetClientHello, on the server, returns either the normal ClientHello
- // message or the ClientHelloInner if it has been serialized to
- // |ech_client_hello_buf|. This function should only be called when the
- // current message is a ClientHello. It returns true on success and false on
- // error.
- //
- // Note that fields of the returned |out_msg| and |out_client_hello| point
- // into a handshake-owned buffer, so their lifetimes should not exceed this
- // SSL_HANDSHAKE.
- bool GetClientHello(SSLMessage *out_msg, SSL_CLIENT_HELLO *out_client_hello);
-
Span<uint8_t> secret() { return MakeSpan(secret_, hash_len_); }
- Span<const uint8_t> secret() const {
- return MakeConstSpan(secret_, hash_len_);
- }
Span<uint8_t> early_traffic_secret() {
return MakeSpan(early_traffic_secret_, hash_len_);
}
@@ -1795,7 +1621,7 @@ struct SSL_HANDSHAKE {
union {
// sent is a bitset where the bits correspond to elements of kExtensions
- // in extensions.cc. Each bit is set if that extension was sent in a
+ // in t1_lib.c. Each bit is set if that extension was sent in a
// ClientHello. It's not used by servers.
uint32_t sent = 0;
// received is a bitset, like |sent|, but is used by servers to record
@@ -1803,9 +1629,9 @@ struct SSL_HANDSHAKE {
uint32_t received;
} extensions;
- // inner_extensions_sent, on clients that offer ECH, is |extensions.sent| for
- // the ClientHelloInner.
- uint32_t inner_extensions_sent = 0;
+ // retry_group is the group ID selected by the server in HelloRetryRequest in
+ // TLS 1.3.
+ uint16_t retry_group = 0;
// error, if |wait| is |ssl_hs_error|, is the error the handshake failed on.
UniquePtr<ERR_SAVE_STATE> error;
@@ -1818,30 +1644,15 @@ struct SSL_HANDSHAKE {
// transcript is the current handshake transcript.
SSLTranscript transcript;
- // inner_transcript, on the client, is the handshake transcript for the
- // ClientHelloInner handshake. It is moved to |transcript| if the server
- // accepts ECH.
- SSLTranscript inner_transcript;
-
- // inner_client_random is the ClientHello random value used with
- // ClientHelloInner.
- uint8_t inner_client_random[SSL3_RANDOM_SIZE] = {0};
-
// cookie is the value of the cookie received from the server, if any.
Array<uint8_t> cookie;
- // ech_client_bytes contains the ECH extension to send in the ClientHello.
- Array<uint8_t> ech_client_bytes;
+ // ech_grease contains the bytes of the GREASE ECH extension that was sent in
+ // the first ClientHello.
+ Array<uint8_t> ech_grease;
- // ech_retry_configs, on the client, contains the retry configs from the
- // server as a serialized ECHConfigList.
- Array<uint8_t> ech_retry_configs;
-
- // ech_client_hello_buf, on the server, contains the bytes of the
- // reconstructed ClientHelloInner message.
- Array<uint8_t> ech_client_hello_buf;
-
- // key_share_bytes is the key_share extension that the client should send.
+ // key_share_bytes is the value of the previously sent KeyShare extension by
+ // the client in TLS 1.3.
Array<uint8_t> key_share_bytes;
// ecdh_public_key, for servers, is the key share to be sent to the client in
@@ -1865,21 +1676,17 @@ struct SSL_HANDSHAKE {
// peer_key is the peer's ECDH key for a TLS 1.2 client.
Array<uint8_t> peer_key;
- // extension_permutation is the permutation to apply to ClientHello
- // extensions. It maps indices into the |kExtensions| table into other
- // indices.
- Array<uint8_t> extension_permutation;
+ // negotiated_token_binding_version is used by a server to store the
+ // on-the-wire encoding of the Token Binding protocol version to advertise in
+ // the ServerHello/EncryptedExtensions if the Token Binding extension is to be
+ // sent.
+ uint16_t negotiated_token_binding_version;
// cert_compression_alg_id, for a server, contains the negotiated certificate
// compression algorithm for this client. It is only valid if
// |cert_compression_negotiated| is true.
uint16_t cert_compression_alg_id;
- // ech_hpke_ctx is the HPKE context used in ECH. On the server, it is
- // initialized if |ech_status| is |ssl_ech_accepted|. On the client, it is
- // initialized if |selected_ech_config| is not nullptr.
- ScopedEVP_HPKE_CTX ech_hpke_ctx;
-
// server_params, in a TLS 1.2 server, stores the ServerKeyExchange
// parameters. It has client and server randoms prepended for signing
// convenience.
@@ -1916,29 +1723,12 @@ struct SSL_HANDSHAKE {
// the client if |in_early_data| is true.
UniquePtr<SSL_SESSION> early_session;
- // ssl_ech_keys, for servers, is the set of ECH keys to use with this
- // handshake. This is copied from |SSL_CTX| to ensure consistent behavior as
- // |SSL_CTX| rotates keys.
- UniquePtr<SSL_ECH_KEYS> ech_keys;
-
- // selected_ech_config, for clients, is the ECHConfig the client uses to offer
- // ECH, or nullptr if ECH is not being offered. If non-NULL, |ech_hpke_ctx|
- // will be initialized.
- UniquePtr<ECHConfig> selected_ech_config;
-
// new_cipher is the cipher being negotiated in this handshake.
const SSL_CIPHER *new_cipher = nullptr;
// key_block is the record-layer key block for TLS 1.2 and earlier.
Array<uint8_t> key_block;
- // hints contains the handshake hints for this connection. If
- // |hints_requested| is true, this field is non-null and contains the pending
- // hints to filled as the predicted handshake progresses. Otherwise, this
- // field, if non-null, contains hints configured by the caller and will
- // influence the handshake on match.
- UniquePtr<SSL_HANDSHAKE_HINTS> hints;
-
// ech_present, on the server, indicates whether the ClientHello contained an
// encrypted_client_hello extension.
bool ech_present : 1;
@@ -1947,13 +1737,13 @@ struct SSL_HANDSHAKE {
// contained an ech_is_inner extension.
bool ech_is_inner_present : 1;
- // ech_authenticated_reject, on the client, indicates whether an ECH rejection
- // handshake has been authenticated.
- bool ech_authenticated_reject : 1;
-
// scts_requested is true if the SCT extension is in the ClientHello.
bool scts_requested : 1;
+ // needs_psk_binder is true if the ClientHello has a placeholder PSK binder to
+ // be filled in.
+ bool needs_psk_binder : 1;
+
// handshake_finalized is true once the handshake has completed, at which
// point accessors should use the established state.
bool handshake_finalized : 1;
@@ -2015,17 +1805,15 @@ struct SSL_HANDSHAKE {
// in progress.
bool pending_private_key_op : 1;
+ // grease_seeded is true if |grease_seed| has been initialized.
+ bool grease_seeded : 1;
+
// handback indicates that a server should pause the handshake after
// finishing operations that require private key material, in such a way that
// |SSL_get_error| returns |SSL_ERROR_HANDBACK|. It is set by
// |SSL_apply_handoff|.
bool handback : 1;
- // hints_requested indicates the caller has requested handshake hints. Only
- // the first round-trip of the handshake will complete, after which the
- // |hints| structure can be serialized.
- bool hints_requested : 1;
-
// cert_compression_negotiated is true iff |cert_compression_alg_id| is valid.
bool cert_compression_negotiated : 1;
@@ -2033,14 +1821,6 @@ struct SSL_HANDSHAKE {
// which implemented TLS 1.3 incorrectly.
bool apply_jdk11_workaround : 1;
- // can_release_private_key is true if the private key will no longer be used
- // in this handshake.
- bool can_release_private_key : 1;
-
- // channel_id_negotiated is true if Channel ID should be used in this
- // handshake.
- bool channel_id_negotiated : 1;
-
// client_version is the value sent or received in the ClientHello version.
uint16_t client_version = 0;
@@ -2052,14 +1832,12 @@ struct SSL_HANDSHAKE {
// record layer.
uint16_t early_data_written = 0;
- // ech_config_id is the ECH config sent by the client.
- uint8_t ech_config_id = 0;
-
// session_id is the session ID in the ClientHello.
uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH] = {0};
uint8_t session_id_len = 0;
- // grease_seed is the entropy for GREASE values.
+ // grease_seed is the entropy for GREASE values. It is valid if
+ // |grease_seeded| is true.
uint8_t grease_seed[ssl_grease_last_index + 1] = {0};
};
@@ -2119,24 +1897,14 @@ bool tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg);
bssl::UniquePtr<SSL_SESSION> tls13_create_session_with_ticket(SSL *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.
-bool ssl_setup_extension_permutation(SSL_HANDSHAKE *hs);
-
-// ssl_setup_key_shares computes client key shares and saves them in |hs|. It
-// returns true on success and false on failure. If |override_group_id| is zero,
-// it offers the default groups, including GREASE. If it is non-zero, it offers
-// a single key share of the specified group.
-bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id);
-
bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs,
Array<uint8_t> *out_secret,
uint8_t *out_alert, CBS *contents);
bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found,
- Span<const uint8_t> *out_peer_key,
- uint8_t *out_alert,
- const SSL_CLIENT_HELLO *client_hello);
-bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out);
+ Array<uint8_t> *out_secret,
+ uint8_t *out_alert, CBS *contents);
+bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out,
+ bool dry_run);
bool ssl_ext_pre_shared_key_parse_serverhello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
@@ -2151,17 +1919,7 @@ bool ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out);
// returns whether it's valid.
bool ssl_is_sct_list_valid(const CBS *contents);
-// ssl_write_client_hello_without_extensions writes a ClientHello to |out|,
-// up to the extensions field. |type| determines the type of ClientHello to
-// write. If |omit_session_id| is true, the session ID is empty.
-bool ssl_write_client_hello_without_extensions(const SSL_HANDSHAKE *hs,
- CBB *cbb,
- ssl_client_hello_type_t type,
- bool empty_session_id);
-
-// ssl_add_client_hello constructs a ClientHello and adds it to the outgoing
-// flight. It returns true on success and false on error.
-bool ssl_add_client_hello(SSL_HANDSHAKE *hs);
+bool ssl_write_client_hello(SSL_HANDSHAKE *hs);
enum ssl_cert_verify_context_t {
ssl_cert_verify_server,
@@ -2177,9 +1935,6 @@ bool tls13_get_cert_verify_signature_input(
SSL_HANDSHAKE *hs, Array<uint8_t> *out,
enum ssl_cert_verify_context_t cert_verify_context);
-// ssl_is_valid_alpn_list returns whether |in| is a valid ALPN protocol list.
-bool ssl_is_valid_alpn_list(Span<const uint8_t> in);
-
// ssl_is_alpn_protocol_allowed returns whether |protocol| is a valid server
// selection for |hs->ssl|'s client preferences.
bool ssl_is_alpn_protocol_allowed(const SSL_HANDSHAKE *hs,
@@ -2191,13 +1946,6 @@ bool ssl_is_alpn_protocol_allowed(const SSL_HANDSHAKE *hs,
bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert,
const SSL_CLIENT_HELLO *client_hello);
-// ssl_get_local_application_settings looks up the configured ALPS value for
-// |protocol|. If found, it sets |*out_settings| to the value and returns true.
-// Otherwise, it returns false.
-bool ssl_get_local_application_settings(const SSL_HANDSHAKE *hs,
- Span<const uint8_t> *out_settings,
- Span<const uint8_t> protocol);
-
// ssl_negotiate_alps negotiates the ALPS extension, if applicable. It returns
// true on successful negotiation or if nothing was negotiated. It returns false
// and sets |*out_alert| to an alert on error.
@@ -2234,10 +1982,6 @@ bool ssl_output_cert_chain(SSL_HANDSHAKE *hs);
// handshake. Note, in TLS 1.2 resumptions, this session is immutable.
const SSL_SESSION *ssl_handshake_session(const SSL_HANDSHAKE *hs);
-// ssl_done_writing_client_hello is called after the last ClientHello is written
-// by |hs|. It releases some memory that is no longer needed.
-void ssl_done_writing_client_hello(SSL_HANDSHAKE *hs);
-
// SSLKEYLOGFILE functions.
@@ -2249,11 +1993,8 @@ bool ssl_log_secret(const SSL *ssl, const char *label,
// ClientHello functions.
-// ssl_client_hello_init parses |body| as a ClientHello message, excluding the
-// message header, and writes the result to |*out|. It returns true on success
-// and false on error. This function is exported for testing.
-OPENSSL_EXPORT bool ssl_client_hello_init(const SSL *ssl, SSL_CLIENT_HELLO *out,
- Span<const uint8_t> body);
+bool ssl_client_hello_init(const SSL *ssl, SSL_CLIENT_HELLO *out,
+ const SSLMessage &msg);
bool ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello,
CBS *out, uint16_t extension_type);
@@ -2268,8 +2009,7 @@ bool ssl_client_cipher_list_contains_cipher(
// connection, the values for each index will be deterministic. This allows the
// same ClientHello be sent twice for a HelloRetryRequest or the same group be
// advertised in both supported_groups and key_shares.
-uint16_t ssl_get_grease_value(const SSL_HANDSHAKE *hs,
- enum ssl_grease_index_t index);
+uint16_t ssl_get_grease_value(SSL_HANDSHAKE *hs, enum ssl_grease_index_t index);
// Signature algorithms.
@@ -2429,11 +2169,10 @@ struct SSL_PROTOCOL_METHOD {
// 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)(SSL *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,
- bssl::Array<uint8_t> *out_msg);
+ bool (*finish_message)(SSL *ssl, CBB *cbb, bssl::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, bssl::Array<uint8_t> msg);
@@ -2582,16 +2321,6 @@ enum ssl_shutdown_t {
ssl_shutdown_error = 2,
};
-enum ssl_ech_status_t {
- // ssl_ech_none indicates ECH was not offered, or we have not gotten far
- // enough in the handshake to determine the status.
- ssl_ech_none,
- // ssl_ech_accepted indicates the server accepted ECH.
- ssl_ech_accepted,
- // ssl_ech_rejected indicates the server was offered ECH but rejected it.
- ssl_ech_rejected,
-};
-
struct SSL3_STATE {
static constexpr bool kAllowUniquePtr = true;
@@ -2654,8 +2383,9 @@ struct SSL3_STATE {
// key_update_count is the number of consecutive KeyUpdates received.
uint8_t key_update_count = 0;
- // ech_status indicates whether ECH was accepted by the server.
- ssl_ech_status_t ech_status = ssl_ech_none;
+ // 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.
@@ -2690,8 +2420,9 @@ struct SSL3_STATE {
bool send_connection_binding : 1;
- // channel_id_valid is true if, on the server, the client has negotiated a
- // Channel ID and the |channel_id| field is filled in.
+ // In a client, this means that the server supported Channel ID and that a
+ // Channel ID was sent. In a server it means that we echoed support for
+ // Channel IDs and that |channel_id| will be valid after the handshake.
bool channel_id_valid : 1;
// key_update_pending is true if we have a KeyUpdate acknowledgment
@@ -2704,6 +2435,9 @@ struct SSL3_STATE {
// early_data_accepted is true if early data was accepted by the server.
bool early_data_accepted : 1;
+ // token_binding_negotiated is set if Token Binding was negotiated.
+ bool token_binding_negotiated : 1;
+
// alert_dispatch is true there is an alert in |send_alert| to be sent.
bool alert_dispatch : 1;
@@ -2986,8 +2720,7 @@ struct SSL_CONFIG {
Array<uint16_t> supported_group_list; // our list
- // channel_id_private is the client's Channel ID private key, or null if
- // Channel ID should not be offered on this connection.
+ // The client's Channel ID private key.
UniquePtr<EVP_PKEY> channel_id_private;
// For a client, this contains the list of supported protocols in wire
@@ -2998,6 +2731,9 @@ struct SSL_CONFIG {
// along with their corresponding ALPS values.
GrowableArray<ALPSConfig> alps_configs;
+ // Contains a list of supported Token Binding key parameters.
+ Array<uint8_t> token_binding_params;
+
// Contains the QUIC transport params that this endpoint will send.
Array<uint8_t> quic_transport_params;
@@ -3012,10 +2748,6 @@ struct SSL_CONFIG {
// DTLS-SRTP.
UniquePtr<STACK_OF(SRTP_PROTECTION_PROFILE)> srtp_profiles;
- // client_ech_config_list, if not empty, is a serialized ECHConfigList
- // structure for the client to use when negotiating ECH.
- Array<uint8_t> client_ech_config_list;
-
// verify_mode is a bitmask of |SSL_VERIFY_*| values.
uint8_t verify_mode = SSL_VERIFY_NONE;
@@ -3030,8 +2762,9 @@ struct SSL_CONFIG {
// whether OCSP stapling will be requested.
bool ocsp_stapling_enabled : 1;
- // channel_id_enabled is copied from the |SSL_CTX|. For a server, it means
- // that we'll accept Channel IDs from clients. It is ignored on the client.
+ // channel_id_enabled is copied from the |SSL_CTX|. For a server, means that
+ // we'll accept Channel IDs from clients. For a client, means that we'll
+ // advertise support.
bool channel_id_enabled : 1;
// If enforce_rsa_key_usage is true, the handshake will fail if the
@@ -3061,9 +2794,6 @@ struct SSL_CONFIG {
// QUIC drafts up to and including 32 used a different TLS extension
// codepoint to convey QUIC's transport parameters.
bool quic_use_legacy_codepoint : 1;
-
- // permute_extensions is whether to permute extensions when sending messages.
- bool permute_extensions : 1;
};
// From RFC 8446, used in determining PSK modes.
@@ -3084,7 +2814,7 @@ bool ssl_is_key_type_supported(int key_type);
bool ssl_compare_public_and_private_key(const EVP_PKEY *pubkey,
const EVP_PKEY *privkey);
bool ssl_cert_check_private_key(const CERT *cert, const EVP_PKEY *privkey);
-bool ssl_get_new_session(SSL_HANDSHAKE *hs);
+int ssl_get_new_session(SSL_HANDSHAKE *hs, int is_server);
int ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out, const SSL_SESSION *session);
int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx);
@@ -3165,7 +2895,7 @@ void ssl_session_rebase_time(SSL *ssl, SSL_SESSION *session);
void ssl_session_renew_timeout(SSL *ssl, SSL_SESSION *session,
uint32_t timeout);
-void ssl_update_cache(SSL *ssl);
+void ssl_update_cache(SSL_HANDSHAKE *hs, int mode);
void ssl_send_alert(SSL *ssl, int level, int desc);
int ssl_send_alert_impl(SSL *ssl, int level, int desc);
@@ -3187,14 +2917,14 @@ int tls_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf,
bool tls_new(SSL *ssl);
void tls_free(SSL *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_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type);
+bool tls_finish_message(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_flight(SSL *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_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type);
+bool dtls1_finish_message(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);
int dtls1_flush_flight(SSL *ssl);
@@ -3279,27 +3009,11 @@ bool tls1_set_curves(Array<uint16_t> *out_group_ids, Span<const int> curves);
// false.
bool tls1_set_curves_list(Array<uint16_t> *out_group_ids, const char *curves);
-// ssl_add_clienthello_tlsext writes ClientHello extensions to |out| for |type|.
-// It returns true on success and false on failure. The |header_len| argument is
-// the length of the ClientHello written so far and is used to compute the
-// padding length. (It does not include the record header or handshake headers.)
-//
-// If |type| is |ssl_client_hello_inner|, this function also writes the
-// compressed extensions to |out_encoded|. Otherwise, |out_encoded| should be
-// nullptr.
-//
-// On success, the function sets |*out_needs_psk_binder| to whether the last
-// ClientHello extension was the pre_shared_key extension and needs a PSK binder
-// filled in. The caller should then update |out| and, if applicable,
-// |out_encoded| with the binder after completing the whole message.
-//
-// If |omit_ech_len| is non-zero, the ECH extension is omitted, but padding is
-// computed as if there were an extension of length |omit_ech_len|. This is used
-// to compute ClientHelloOuterAAD.
-bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, CBB *out_encoded,
- bool *out_needs_psk_binder,
- ssl_client_hello_type_t type, size_t header_len,
- size_t omit_ech_len);
+// ssl_add_clienthello_tlsext writes ClientHello extensions to |out|. It returns
+// true on success and false on failure. The |header_len| argument is the length
+// of the ClientHello written so far and is used to compute the padding length.
+// (It does not include the record header.)
+bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, size_t header_len);
bool ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out);
bool ssl_parse_clienthello_tlsext(SSL_HANDSHAKE *hs,
@@ -3342,6 +3056,12 @@ bool tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len);
// data.
bool tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs);
+// ssl_do_channel_id_callback checks runs |hs->ssl->ctx->channel_id_cb| if
+// necessary. It returns true on success and false on fatal error. Note that, on
+// success, |hs->ssl->channel_id_private| may be unset, in which case the
+// operation should be retried later.
+bool ssl_do_channel_id_callback(SSL_HANDSHAKE *hs);
+
// ssl_can_write returns whether |ssl| is allowed to write.
bool ssl_can_write(const SSL *ssl);
@@ -3465,6 +3185,9 @@ struct ssl_ctx_st {
int (*client_cert_cb)(SSL *ssl, X509 **out_x509,
EVP_PKEY **out_pkey) = nullptr;
+ // get channel id callback
+ void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey) = nullptr;
+
CRYPTO_EX_DATA ex_data;
// Default values used when no per-SSL value is defined follow
@@ -3592,15 +3315,9 @@ struct ssl_ctx_st {
// Supported group values inherited by SSL structure
bssl::Array<uint16_t> supported_group_list;
- // channel_id_private is the client's Channel ID private key, or null if
- // Channel ID should not be offered on this connection.
+ // The client's Channel ID private key.
bssl::UniquePtr<EVP_PKEY> channel_id_private;
- // ech_keys contains the server's list of ECHConfig values and associated
- // private keys. This list may be swapped out at any time, so all access must
- // be synchronized through |lock|.
- bssl::UniquePtr<SSL_ECH_KEYS> ech_keys;
-
// keylog_callback, if not NULL, is the key logging callback. See
// |SSL_CTX_set_keylog_callback|.
void (*keylog_callback)(const SSL *ssl, const char *line) = nullptr;
@@ -3648,12 +3365,9 @@ struct ssl_ctx_st {
// advertise support.
bool channel_id_enabled : 1;
- // grease_enabled is whether GREASE (RFC 8701) is enabled.
+ // grease_enabled is whether draft-davidben-tls-grease-01 is enabled.
bool grease_enabled : 1;
- // permute_extensions is whether to permute extensions when sending messages.
- bool permute_extensions : 1;
-
// allow_unknown_alpn_protos is whether the client allows unsolicited ALPN
// protocols from the peer.
bool allow_unknown_alpn_protos : 1;
@@ -3917,17 +3631,5 @@ struct ssl_session_st {
friend void SSL_SESSION_free(SSL_SESSION *);
};
-struct ssl_ech_keys_st {
- ssl_ech_keys_st() = default;
- ssl_ech_keys_st(const ssl_ech_keys_st &) = delete;
- ssl_ech_keys_st &operator=(const ssl_ech_keys_st &) = delete;
-
- bssl::GrowableArray<bssl::UniquePtr<bssl::ECHServerConfig>> configs;
- CRYPTO_refcount_t references = 1;
-
- private:
- ~ssl_ech_keys_st() = default;
- friend void SSL_ECH_KEYS_free(SSL_ECH_KEYS *);
-};
#endif // OPENSSL_HEADER_SSL_INTERNAL_H