diff options
author | Pete Bentley <prb@google.com> | 2021-09-23 10:49:18 +0100 |
---|---|---|
committer | Pete Bentley <prb@google.com> | 2021-09-27 19:05:23 +0100 |
commit | 8bb65ff676b006f67cccd75a8f4cd6f8a296409e (patch) | |
tree | 741bef31d3d7f6d72020097ad72fc7b7a1e0ec9c /src/ssl/internal.h | |
parent | f54ba3566f9139b088c0328ceccc69b7d5dab09d (diff) | |
download | boringssl-8bb65ff676b006f67cccd75a8f4cd6f8a296409e.tar.gz |
external/boringssl: Sync to 66e61c577d39e757bf491468f651461fa79fd5e1.
This includes the following changes:
https://boringssl.googlesource.com/boringssl/+log/c1571feb5faf5cce844354c63d0f3e842464bea3..66e61c577d39e757bf491468f651461fa79fd5e1
* Allow PKCS7_sign to work for signing kernel modules.
* Speed up constant-time base64 decoding.
* Unwind remnants of ASN1_TFLG_NDEF.
* acvptool: add CS3 support.
* Ignore SIGPIPE in the bssl tool.
* Add FIPS counters for AES-GCM in EVP_AEAD.
* Refresh fuzzer corpus for ECH draft-13.
* Fix the TLS fuzzers for ECH draft-13.
* Clarify that TLS sessions are not application sessions.
* Fix BN_prime_checks_for_validation to align with false-positive rate.
* Add maskHash to RSA_PSS_PARAMS for compat
* Remove ASN1_OP_I2D_* callbacks.
* Don't read it->funcs without checking it->itype.
* Reject missing required fields in i2d functions.
Update-Note: Structures with missing mandatory fields can no longer be
encoded. Note that, apart from the cases already handled by preceding
CLs, tasn_new.c will fill in non-NULL empty objects everywhere. The main
downstream impact I've seen of this particular change is in combination
with other bugs. Consider a caller that does:
* Reject -1 types in ASN1_TYPE and MSTRINGs when encoding.
Update-Note: A default-constructed object with a required ANY or
string-like CHOICE field cannot be encoded until the field is specified.
Note this affects i2d_X509: notBefore and notAfter are string-like
CHOICEs in OpenSSL.
* Correctly handle invalid ASN1_OBJECTs when encoding.
Update-Note: A default-constructed object with a required ASN1_OBJECT
field can no longer be encoded without initializing the ASN1_OBJECT.
Note this affects X509: the signature algorithm is an ASN1_OBJECT. Tests
that try to serialize an X509_new() must fill in all required fields.
(Production code is unlikely to be affected because the output was
unparsable anyway, while tests sometimes wouldn't notice.)
* Check for invalid CHOICE selectors in i2d functions.
Update-Note: An invalid CHOICE object (e.g. GENERAL_NAME) will now fail
when encoded, rather than be silently omitted. In particular, CHOICE
objects are default-initialized by tasn_new.c in an empty -1 state.
Structures containing a required CHOICE field can no longer be encoded
without filling in the CHOICE.
* Fix x509_name_ex_i2d error-handling.
* Correctly propagate errors in i2d functions.
Update-Note: Some error cases which were silently misinterpreted as
missing OPTIONAL elements will now cause encoding to fail.
* acvptool: add hmacDRBG support
* Check for __TRUSTY__ instead of TRUSTY.
* Update comment for ECH draft-13.
* Silence a GCC false positive warning.
* Switch to the new, simpler WHATWG URL formulation.
* Revert "Guard use of sdallocx with BORINGSSL_SDALLOCX"
* Fix calculation of draft-13 ECH confirmation signal.
* Update to draft-ietf-tls-esni-13.
* Reword SSL_get0_ech_name_override documentation.
* Remove SSL_set_verify_result.
* Make most of crypto/x509 opaque.
Update-Note: Patch cl/390055173 into the roll that includes this. This
unexports most of the X.509 structs, aligning with OpenSSL. Use the
accessor APIs instead.
* Remove V_ASN1_APP_CHOOSE.
Update-Note: V_ASN1_APP_CHOOSE is removed. I only found one use, which
has been fixed.
* Rewrite ASN1_PRINTABLE_type and add tests.
* Include SHA512-256 in EVP_get_digestbyname and EVP_MD_do_all.
* NUL is not printable.
Update-Note: ASN1_mbstring_ncopy will no longer allow PrintableString
for strings containing NUL.
* Make RSA_check_key more than 2x as fast.
* Benchmark RSA private key parsing.
* Work around yet another MSVC 2015 SFINAE bug.
* Avoid re-hashing the transcript multiple times.
* Make ssl_parse_extensions a little easier to use.
* Deduplicate our three ServerHello parsers.
* Merge in OpenSSL's X.509 corpus.
* Run X509_print in the certificate fuzzer.
* Fix some error-handling in i2v functions.
* Fix typo.
* OPENSSL_strndup should not return NULL given {NULL, 0}.
* Rewrite name constraints matching with CBS.
* Add some tests for name constraints.
* Fix i2v_GENERAL_NAME to not assume NUL terminated strings
* Do not rely on ASN1_STRING being NUL-terminated.
* Add a CBB_add_zeros helper.
* Linkify RFCs in documentation.
* Refer to RFCs consistently.
* runner: Test session IDs over 32 bytes.
* Process the TLS 1.3 cipher suite in one place.
* Guard use of sdallocx with BORINGSSL_SDALLOCX
* Bump minimum GCC version and note impending VS2015 deprecation.
* Add Span::first() and Span::last().
* Simplify built-in BIOs slightly.
* Fix some error returns from SSL_read and SSL_write.
* Fix negative ENUMERATED values in multi-strings.
* Add a test for ASN1_mbstring_copy and clean up.
* Remove ASN1_TFLG_SET_ORDER.
* Fix ASN1_STRING_print_ex with negative integers.
* Check i2d_ASN1_TYPE's return value in ASN1_STRING_print_ex.
* Document ASN.1 printing functions.
* Move some ASN1 printing functions to crypto/asn1.
* Move a_strex.c back to asn1, split X509_NAME bits out.
* Unwind io_ch abstraction in print functions.
* Implement ASN1_STRING_print_ex_fp, etc., with file BIOs.
* Remove OPENSSL_NO_FP_API ifdefs.
* Move X509_ALGOR to x509.h.
* Unexport BIT_STRING_BITNAME.
* Unexport ub_* constants.
Update-Note: Removed some unnamespaced constants.
* Always use an ASN1_STRING_TABLE global mask of UTF8String.
Update-Note: The global mask for ASN1_STRING_set_by_NID is now always
UTF-8. Callers that want another type should reconsider and, if UTF-8 is
still unsuitable, just pass the actual desired type into
ASN1_mbstring_copy, X509_NAME_ENTRY_set_data, etc
* Document ASN1_mbstring_copy.
* Update ghashv8-armx.pl from upstream.
* Align with upstream on 'close STDOUT' lines.
* Avoid double-expanding variables in CMake.
* Reject years outside 0000-9999 in ASN1_GENERALIZEDTIME_adj.
* Add some tests for time_t to ASN1_TIME conversions.
* Remove ASN1_STRING_FLAG_MSTRING.
Update-Note: ASN1_STRING_FLAG_MSTRING is no longer defined and
X509_time_adj_ex now behaves more predictably. Callers that actually
wanted to lock to a specific type should call ASN1_UTCTIME_adj or
ASN1_GENERALIZEDTIME_adj instead.
* Document another batch of functions.
* Clarify BIO_new_mum_buf's lifetime rules.
* generate_ech.cc: include needed headers
* Don't overread in poly_Rq_mul
* acvp: recognise another style of JSON.
* Revert "Revert "Revert "Disable check that X.509 extensions implies v3."""
Test: atest CtsLibcoreTestCases CtsLibcoreOkHttpTestCases
Change-Id: I4f2228ef815ded0599322186ab7bad49ab1bb5af
Diffstat (limited to 'src/ssl/internal.h')
-rw-r--r-- | src/ssl/internal.h | 106 |
1 files changed, 63 insertions, 43 deletions
diff --git a/src/ssl/internal.h b/src/ssl/internal.h index 3b7326ae..ab23d29b 100644 --- a/src/ssl/internal.h +++ b/src/ssl/internal.h @@ -146,6 +146,7 @@ #include <stdlib.h> +#include <initializer_list> #include <limits> #include <new> #include <type_traits> @@ -693,7 +694,8 @@ class SSLTranscript { // InitHash initializes the handshake hash based on the PRF and contents of // the handshake transcript. Subsequent calls to |Update| will update the // rolling hash. It returns one on success and zero on failure. It is an error - // to call this function after the handshake buffer is released. + // to call this function after the handshake buffer is released. This may be + // called multiple times to change the hash function. bool InitHash(uint16_t version, const SSL_CIPHER *cipher); // UpdateForHelloRetryRequest resets the rolling hash with the @@ -1449,7 +1451,7 @@ struct ECHConfig { 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 maximum_name_length = 0; uint8_t config_id = 0; }; @@ -1486,6 +1488,10 @@ enum ssl_client_hello_type_t { ssl_client_hello_outer, }; +// ECH_CLIENT_* are types for the ClientHello encrypted_client_hello extension. +#define ECH_CLIENT_OUTER 0 +#define ECH_CLIENT_INNER 1 + // 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 @@ -1497,18 +1503,13 @@ OPENSSL_EXPORT bool ssl_decode_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, +// ssl_client_hello_decrypt attempts to decrypt the |payload| and writes the +// result to |*out|. |payload| must point into |client_hello_outer|. It returns +// true on success and false on error. On error, it sets |*out_is_decrypt_error| +// to whether the failure was due to a bad ciphertext. +bool ssl_client_hello_decrypt(EVP_HPKE_CTX *hpke_ctx, Array<uint8_t> *out, 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 @@ -1518,13 +1519,14 @@ bool ssl_client_hello_decrypt(EVP_HPKE_CTX *hpke_ctx, 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. +// writing it to |out|. The transcript portion is the concatenation of +// |transcript| with |msg|. The |ECH_CONFIRMATION_SIGNAL_LEN| bytes from +// |offset| in |msg| are replaced with zeros before hashing. This function +// 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); + Span<const uint8_t> client_random, + const SSLTranscript &transcript, bool is_hrr, + Span<const uint8_t> msg, size_t offset); // 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. @@ -1830,8 +1832,9 @@ struct SSL_HANDSHAKE { // 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_client_outer contains the outer ECH extension to send in the + // ClientHello, excluding the header and type byte. + Array<uint8_t> ech_client_outer; // ech_retry_configs, on the client, contains the retry configs from the // server as a serialized ECHConfigList. @@ -1939,13 +1942,9 @@ struct SSL_HANDSHAKE { // 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; - - // ech_is_inner_present, on the server, indicates whether the ClientHello - // contained an ech_is_inner extension. - bool ech_is_inner_present : 1; + // ech_is_inner, on the server, indicates whether the ClientHello contained an + // inner ECH extension. + bool ech_is_inner : 1; // ech_authenticated_reject, on the client, indicates whether an ECH rejection // handshake has been authenticated. @@ -2163,6 +2162,22 @@ bool ssl_write_client_hello_without_extensions(const SSL_HANDSHAKE *hs, // flight. It returns true on success and false on error. bool ssl_add_client_hello(SSL_HANDSHAKE *hs); +struct ParsedServerHello { + CBS raw; + uint16_t legacy_version = 0; + CBS random; + CBS session_id; + uint16_t cipher_suite = 0; + uint8_t compression_method = 0; + CBS extensions; +}; + +// ssl_parse_server_hello parses |msg| as a ServerHello. On success, it writes +// the result to |*out| and returns true. Otherwise, it returns false and sets +// |*out_alert| to an alert to send to the peer. +bool ssl_parse_server_hello(ParsedServerHello *out, uint8_t *out_alert, + const SSLMessage &msg); + enum ssl_cert_verify_context_t { ssl_cert_verify_server, ssl_cert_verify_client, @@ -2204,19 +2219,25 @@ bool ssl_get_local_application_settings(const SSL_HANDSHAKE *hs, bool ssl_negotiate_alps(SSL_HANDSHAKE *hs, uint8_t *out_alert, const SSL_CLIENT_HELLO *client_hello); -struct SSL_EXTENSION_TYPE { +struct SSLExtension { + SSLExtension(uint16_t type_arg, bool allowed_arg = true) + : type(type_arg), allowed(allowed_arg), present(false) { + CBS_init(&data, nullptr, 0); + } + uint16_t type; - bool *out_present; - CBS *out_data; + bool allowed; + bool present; + CBS data; }; // ssl_parse_extensions parses a TLS extensions block out of |cbs| and advances -// it. It writes the parsed extensions to pointers denoted by |ext_types|. On -// success, it fills in the |out_present| and |out_data| fields and returns -// true. Otherwise, it sets |*out_alert| to an alert to send and returns false. -// Unknown extensions are rejected unless |ignore_unknown| is true. +// it. It writes the parsed extensions to pointers in |extensions|. On success, +// it fills in the |present| and |data| fields and returns true. Otherwise, it +// sets |*out_alert| to an alert to send and returns false. Unknown extensions +// are rejected unless |ignore_unknown| is true. bool ssl_parse_extensions(const CBS *cbs, uint8_t *out_alert, - Span<const SSL_EXTENSION_TYPE> ext_types, + std::initializer_list<SSLExtension *> extensions, bool ignore_unknown); // ssl_verify_peer_cert verifies the peer certificate for |hs|. @@ -2255,6 +2276,9 @@ bool ssl_log_secret(const SSL *ssl, const char *label, OPENSSL_EXPORT bool ssl_client_hello_init(const SSL *ssl, SSL_CLIENT_HELLO *out, Span<const uint8_t> body); +bool ssl_parse_client_hello_with_trailing_data(const SSL *ssl, CBS *cbs, + SSL_CLIENT_HELLO *out); + bool ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello, CBS *out, uint16_t extension_type); @@ -2315,7 +2339,7 @@ bool tls12_check_peer_sigalg(const SSL_HANDSHAKE *hs, uint8_t *out_alert, #define TLSEXT_CHANNEL_ID_SIZE 128 -// From RFC4492, used in encoding the curve type in ECParameters +// From RFC 4492, used in encoding the curve type in ECParameters #define NAMED_CURVE_TYPE 3 struct CERT { @@ -3292,19 +3316,15 @@ bool tls1_set_curves_list(Array<uint16_t> *out_group_ids, const char *curves); // 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_client_hello_type_t type, + size_t header_len); bool ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out); bool ssl_parse_clienthello_tlsext(SSL_HANDSHAKE *hs, const SSL_CLIENT_HELLO *client_hello); -bool ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, CBS *cbs); +bool ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, const CBS *extensions); #define tlsext_tick_md EVP_sha256 |