|  | /* | 
|  | * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. | 
|  | * | 
|  | * Licensed under the OpenSSL license (the "License").  You may not use | 
|  | * this file except in compliance with the License.  You can obtain a copy | 
|  | * in the file LICENSE in the source distribution or at | 
|  | * https://www.openssl.org/source/license.html | 
|  | */ | 
|  |  | 
|  | #include <openssl/ssl.h> | 
|  |  | 
|  | #include <assert.h> | 
|  | #include <string.h> | 
|  |  | 
|  | #include <openssl/bytestring.h> | 
|  | #include <openssl/err.h> | 
|  | #include <openssl/mem.h> | 
|  |  | 
|  | #include "../crypto/internal.h" | 
|  | #include "internal.h" | 
|  |  | 
|  |  | 
|  | BSSL_NAMESPACE_BEGIN | 
|  |  | 
|  | // kMaxEmptyRecords is the number of consecutive, empty records that will be | 
|  | // processed. Without this limit an attacker could send empty records at a | 
|  | // faster rate than we can process and cause record processing to loop | 
|  | // forever. | 
|  | static const uint8_t kMaxEmptyRecords = 32; | 
|  |  | 
|  | // kMaxEarlyDataSkipped is the maximum number of rejected early data bytes that | 
|  | // will be skipped. Without this limit an attacker could send records at a | 
|  | // faster rate than we can process and cause trial decryption to loop forever. | 
|  | // This value should be slightly above kMaxEarlyDataAccepted, which is measured | 
|  | // in plaintext. | 
|  | static const size_t kMaxEarlyDataSkipped = 16384; | 
|  |  | 
|  | // kMaxWarningAlerts is the number of consecutive warning alerts that will be | 
|  | // processed. | 
|  | 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) { | 
|  | #if !defined(BORINGSSL_UNSAFE_FUZZER_MODE) | 
|  | return !ssl->s3->aead_write_ctx->is_null_cipher() && | 
|  | ssl_protocol_version(ssl) < TLS1_1_VERSION && | 
|  | (ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 && | 
|  | SSL_CIPHER_is_block_cipher(ssl->s3->aead_write_ctx->cipher()); | 
|  | #else | 
|  | return false; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | size_t ssl_record_prefix_len(const SSL *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, | 
|  | size_t consumed) { | 
|  | ssl->s3->early_data_skipped += consumed; | 
|  | if (ssl->s3->early_data_skipped < consumed) { | 
|  | ssl->s3->early_data_skipped = kMaxEarlyDataSkipped + 1; | 
|  | } | 
|  |  | 
|  | if (ssl->s3->early_data_skipped > kMaxEarlyDataSkipped) { | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA); | 
|  | *out_alert = SSL_AD_UNEXPECTED_MESSAGE; | 
|  | return ssl_open_record_error; | 
|  | } | 
|  |  | 
|  | return ssl_open_record_discard; | 
|  | } | 
|  |  | 
|  | static uint16_t tls_record_version(const SSL *ssl) { | 
|  | if (ssl->s3->version == 0) { | 
|  | // Before the version is determined, outgoing records use TLS 1.0 for | 
|  | // historical compatibility requirements. | 
|  | return TLS1_VERSION; | 
|  | } | 
|  |  | 
|  | // TLS 1.3 freezes the record version at TLS 1.2. Previous ones use the | 
|  | // version itself. | 
|  | return ssl_protocol_version(ssl) >= TLS1_3_VERSION ? TLS1_2_VERSION | 
|  | : ssl->s3->version; | 
|  | } | 
|  |  | 
|  | ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, | 
|  | Span<uint8_t> *out, size_t *out_consumed, | 
|  | uint8_t *out_alert, Span<uint8_t> in) { | 
|  | *out_consumed = 0; | 
|  | if (ssl->s3->read_shutdown == ssl_shutdown_close_notify) { | 
|  | return ssl_open_record_close_notify; | 
|  | } | 
|  |  | 
|  | // If there is an unprocessed handshake message or we are already buffering | 
|  | // too much, stop before decrypting another handshake record. | 
|  | if (!tls_can_accept_handshake_data(ssl, out_alert)) { | 
|  | return ssl_open_record_error; | 
|  | } | 
|  |  | 
|  | CBS cbs = CBS(in); | 
|  |  | 
|  | // Decode the record header. | 
|  | uint8_t type; | 
|  | uint16_t version, ciphertext_len; | 
|  | if (!CBS_get_u8(&cbs, &type) ||      // | 
|  | !CBS_get_u16(&cbs, &version) ||  // | 
|  | !CBS_get_u16(&cbs, &ciphertext_len)) { | 
|  | *out_consumed = SSL3_RT_HEADER_LENGTH; | 
|  | return ssl_open_record_partial; | 
|  | } | 
|  |  | 
|  | bool version_ok; | 
|  | if (ssl->s3->aead_read_ctx->is_null_cipher()) { | 
|  | // Only check the first byte. Enforcing beyond that can prevent decoding | 
|  | // version negotiation failure alerts. | 
|  | version_ok = (version >> 8) == SSL3_VERSION_MAJOR; | 
|  | } else { | 
|  | version_ok = version == tls_record_version(ssl); | 
|  | } | 
|  |  | 
|  | if (!version_ok) { | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER); | 
|  | *out_alert = SSL_AD_PROTOCOL_VERSION; | 
|  | return ssl_open_record_error; | 
|  | } | 
|  |  | 
|  | // Check the ciphertext length. | 
|  | if (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH) { | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); | 
|  | *out_alert = SSL_AD_RECORD_OVERFLOW; | 
|  | return ssl_open_record_error; | 
|  | } | 
|  |  | 
|  | // Extract the body. | 
|  | CBS body; | 
|  | if (!CBS_get_bytes(&cbs, &body, ciphertext_len)) { | 
|  | *out_consumed = SSL3_RT_HEADER_LENGTH + (size_t)ciphertext_len; | 
|  | return ssl_open_record_partial; | 
|  | } | 
|  |  | 
|  | 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); | 
|  |  | 
|  | // In TLS 1.3, during the handshake, skip ChangeCipherSpec records. | 
|  | static const uint8_t kChangeCipherSpec[] = {SSL3_MT_CCS}; | 
|  | if (ssl_has_final_version(ssl) && | 
|  | ssl_protocol_version(ssl) >= TLS1_3_VERSION && SSL_in_init(ssl) && | 
|  | type == SSL3_RT_CHANGE_CIPHER_SPEC && | 
|  | Span<const uint8_t>(body) == kChangeCipherSpec) { | 
|  | ssl->s3->empty_record_count++; | 
|  | if (ssl->s3->empty_record_count > kMaxEmptyRecords) { | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS); | 
|  | *out_alert = SSL_AD_UNEXPECTED_MESSAGE; | 
|  | return ssl_open_record_error; | 
|  | } | 
|  | return ssl_open_record_discard; | 
|  | } | 
|  |  | 
|  | // Skip early data received when expecting a second ClientHello if we rejected | 
|  | // 0RTT. | 
|  | if (ssl->s3->skip_early_data &&                  // | 
|  | ssl->s3->aead_read_ctx->is_null_cipher() &&  // | 
|  | type == SSL3_RT_APPLICATION_DATA) { | 
|  | return skip_early_data(ssl, out_alert, *out_consumed); | 
|  | } | 
|  |  | 
|  | // Ensure the sequence number update does not overflow. | 
|  | if (ssl->s3->read_sequence + 1 == 0) { | 
|  | OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); | 
|  | *out_alert = SSL_AD_INTERNAL_ERROR; | 
|  | return ssl_open_record_error; | 
|  | } | 
|  |  | 
|  | // Decrypt the body in-place. | 
|  | if (!ssl->s3->aead_read_ctx->Open( | 
|  | 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(); | 
|  | return skip_early_data(ssl, out_alert, *out_consumed); | 
|  | } | 
|  |  | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); | 
|  | *out_alert = SSL_AD_BAD_RECORD_MAC; | 
|  | return ssl_open_record_error; | 
|  | } | 
|  |  | 
|  | ssl->s3->skip_early_data = false; | 
|  | ssl->s3->read_sequence++; | 
|  |  | 
|  | // TLS 1.3 hides the record type inside the encrypted data. | 
|  | bool has_padding = !ssl->s3->aead_read_ctx->is_null_cipher() && | 
|  | ssl_protocol_version(ssl) >= TLS1_3_VERSION; | 
|  |  | 
|  | // If there is padding, the plaintext limit includes the padding, but includes | 
|  | // extra room for the inner content type. | 
|  | size_t plaintext_limit = | 
|  | has_padding ? SSL3_RT_MAX_PLAIN_LENGTH + 1 : SSL3_RT_MAX_PLAIN_LENGTH; | 
|  | if (out->size() > plaintext_limit) { | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); | 
|  | *out_alert = SSL_AD_RECORD_OVERFLOW; | 
|  | return ssl_open_record_error; | 
|  | } | 
|  |  | 
|  | if (has_padding) { | 
|  | // The outer record type is always application_data. | 
|  | if (type != SSL3_RT_APPLICATION_DATA) { | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_RECORD_TYPE); | 
|  | *out_alert = SSL_AD_DECODE_ERROR; | 
|  | return ssl_open_record_error; | 
|  | } | 
|  |  | 
|  | do { | 
|  | if (out->empty()) { | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); | 
|  | *out_alert = SSL_AD_DECRYPT_ERROR; | 
|  | return ssl_open_record_error; | 
|  | } | 
|  | type = out->back(); | 
|  | *out = out->subspan(0, out->size() - 1); | 
|  | } while (type == 0); | 
|  | } | 
|  |  | 
|  | // Limit the number of consecutive empty records. | 
|  | if (out->empty()) { | 
|  | ssl->s3->empty_record_count++; | 
|  | if (ssl->s3->empty_record_count > kMaxEmptyRecords) { | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS); | 
|  | *out_alert = SSL_AD_UNEXPECTED_MESSAGE; | 
|  | return ssl_open_record_error; | 
|  | } | 
|  | // Apart from the limit, empty records are returned up to the caller. This | 
|  | // allows the caller to reject records of the wrong type. | 
|  | } else { | 
|  | ssl->s3->empty_record_count = 0; | 
|  | } | 
|  |  | 
|  | if (type == SSL3_RT_ALERT) { | 
|  | return ssl_process_alert(ssl, out_alert, *out); | 
|  | } | 
|  |  | 
|  | // Handshake messages may not interleave with any other record type. | 
|  | if (type != SSL3_RT_HANDSHAKE &&  // | 
|  | tls_has_unprocessed_handshake_data(ssl)) { | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); | 
|  | *out_alert = SSL_AD_UNEXPECTED_MESSAGE; | 
|  | return ssl_open_record_error; | 
|  | } | 
|  |  | 
|  | ssl->s3->warning_alert_count = 0; | 
|  |  | 
|  | *out_type = type; | 
|  | return ssl_open_record_success; | 
|  | } | 
|  |  | 
|  | static bool 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 (!aead->is_null_cipher() && ssl_protocol_version(ssl) >= 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, 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 false; | 
|  | } | 
|  |  | 
|  | assert(in == out || !buffers_alias(in, in_len, out, in_len)); | 
|  | assert(!buffers_alias(in, in_len, out_prefix, ssl_record_prefix_len(ssl))); | 
|  | assert(!buffers_alias(in, in_len, out_suffix, suffix_len)); | 
|  |  | 
|  | if (extra_in_len) { | 
|  | out_prefix[0] = SSL3_RT_APPLICATION_DATA; | 
|  | } else { | 
|  | out_prefix[0] = type; | 
|  | } | 
|  |  | 
|  | uint16_t record_version = tls_record_version(ssl); | 
|  | 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); | 
|  |  | 
|  | // Ensure the sequence number update does not overflow. | 
|  | if (ssl->s3->write_sequence + 1 == 0) { | 
|  | OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | 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)) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | ssl->s3->write_sequence++; | 
|  | ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, header); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | static size_t tls_seal_scatter_prefix_len(const SSL *ssl, uint8_t type, | 
|  | 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)) { | 
|  | // In the case of record splitting, the 1-byte record (of the 1/n-1 split) | 
|  | // will be placed in the prefix, as will four of the five bytes of the | 
|  | // record header for the main record. The final byte will replace the first | 
|  | // byte of the plaintext that was used in the small record. | 
|  | ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher()); | 
|  | ret += SSL3_RT_HEADER_LENGTH - 1; | 
|  | } else { | 
|  | ret += ssl->s3->aead_write_ctx->ExplicitNonceLen(); | 
|  | } | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | static bool tls_seal_scatter_suffix_len(const SSL *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) { | 
|  | // TLS 1.3 adds an extra byte for encrypted record type. | 
|  | extra_in_len = 1; | 
|  | } | 
|  | // clang-format off | 
|  | if (type == SSL3_RT_APPLICATION_DATA && | 
|  | in_len > 1 && | 
|  | ssl_needs_record_splitting(ssl)) { | 
|  | // With record splitting enabled, the first byte gets sealed into a separate | 
|  | // record which is written into the prefix. | 
|  | in_len -= 1; | 
|  | } | 
|  | // clang-format on | 
|  | return ssl->s3->aead_write_ctx->SuffixLen(out_suffix_len, in_len, | 
|  | extra_in_len); | 
|  | } | 
|  |  | 
|  | // tls_seal_scatter_record seals a new record of type |type| and body |in| and | 
|  | // splits it between |out_prefix|, |out|, and |out_suffix|. Exactly | 
|  | // |tls_seal_scatter_prefix_len| bytes are written to |out_prefix|, |in_len| | 
|  | // bytes to |out|, and |tls_seal_scatter_suffix_len| bytes to |out_suffix|. It | 
|  | // 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) { | 
|  | if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 && | 
|  | ssl_needs_record_splitting(ssl)) { | 
|  | assert(ssl->s3->aead_write_ctx->ExplicitNonceLen() == 0); | 
|  | const size_t prefix_len = SSL3_RT_HEADER_LENGTH; | 
|  |  | 
|  | // Write the 1-byte fragment into |out_prefix|. | 
|  | uint8_t *split_body = out_prefix + prefix_len; | 
|  | uint8_t *split_suffix = split_body + 1; | 
|  |  | 
|  | if (!do_seal_record(ssl, out_prefix, split_body, split_suffix, type, in, | 
|  | 1)) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | size_t split_record_suffix_len; | 
|  | if (!ssl->s3->aead_write_ctx->SuffixLen(&split_record_suffix_len, 1, 0)) { | 
|  | assert(false); | 
|  | return false; | 
|  | } | 
|  | const size_t split_record_len = prefix_len + 1 + split_record_suffix_len; | 
|  | assert(SSL3_RT_HEADER_LENGTH + ssl_cipher_get_record_split_len( | 
|  | ssl->s3->aead_write_ctx->cipher()) == | 
|  | split_record_len); | 
|  |  | 
|  | // Write the n-1-byte fragment. The header gets split between |out_prefix| | 
|  | // (header[:-1]) and |out| (header[-1:]). | 
|  | uint8_t tmp_prefix[SSL3_RT_HEADER_LENGTH]; | 
|  | if (!do_seal_record(ssl, tmp_prefix, out + 1, out_suffix, type, in + 1, | 
|  | in_len - 1)) { | 
|  | return false; | 
|  | } | 
|  | assert(tls_seal_scatter_prefix_len(ssl, type, in_len) == | 
|  | split_record_len + SSL3_RT_HEADER_LENGTH - 1); | 
|  | OPENSSL_memcpy(out_prefix + split_record_len, tmp_prefix, | 
|  | SSL3_RT_HEADER_LENGTH - 1); | 
|  | OPENSSL_memcpy(out, tmp_prefix + SSL3_RT_HEADER_LENGTH - 1, 1); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | 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, | 
|  | 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)) { | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | const size_t prefix_len = tls_seal_scatter_prefix_len(ssl, type, in_len); | 
|  | size_t suffix_len; | 
|  | if (!tls_seal_scatter_suffix_len(ssl, &suffix_len, type, in_len)) { | 
|  | return false; | 
|  | } | 
|  | if (in_len + prefix_len < in_len || | 
|  | prefix_len + in_len + suffix_len < prefix_len + in_len) { | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); | 
|  | return false; | 
|  | } | 
|  | if (max_out_len < in_len + prefix_len + suffix_len) { | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | uint8_t *prefix = out; | 
|  | uint8_t *body = out + prefix_len; | 
|  | uint8_t *suffix = body + in_len; | 
|  | if (!tls_seal_scatter_record(ssl, prefix, body, suffix, type, in, in_len)) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | *out_len = prefix_len + in_len + suffix_len; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert, | 
|  | Span<const uint8_t> in) { | 
|  | // Alerts records may not contain fragmented or multiple alerts. | 
|  | if (in.size() != 2) { | 
|  | *out_alert = SSL_AD_DECODE_ERROR; | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT); | 
|  | return ssl_open_record_error; | 
|  | } | 
|  |  | 
|  | ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_ALERT, in); | 
|  |  | 
|  | const uint8_t alert_level = in[0]; | 
|  | const uint8_t alert_descr = in[1]; | 
|  |  | 
|  | uint16_t alert = (alert_level << 8) | alert_descr; | 
|  | ssl_do_info_callback(ssl, SSL_CB_READ_ALERT, alert); | 
|  |  | 
|  | if (alert_level == SSL3_AL_WARNING) { | 
|  | if (alert_descr == SSL_AD_CLOSE_NOTIFY) { | 
|  | ssl->s3->read_shutdown = ssl_shutdown_close_notify; | 
|  | return ssl_open_record_close_notify; | 
|  | } | 
|  |  | 
|  | // Warning alerts do not exist in TLS 1.3, but RFC 8446 section 6.1 | 
|  | // continues to define user_canceled as a signal to cancel the handshake, | 
|  | // without specifying how to handle it. JDK11 misuses it to signal | 
|  | // full-duplex connection close after the handshake. As a workaround, skip | 
|  | // user_canceled as in TLS 1.2. This matches NSS and OpenSSL. | 
|  | if (ssl_has_final_version(ssl) && | 
|  | ssl_protocol_version(ssl) >= TLS1_3_VERSION && | 
|  | alert_descr != SSL_AD_USER_CANCELLED) { | 
|  | *out_alert = SSL_AD_DECODE_ERROR; | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT); | 
|  | return ssl_open_record_error; | 
|  | } | 
|  |  | 
|  | ssl->s3->warning_alert_count++; | 
|  | if (ssl->s3->warning_alert_count > kMaxWarningAlerts) { | 
|  | *out_alert = SSL_AD_UNEXPECTED_MESSAGE; | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_WARNING_ALERTS); | 
|  | return ssl_open_record_error; | 
|  | } | 
|  | return ssl_open_record_discard; | 
|  | } | 
|  |  | 
|  | if (alert_level == SSL3_AL_FATAL) { | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr); | 
|  | ERR_add_error_dataf("SSL alert number %d", alert_descr); | 
|  | *out_alert = 0;  // No alert to send back to the peer. | 
|  | return ssl_open_record_error; | 
|  | } | 
|  |  | 
|  | *out_alert = SSL_AD_ILLEGAL_PARAMETER; | 
|  | OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_ALERT_TYPE); | 
|  | return ssl_open_record_error; | 
|  | } | 
|  |  | 
|  | BSSL_NAMESPACE_END | 
|  |  | 
|  | using namespace bssl; | 
|  |  | 
|  | size_t SSL_max_seal_overhead(const SSL *ssl) { | 
|  | if (SSL_is_dtls(ssl)) { | 
|  | // TODO(crbug.com/381113363): Use the 0-RTT epoch if writing 0-RTT. | 
|  | return dtls_max_seal_overhead(ssl, ssl->d1->write_epoch.epoch()); | 
|  | } | 
|  |  | 
|  | size_t ret = SSL3_RT_HEADER_LENGTH; | 
|  | ret += ssl->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) { | 
|  | ret += 1; | 
|  | } | 
|  | if (ssl_needs_record_splitting(ssl)) { | 
|  | ret *= 2; | 
|  | } | 
|  | return ret; | 
|  | } |