Packages
hackney
3.0.2
4.7.2
4.7.1
4.7.0
4.6.1
4.6.0
4.5.2
4.5.1
4.5.0
4.4.5
4.4.3
4.4.2
4.4.1
4.4.0
4.3.0
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.3
4.0.2
4.0.1
4.0.0
3.2.1
3.2.0
3.1.2
3.1.1
3.1.0
3.0.3
3.0.2
3.0.1
3.0.0
retired
2.0.1
2.0.0
2.0.0-beta.1
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.1
1.20.0
1.19.1
1.19.0
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.0
1.15.2
1.15.1
1.15.0
1.14.3
1.14.2
1.14.0
1.13.0
1.12.1
1.12.0
1.11.0
1.10.1
1.10.0
1.9.0
1.8.6
1.8.5
1.8.4
1.8.3
1.8.2
1.8.0
1.7.1
1.7.0
1.6.6
retired
1.6.5
1.6.4
retired
1.6.3
1.6.2
1.6.1
1.6.0
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.6
1.0.5
1.0.2
1.0.1
0.15.2
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
Simple HTTP client with HTTP/1.1, HTTP/2, and HTTP/3 support
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
c_src/boringssl/ssl/tls_record.cc
// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#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) {
return !CRYPTO_fuzzer_mode_enabled() &&
!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());
}
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;
}
auto header = in.first(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,
Span(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 = nullptr;
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 = Span(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;
}