Remove experimental TLS 1.3 short record header extension.

Due to middlebox and ecosystem intolerance, short record headers are going to
be unsustainable to deploy.

BUG=119

Change-Id: I20fee79dd85bff229eafc6aeb72e4f33cac96d82
Reviewed-on: https://boringssl-review.googlesource.com/14044
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
Steven Valdez 2017-03-02 16:05:03 -05:00 committed by CQ bot account: commit-bot@chromium.org
parent 9ea9f9ce51
commit 924a352d1b
19 changed files with 66 additions and 498 deletions

View File

@ -247,8 +247,6 @@ struct GlobalState {
assert(pkey != nullptr);
SSL_CTX_set1_tls_channel_id(ctx, pkey);
EVP_PKEY_free(pkey);
SSL_CTX_set_short_header_enabled(ctx, 1);
}
~GlobalState() {

View File

@ -240,8 +240,6 @@ struct GlobalState {
SSL_CTX_set_alpn_select_cb(ctx, ALPNSelectCallback, nullptr);
SSL_CTX_set_next_protos_advertised_cb(ctx, NPNAdvertiseCallback, nullptr);
SSL_CTX_set_short_header_enabled(ctx, 1);
}
~GlobalState() {

View File

@ -3210,11 +3210,6 @@ OPENSSL_EXPORT void SSL_CTX_set_grease_enabled(SSL_CTX *ctx, int enabled);
* record with |ssl|. */
OPENSSL_EXPORT size_t SSL_max_seal_overhead(const SSL *ssl);
/* SSL_CTX_set_short_header_enabled configures whether a short record header in
* TLS 1.3 may be negotiated. This allows client and server to negotiate
* https://github.com/tlswg/tls13-spec/pull/762 for testing. */
OPENSSL_EXPORT void SSL_CTX_set_short_header_enabled(SSL_CTX *ctx, int enabled);
/* Deprecated functions. */
@ -4136,10 +4131,6 @@ struct ssl_ctx_st {
/* grease_enabled is one if draft-davidben-tls-grease-01 is enabled and zero
* otherwise. */
unsigned grease_enabled:1;
/* short_header_enabled is one if a short record header in TLS 1.3 may
* be negotiated and zero otherwise. */
unsigned short_header_enabled:1;
};

View File

@ -227,9 +227,6 @@ extern "C" {
/* This is not an IANA defined extension number */
#define TLSEXT_TYPE_channel_id 30032
/* This is not an IANA defined extension number */
#define TLSEXT_TYPE_short_header 27463
/* status request value from RFC 3546 */
#define TLSEXT_STATUSTYPE_ocsp 1

View File

@ -1604,10 +1604,6 @@ typedef struct ssl3_state_st {
* handshake. */
unsigned tlsext_channel_id_valid:1;
/* short_header is one if https://github.com/tlswg/tls13-spec/pull/762 has
* been negotiated. */
unsigned short_header:1;
uint8_t send_alert[2];
/* pending_flight is the pending outgoing flight. This is used to flush each

View File

@ -2552,10 +2552,6 @@ void SSL_CTX_set_grease_enabled(SSL_CTX *ctx, int enabled) {
ctx->grease_enabled = !!enabled;
}
void SSL_CTX_set_short_header_enabled(SSL_CTX *ctx, int enabled) {
ctx->short_header_enabled = !!enabled;
}
int SSL_clear(SSL *ssl) {
/* In OpenSSL, reusing a client |SSL| with |SSL_clear| causes the previously
* established session to be offered the next time around. wpa_supplicant

View File

@ -2403,46 +2403,6 @@ static int ext_cookie_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
}
/* Short record headers
*
* This is a non-standard extension which negotiates
* https://github.com/tlswg/tls13-spec/pull/762 for experimenting. */
static int ext_short_header_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
uint16_t min_version, max_version;
if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
return 0;
}
if (max_version < TLS1_3_VERSION ||
!ssl->ctx->short_header_enabled) {
return 1;
}
return CBB_add_u16(out, TLSEXT_TYPE_short_header) &&
CBB_add_u16(out, 0 /* empty extension */);
}
static int ext_short_header_parse_clienthello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents == NULL ||
!ssl->ctx->short_header_enabled ||
ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
return 1;
}
if (CBS_len(contents) != 0) {
return 0;
}
ssl->s3->short_header = 1;
return 1;
}
/* Negotiated Groups
*
* https://tools.ietf.org/html/rfc4492#section-5.1.2
@ -2673,14 +2633,6 @@ static const struct tls_extension kExtensions[] = {
ignore_parse_clienthello,
dont_add_serverhello,
},
{
TLSEXT_TYPE_short_header,
NULL,
ext_short_header_add_clienthello,
forbid_parse_serverhello,
ext_short_header_parse_clienthello,
dont_add_serverhello,
},
/* The final extension must be non-empty. WebSphere Application Server 7.0 is
* intolerant to the last extension being zero-length. See
* https://crbug.com/363583. */

View File

@ -1176,10 +1176,6 @@ static bssl::UniquePtr<SSL_CTX> SetupCtx(const TestConfig *config) {
return nullptr;
}
if (config->enable_short_header) {
SSL_CTX_set_short_header_enabled(ssl_ctx.get(), 1);
}
if (config->enable_early_data) {
SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1);
}

View File

@ -100,7 +100,6 @@ const (
extensionNextProtoNeg uint16 = 13172 // not IANA assigned
extensionRenegotiationInfo uint16 = 0xff01
extensionChannelID uint16 = 30032 // not IANA assigned
extensionShortHeader uint16 = 27463 // not IANA assigned
)
// TLS signaling cipher suite values
@ -223,7 +222,6 @@ type ConnectionState struct {
SCTList []byte // signed certificate timestamp list
PeerSignatureAlgorithm signatureAlgorithm // algorithm used by the peer in the handshake
CurveID CurveID // the curve used in ECDHE
ShortHeader bool // whether the short header extension was negotiated
}
// ClientAuthType declares the policy the server will follow for
@ -1274,18 +1272,6 @@ type ProtocolBugs struct {
// request signed certificate timestamps.
NoSignedCertificateTimestamps bool
// EnableShortHeader, if true, causes the TLS 1.3 short header extension
// to be enabled.
EnableShortHeader bool
// AlwaysNegotiateShortHeader, if true, causes the server to always
// negotiate the short header extension in ServerHello.
AlwaysNegotiateShortHeader bool
// ClearShortHeaderBit, if true, causes the server to send short headers
// without the high bit set.
ClearShortHeaderBit bool
// SendSupportedPointFormats, if not nil, is the list of supported point
// formats to send in ClientHello or ServerHello. If set to a non-nil
// empty slice, no extension will be sent.

View File

@ -167,8 +167,6 @@ type halfConn struct {
trafficSecret []byte
shortHeader bool
config *Config
}
@ -315,17 +313,10 @@ func (hc *halfConn) updateOutSeq() {
copy(hc.outSeq[:], hc.seq[:])
}
func (hc *halfConn) isShortHeader() bool {
return hc.shortHeader && hc.cipher != nil
}
func (hc *halfConn) recordHeaderLen() int {
if hc.isDTLS {
return dtlsRecordHeaderLen
}
if hc.isShortHeader() {
return 2
}
return tlsRecordHeaderLen
}
@ -629,9 +620,6 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int, typ recordType) (bool,
n := len(b.data) - recordHeaderLen
b.data[recordHeaderLen-2] = byte(n >> 8)
b.data[recordHeaderLen-1] = byte(n)
if hc.isShortHeader() && !hc.config.Bugs.ClearShortHeaderBit {
b.data[0] |= 0x80
}
hc.incSeq(true)
return true, 0
@ -762,35 +750,20 @@ RestartReadRecord:
return 0, nil, err
}
var typ recordType
var vers uint16
var n int
if c.in.isShortHeader() {
typ = recordTypeApplicationData
vers = VersionTLS10
n = int(b.data[0])<<8 | int(b.data[1])
if n&0x8000 == 0 {
c.sendAlert(alertDecodeError)
return 0, nil, c.in.setErrorLocked(errors.New("tls: length did not have high bit set"))
}
typ := recordType(b.data[0])
n = n & 0x7fff
} else {
typ = recordType(b.data[0])
// No valid TLS record has a type of 0x80, however SSLv2 handshakes
// start with a uint16 length where the MSB is set and the first record
// is always < 256 bytes long. Therefore typ == 0x80 strongly suggests
// an SSLv2 client.
if want == recordTypeHandshake && typ == 0x80 {
c.sendAlert(alertProtocolVersion)
return 0, nil, c.in.setErrorLocked(errors.New("tls: unsupported SSLv2 handshake received"))
}
vers = uint16(b.data[1])<<8 | uint16(b.data[2])
n = int(b.data[3])<<8 | int(b.data[4])
// No valid TLS record has a type of 0x80, however SSLv2 handshakes
// start with a uint16 length where the MSB is set and the first record
// is always < 256 bytes long. Therefore typ == 0x80 strongly suggests
// an SSLv2 client.
if want == recordTypeHandshake && typ == 0x80 {
c.sendAlert(alertProtocolVersion)
return 0, nil, c.in.setErrorLocked(errors.New("tls: unsupported SSLv2 handshake received"))
}
vers := uint16(b.data[1])<<8 | uint16(b.data[2])
n := int(b.data[3])<<8 | int(b.data[4])
// Alerts sent near version negotiation do not have a well-defined
// record-layer version prior to TLS 1.3. (In TLS 1.3, the record-layer
// version is irrelevant.)
@ -1118,36 +1091,32 @@ func (c *Conn) doWriteRecord(typ recordType, data []byte) (n int, err error) {
}
}
b.resize(recordHeaderLen + explicitIVLen + m)
// If using a short record header, the length will be filled in
// by encrypt.
if !c.out.isShortHeader() {
b.data[0] = byte(typ)
if c.vers >= VersionTLS13 && c.out.cipher != nil {
b.data[0] = byte(recordTypeApplicationData)
if outerType := c.config.Bugs.OuterRecordType; outerType != 0 {
b.data[0] = byte(outerType)
}
b.data[0] = byte(typ)
if c.vers >= VersionTLS13 && c.out.cipher != nil {
b.data[0] = byte(recordTypeApplicationData)
if outerType := c.config.Bugs.OuterRecordType; outerType != 0 {
b.data[0] = byte(outerType)
}
vers := c.vers
if vers == 0 || vers >= VersionTLS13 {
// Some TLS servers fail if the record version is
// greater than TLS 1.0 for the initial ClientHello.
//
// TLS 1.3 fixes the version number in the record
// layer to {3, 1}.
vers = VersionTLS10
}
if c.config.Bugs.SendRecordVersion != 0 {
vers = c.config.Bugs.SendRecordVersion
}
if c.vers == 0 && c.config.Bugs.SendInitialRecordVersion != 0 {
vers = c.config.Bugs.SendInitialRecordVersion
}
b.data[1] = byte(vers >> 8)
b.data[2] = byte(vers)
b.data[3] = byte(m >> 8)
b.data[4] = byte(m)
}
vers := c.vers
if vers == 0 || vers >= VersionTLS13 {
// Some TLS servers fail if the record version is
// greater than TLS 1.0 for the initial ClientHello.
//
// TLS 1.3 fixes the version number in the record
// layer to {3, 1}.
vers = VersionTLS10
}
if c.config.Bugs.SendRecordVersion != 0 {
vers = c.config.Bugs.SendRecordVersion
}
if c.vers == 0 && c.config.Bugs.SendInitialRecordVersion != 0 {
vers = c.config.Bugs.SendInitialRecordVersion
}
b.data[1] = byte(vers >> 8)
b.data[2] = byte(vers)
b.data[3] = byte(m >> 8)
b.data[4] = byte(m)
if explicitIVLen > 0 {
explicitIV := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
if explicitIVIsSeq {
@ -1705,7 +1674,6 @@ func (c *Conn) ConnectionState() ConnectionState {
state.SCTList = c.sctList
state.PeerSignatureAlgorithm = c.peerSignatureAlgorithm
state.CurveID = c.curveID
state.ShortHeader = c.in.shortHeader
}
return state
@ -1873,8 +1841,3 @@ func (c *Conn) sendFakeEarlyData(len int) error {
_, err := c.conn.Write(payload)
return err
}
func (c *Conn) setShortHeader() {
c.in.shortHeader = true
c.out.shortHeader = true
}

View File

@ -81,7 +81,6 @@ func (c *Conn) clientHandshake() error {
srtpMasterKeyIdentifier: c.config.Bugs.SRTPMasterKeyIdentifer,
customExtension: c.config.Bugs.CustomExtension,
pskBinderFirst: c.config.Bugs.PSKBinderFirst,
shortHeaderSupported: c.config.Bugs.EnableShortHeader,
}
disableEMS := c.config.Bugs.NoExtendedMasterSecret
@ -717,18 +716,6 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
hs.finishedHash.addEntropy(zeroSecret)
}
if hs.serverHello.shortHeader && !hs.hello.shortHeaderSupported {
return errors.New("tls: server sent unsolicited short header extension")
}
if hs.serverHello.shortHeader && hs.hello.hasEarlyData {
return errors.New("tls: server sent short header extension in response to early data")
}
if hs.serverHello.shortHeader {
c.setShortHeader()
}
// Derive handshake traffic keys and switch read key to handshake
// traffic key.
clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(clientHandshakeTrafficLabel)
@ -1363,10 +1350,6 @@ func (hs *clientHandshakeState) serverResumedSession() bool {
func (hs *clientHandshakeState) processServerHello() (bool, error) {
c := hs.c
if hs.serverHello.shortHeader {
return false, errors.New("tls: short header extension sent before TLS 1.3")
}
if hs.serverResumedSession() {
// For test purposes, assert that the server never accepts the
// resumption offer on renegotiation.

View File

@ -167,7 +167,6 @@ type clientHelloMsg struct {
customExtension string
hasGREASEExtension bool
pskBinderFirst bool
shortHeaderSupported bool
}
func (m *clientHelloMsg) equal(i interface{}) bool {
@ -213,8 +212,7 @@ func (m *clientHelloMsg) equal(i interface{}) bool {
m.sctListSupported == m1.sctListSupported &&
m.customExtension == m1.customExtension &&
m.hasGREASEExtension == m1.hasGREASEExtension &&
m.pskBinderFirst == m1.pskBinderFirst &&
m.shortHeaderSupported == m1.shortHeaderSupported
m.pskBinderFirst == m1.pskBinderFirst
}
func (m *clientHelloMsg) marshal() []byte {
@ -430,10 +428,6 @@ func (m *clientHelloMsg) marshal() []byte {
customExt := extensions.addU16LengthPrefixed()
customExt.addBytes([]byte(m.customExtension))
}
if m.shortHeaderSupported {
extensions.addU16(extensionShortHeader)
extensions.addU16(0) // Length is always 0
}
// The PSK extension must be last (draft-ietf-tls-tls13-18 section 4.2.6).
if len(m.pskIdentities) > 0 && !m.pskBinderFirst {
extensions.addU16(extensionPreSharedKey)
@ -805,11 +799,6 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
return false
}
m.sctListSupported = true
case extensionShortHeader:
if length != 0 {
return false
}
m.shortHeaderSupported = true
case extensionCustom:
m.customExtension = string(data[:length])
}
@ -838,7 +827,6 @@ type serverHelloMsg struct {
compressionMethod uint8
customExtension string
unencryptedALPN string
shortHeader bool
extensions serverExtensions
}
@ -876,11 +864,6 @@ func (m *serverHelloMsg) marshal() []byte {
extensions := hello.addU16LengthPrefixed()
if m.shortHeader {
extensions.addU16(extensionShortHeader)
extensions.addU16(0) // Length
}
if vers >= VersionTLS13 {
if m.hasKeyShare {
extensions.addU16(extensionKeyShare)
@ -1000,11 +983,6 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
}
m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
m.hasPSKIdentity = true
case extensionShortHeader:
if len(d) != 0 {
return false
}
m.shortHeader = true
default:
// Only allow the 3 extensions that are sent in
// the clear in TLS 1.3.

View File

@ -365,15 +365,6 @@ func (hs *serverHandshakeState) doTLS13Handshake() error {
versOverride: config.Bugs.SendServerHelloVersion,
customExtension: config.Bugs.CustomUnencryptedExtension,
unencryptedALPN: config.Bugs.SendUnencryptedALPN,
shortHeader: hs.clientHello.shortHeaderSupported && config.Bugs.EnableShortHeader,
}
if config.Bugs.AlwaysNegotiateShortHeader {
hs.hello.shortHeader = true
}
if hs.hello.shortHeader {
c.setShortHeader()
}
hs.hello.random = make([]byte, 32)
@ -1025,7 +1016,6 @@ func (hs *serverHandshakeState) processClientHello() (isResume bool, err error)
vers: versionToWire(c.vers, c.isDTLS),
versOverride: config.Bugs.SendServerHelloVersion,
compressionMethod: compressionNone,
shortHeader: config.Bugs.AlwaysNegotiateShortHeader,
}
hs.hello.random = make([]byte, 32)

View File

@ -407,8 +407,6 @@ type testCase struct {
// expectPeerCertificate, if not nil, is the certificate chain the peer
// is expected to send.
expectPeerCertificate *Certificate
// expectShortHeader is whether the short header extension should be negotiated.
expectShortHeader bool
}
var testCases []testCase
@ -637,10 +635,6 @@ func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool, nu
}
}
if test.expectShortHeader != connState.ShortHeader {
return fmt.Errorf("ShortHeader is %t, but we expected the opposite", connState.ShortHeader)
}
if test.exportKeyingMaterial > 0 {
actual := make([]byte, test.exportKeyingMaterial)
if _, err := io.ReadFull(tlsConn, actual); err != nil {
@ -2686,27 +2680,6 @@ func addTestForCipherSuite(suite testCipherSuite, ver tlsVersion, protocol proto
shouldFail: shouldFail,
expectedError: expectedError,
})
if ver.version >= VersionTLS13 {
testCases = append(testCases, testCase{
protocol: protocol,
name: prefix + ver.name + "-" + suite.name + "-ShortHeader",
config: Config{
MinVersion: ver.version,
MaxVersion: ver.version,
CipherSuites: []uint16{suite.id},
Certificates: []Certificate{cert},
PreSharedKey: []byte(psk),
PreSharedKeyIdentity: pskIdentity,
Bugs: ProtocolBugs{
EnableShortHeader: true,
},
},
flags: append([]string{"-enable-short-header"}, flags...),
resumeSession: true,
expectShortHeader: true,
})
}
}
func addCipherSuiteTests() {
@ -10244,150 +10217,6 @@ func addECDSAKeyUsageTests() {
}
}
func addShortHeaderTests() {
// The short header extension may be negotiated as either client or
// server.
testCases = append(testCases, testCase{
name: "ShortHeader-Client",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
EnableShortHeader: true,
},
},
flags: []string{"-enable-short-header"},
expectShortHeader: true,
})
testCases = append(testCases, testCase{
testType: serverTest,
name: "ShortHeader-Server",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
EnableShortHeader: true,
},
},
flags: []string{"-enable-short-header"},
expectShortHeader: true,
})
// If the peer doesn't support it, it will not be negotiated.
testCases = append(testCases, testCase{
name: "ShortHeader-No-Yes-Client",
config: Config{
MaxVersion: VersionTLS13,
},
flags: []string{"-enable-short-header"},
})
testCases = append(testCases, testCase{
testType: serverTest,
name: "ShortHeader-No-Yes-Server",
config: Config{
MaxVersion: VersionTLS13,
},
flags: []string{"-enable-short-header"},
})
// If we don't support it, it will not be negotiated.
testCases = append(testCases, testCase{
name: "ShortHeader-Yes-No-Client",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
EnableShortHeader: true,
},
},
})
testCases = append(testCases, testCase{
testType: serverTest,
name: "ShortHeader-Yes-No-Server",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
EnableShortHeader: true,
},
},
})
// It will not be negotiated at TLS 1.2.
testCases = append(testCases, testCase{
name: "ShortHeader-TLS12-Client",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
EnableShortHeader: true,
},
},
flags: []string{"-enable-short-header"},
})
testCases = append(testCases, testCase{
testType: serverTest,
name: "ShortHeader-TLS12-Server",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
EnableShortHeader: true,
},
},
flags: []string{"-enable-short-header"},
})
// Servers reject early data and short header sent together.
testCases = append(testCases, testCase{
testType: serverTest,
name: "ShortHeader-EarlyData",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
EnableShortHeader: true,
SendFakeEarlyDataLength: 1,
},
},
flags: []string{"-enable-short-header"},
shouldFail: true,
expectedError: ":UNEXPECTED_EXTENSION:",
})
// Clients reject unsolicited short header extensions.
testCases = append(testCases, testCase{
name: "ShortHeader-Unsolicited",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
AlwaysNegotiateShortHeader: true,
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_EXTENSION:",
})
testCases = append(testCases, testCase{
name: "ShortHeader-Unsolicited-TLS12",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
AlwaysNegotiateShortHeader: true,
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_EXTENSION:",
})
// The high bit must be checked in short headers.
testCases = append(testCases, testCase{
name: "ShortHeader-ClearShortHeaderBit",
config: Config{
Bugs: ProtocolBugs{
EnableShortHeader: true,
ClearShortHeaderBit: true,
},
},
flags: []string{"-enable-short-header"},
shouldFail: true,
expectedError: ":DECODE_ERROR:",
expectedLocalError: "remote error: error decoding message",
})
}
func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
defer wg.Done()
@ -10514,7 +10343,6 @@ func main() {
addCertificateTests()
addRetainOnlySHA256ClientCertTests()
addECDSAKeyUsageTests()
addShortHeaderTests()
var wg sync.WaitGroup

View File

@ -116,7 +116,6 @@ const Flag<bool> kBoolFlags[] = {
&TestConfig::expect_sha256_client_cert_initial },
{ "-expect-sha256-client-cert-resume",
&TestConfig::expect_sha256_client_cert_resume },
{ "-enable-short-header", &TestConfig::enable_short_header },
{ "-read-with-unfinished-write", &TestConfig::read_with_unfinished_write },
{ "-expect-secure-renegotiation",
&TestConfig::expect_secure_renegotiation },

View File

@ -126,7 +126,6 @@ struct TestConfig {
bool retain_only_sha256_client_cert_resume = false;
bool expect_sha256_client_cert_initial = false;
bool expect_sha256_client_cert_resume = false;
bool enable_short_header = false;
bool read_with_unfinished_write = false;
bool expect_secure_renegotiation = false;
bool expect_no_secure_renegotiation = false;

View File

@ -199,12 +199,11 @@ static enum ssl_hs_wait_t do_process_server_hello(SSL_HANDSHAKE *hs) {
}
/* Parse out the extensions. */
int have_key_share = 0, have_pre_shared_key = 0, have_short_header = 0;
CBS key_share, pre_shared_key, short_header;
int have_key_share = 0, have_pre_shared_key = 0;
CBS key_share, pre_shared_key;
const SSL_EXTENSION_TYPE ext_types[] = {
{TLSEXT_TYPE_key_share, &have_key_share, &key_share},
{TLSEXT_TYPE_pre_shared_key, &have_pre_shared_key, &pre_shared_key},
{TLSEXT_TYPE_short_header, &have_short_header, &short_header},
};
uint8_t alert = SSL_AD_DECODE_ERROR;
@ -318,23 +317,6 @@ static enum ssl_hs_wait_t do_process_server_hello(SSL_HANDSHAKE *hs) {
}
OPENSSL_free(dhe_secret);
/* Negotiate short record headers. */
if (have_short_header) {
if (CBS_len(&short_header) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
if (!ssl->ctx->short_header_enabled) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
return ssl_hs_error;
}
ssl->s3->short_header = 1;
}
if (!ssl_hash_current_message(hs) ||
!tls13_derive_handshake_secrets(hs) ||
!tls13_set_traffic_key(ssl, evp_aead_open, hs->server_handshake_secret,

View File

@ -135,11 +135,6 @@ static const SSL_CIPHER *choose_tls13_cipher(
static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
/* The short record header extension is incompatible with early data. */
if (ssl->s3->skip_early_data && ssl->s3->short_header) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
return ssl_hs_error;
}
SSL_CLIENT_HELLO client_hello;
if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
@ -354,18 +349,8 @@ static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
!CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) ||
!CBB_add_u16_length_prefixed(&body, &extensions) ||
!ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) ||
!ssl_ext_key_share_add_serverhello(hs, &extensions)) {
goto err;
}
if (ssl->s3->short_header) {
if (!CBB_add_u16(&extensions, TLSEXT_TYPE_short_header) ||
!CBB_add_u16(&extensions, 0 /* empty extension */)) {
goto err;
}
}
if (!ssl_add_message_cbb(ssl, &cbb)) {
!ssl_ext_key_share_add_serverhello(hs, &extensions) ||
!ssl_add_message_cbb(ssl, &cbb)) {
goto err;
}

View File

@ -145,19 +145,6 @@ static int ssl_needs_record_splitting(const SSL *ssl) {
SSL_CIPHER_is_block_cipher(ssl->s3->aead_write_ctx->cipher);
}
static int ssl_uses_short_header(const SSL *ssl,
enum evp_aead_direction_t dir) {
if (!ssl->s3->short_header) {
return 0;
}
if (dir == evp_aead_open) {
return ssl->s3->aead_read_ctx != NULL;
}
return ssl->s3->aead_write_ctx != NULL;
}
int ssl_record_sequence_update(uint8_t *seq, size_t seq_len) {
for (size_t i = seq_len - 1; i < seq_len; i--) {
++seq[i];
@ -173,8 +160,6 @@ size_t ssl_record_prefix_len(const SSL *ssl) {
size_t header_len;
if (SSL_is_dtls(ssl)) {
header_len = DTLS1_RT_HEADER_LENGTH;
} else if (ssl_uses_short_header(ssl, evp_aead_open)) {
header_len = 2;
} else {
header_len = SSL3_RT_HEADER_LENGTH;
}
@ -188,17 +173,10 @@ size_t ssl_seal_align_prefix_len(const SSL *ssl) {
SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_write_ctx);
}
size_t header_len;
if (ssl_uses_short_header(ssl, evp_aead_seal)) {
header_len = 2;
} else {
header_len = SSL3_RT_HEADER_LENGTH;
}
size_t ret =
header_len + SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_write_ctx);
size_t ret = SSL3_RT_HEADER_LENGTH +
SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_write_ctx);
if (ssl_needs_record_splitting(ssl)) {
ret += header_len;
ret += SSL3_RT_HEADER_LENGTH;
ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher);
}
return ret;
@ -209,8 +187,7 @@ size_t SSL_max_seal_overhead(const SSL *ssl) {
return dtls_max_seal_overhead(ssl, dtls1_use_current_epoch);
}
size_t ret =
ssl_uses_short_header(ssl, evp_aead_seal) ? 2 : SSL3_RT_HEADER_LENGTH;
size_t ret = SSL3_RT_HEADER_LENGTH;
ret += SSL_AEAD_CTX_max_overhead(ssl->s3->aead_write_ctx);
/* TLS 1.3 needs an extra byte for the encrypted record type. */
if (ssl->s3->have_version &&
@ -234,31 +211,11 @@ enum ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, CBS *out,
/* Decode the record header. */
uint8_t type;
uint16_t version, ciphertext_len;
size_t header_len;
if (ssl_uses_short_header(ssl, evp_aead_open)) {
if (!CBS_get_u16(&cbs, &ciphertext_len)) {
*out_consumed = 2;
return ssl_open_record_partial;
}
if ((ciphertext_len & 0x8000) == 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
*out_alert = SSL_AD_DECODE_ERROR;
return ssl_open_record_error;
}
ciphertext_len &= 0x7fff;
type = SSL3_RT_APPLICATION_DATA;
version = TLS1_VERSION;
header_len = 2;
} else {
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;
}
header_len = SSL3_RT_HEADER_LENGTH;
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;
}
int version_ok;
@ -290,11 +247,12 @@ enum ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, CBS *out,
/* Extract the body. */
CBS body;
if (!CBS_get_bytes(&cbs, &body, ciphertext_len)) {
*out_consumed = header_len + (size_t)ciphertext_len;
*out_consumed = SSL3_RT_HEADER_LENGTH + (size_t)ciphertext_len;
return ssl_open_record_partial;
}
ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, in, header_len);
ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, in,
SSL3_RT_HEADER_LENGTH);
*out_consumed = in_len - CBS_len(&cbs);
@ -398,26 +356,24 @@ static int do_seal_record(SSL *ssl, uint8_t *out, size_t *out_len,
size_t in_len) {
assert(!buffers_alias(in, in_len, out, max_out));
const int short_header = ssl_uses_short_header(ssl, evp_aead_seal);
size_t header_len = short_header ? 2 : SSL3_RT_HEADER_LENGTH;
/* TLS 1.3 hides the actual record type inside the encrypted data. */
if (ssl->s3->have_version &&
ssl3_protocol_version(ssl) >= TLS1_3_VERSION &&
ssl->s3->aead_write_ctx != NULL) {
if (in_len > in_len + header_len + 1 || max_out < in_len + header_len + 1) {
if (in_len > in_len + SSL3_RT_HEADER_LENGTH + 1 ||
max_out < in_len + SSL3_RT_HEADER_LENGTH + 1) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
return 0;
}
OPENSSL_memcpy(out + header_len, in, in_len);
out[header_len + in_len] = type;
in = out + header_len;
OPENSSL_memcpy(out + SSL3_RT_HEADER_LENGTH, in, in_len);
out[SSL3_RT_HEADER_LENGTH + in_len] = type;
in = out + SSL3_RT_HEADER_LENGTH;
type = SSL3_RT_APPLICATION_DATA;
in_len++;
}
if (max_out < header_len) {
if (max_out < SSL3_RT_HEADER_LENGTH) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
return 0;
}
@ -433,13 +389,11 @@ static int do_seal_record(SSL *ssl, uint8_t *out, size_t *out_len,
}
/* Write the non-length portions of the header. */
if (!short_header) {
out[0] = type;
out[1] = wire_version >> 8;
out[2] = wire_version & 0xff;
out += 3;
max_out -= 3;
}
out[0] = type;
out[1] = wire_version >> 8;
out[2] = wire_version & 0xff;
out += 3;
max_out -= 3;
/* Write the ciphertext, leaving two bytes for the length. */
size_t ciphertext_len;
@ -457,13 +411,11 @@ static int do_seal_record(SSL *ssl, uint8_t *out, size_t *out_len,
}
out[0] = ciphertext_len >> 8;
out[1] = ciphertext_len & 0xff;
if (short_header) {
out[0] |= 0x80;
}
*out_len = header_len + ciphertext_len;
*out_len = SSL3_RT_HEADER_LENGTH + ciphertext_len;
ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, out, header_len);
ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, out,
SSL3_RT_HEADER_LENGTH);
return 1;
}
@ -485,7 +437,6 @@ int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
out += frag_len;
max_out -= frag_len;
assert(!ssl_uses_short_header(ssl, evp_aead_seal));
#if !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
assert(SSL3_RT_HEADER_LENGTH + ssl_cipher_get_record_split_len(
ssl->s3->aead_write_ctx->cipher) ==