blob: 08de8fa5f33f7a055e0c7e55257d5074750a16b1 [file] [log] [blame] [edit]
// Copyright 2025 The BoringSSL Authors
//
// 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.
package runner
import "strconv"
func addBasicTests() {
basicTests := []testCase{
{
name: "NoFallbackSCSV",
config: Config{
Bugs: ProtocolBugs{
FailIfNotFallbackSCSV: true,
},
},
shouldFail: true,
expectedLocalError: "no fallback SCSV found",
},
{
name: "SendFallbackSCSV",
config: Config{
Bugs: ProtocolBugs{
FailIfNotFallbackSCSV: true,
},
},
flags: []string{"-fallback-scsv"},
},
{
name: "ClientCertificateTypes",
config: Config{
MaxVersion: VersionTLS12,
ClientAuth: RequestClientCert,
ClientCertificateTypes: []byte{
CertTypeDSSSign,
CertTypeRSASign,
CertTypeECDSASign,
},
},
flags: []string{
"-expect-certificate-types",
base64FlagValue([]byte{
CertTypeDSSSign,
CertTypeRSASign,
CertTypeECDSASign,
}),
},
},
{
name: "CheckClientCertificateTypes",
config: Config{
MaxVersion: VersionTLS12,
ClientAuth: RequestClientCert,
ClientCertificateTypes: []byte{CertTypeECDSASign},
},
shimCertificate: &rsaCertificate,
shouldFail: true,
expectedError: ":UNKNOWN_CERTIFICATE_TYPE:",
},
{
name: "UnauthenticatedECDH",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
Bugs: ProtocolBugs{
UnauthenticatedECDH: true,
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_MESSAGE:",
},
{
name: "SkipCertificateStatus",
config: Config{
MaxVersion: VersionTLS12,
Credential: rsaCertificate.WithOCSP(testOCSPResponse),
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
Bugs: ProtocolBugs{
SkipCertificateStatus: true,
},
},
flags: []string{
"-enable-ocsp-stapling",
// This test involves an optional message. Test the message callback
// trace to ensure we do not miss or double-report any.
"-expect-msg-callback",
`write hs 1
read hs 2
read hs 11
read hs 12
read hs 14
write hs 16
write ccs
write hs 20
read hs 4
read ccs
read hs 20
read alert 1 0
`,
},
},
{
protocol: dtls,
name: "SkipCertificateStatus-DTLS",
config: Config{
MaxVersion: VersionTLS12,
Credential: rsaCertificate.WithOCSP(testOCSPResponse),
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
Bugs: ProtocolBugs{
SkipCertificateStatus: true,
},
},
flags: []string{
"-enable-ocsp-stapling",
// This test involves an optional message. Test the message callback
// trace to ensure we do not miss or double-report any.
"-expect-msg-callback",
`write hs 1
read hs 3
write hs 1
read hs 2
read hs 11
read hs 12
read hs 14
write hs 16
write ccs
write hs 20
read hs 4
read ccs
read hs 20
read alert 1 0
`,
},
},
{
name: "SkipServerKeyExchange",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
Bugs: ProtocolBugs{
SkipServerKeyExchange: true,
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_MESSAGE:",
},
{
testType: serverTest,
name: "ServerSkipCertificateVerify",
config: Config{
MaxVersion: VersionTLS12,
Credential: &rsaCertificate,
Bugs: ProtocolBugs{
SkipCertificateVerify: true,
},
},
expectations: connectionExpectations{
peerCertificate: &rsaCertificate,
},
flags: []string{
"-require-any-client-certificate",
},
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
expectedLocalError: "remote error: unexpected message",
},
{
testType: serverTest,
name: "Alert",
config: Config{
Bugs: ProtocolBugs{
SendSpuriousAlert: alertRecordOverflow,
},
},
shouldFail: true,
expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
},
{
protocol: dtls,
testType: serverTest,
name: "Alert-DTLS",
config: Config{
Bugs: ProtocolBugs{
SendSpuriousAlert: alertRecordOverflow,
},
},
shouldFail: true,
expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
},
{
testType: serverTest,
name: "FragmentAlert",
config: Config{
Bugs: ProtocolBugs{
FragmentAlert: true,
SendSpuriousAlert: alertRecordOverflow,
},
},
shouldFail: true,
expectedError: ":BAD_ALERT:",
},
{
protocol: dtls,
testType: serverTest,
name: "FragmentAlert-DTLS",
config: Config{
Bugs: ProtocolBugs{
FragmentAlert: true,
SendSpuriousAlert: alertRecordOverflow,
},
},
shouldFail: true,
expectedError: ":BAD_ALERT:",
},
{
testType: serverTest,
name: "DoubleAlert",
config: Config{
Bugs: ProtocolBugs{
DoubleAlert: true,
SendSpuriousAlert: alertRecordOverflow,
},
},
shouldFail: true,
expectedError: ":BAD_ALERT:",
},
{
protocol: dtls,
testType: serverTest,
name: "DoubleAlert-DTLS",
config: Config{
Bugs: ProtocolBugs{
DoubleAlert: true,
SendSpuriousAlert: alertRecordOverflow,
},
},
shouldFail: true,
expectedError: ":BAD_ALERT:",
},
{
name: "SkipNewSessionTicket",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
SkipNewSessionTicket: true,
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
},
{
testType: serverTest,
name: "FallbackSCSV",
config: Config{
MaxVersion: VersionTLS11,
Bugs: ProtocolBugs{
SendFallbackSCSV: true,
},
},
shouldFail: true,
expectedError: ":INAPPROPRIATE_FALLBACK:",
expectedLocalError: "remote error: inappropriate fallback",
},
{
testType: serverTest,
name: "FallbackSCSV-VersionMatch-TLS13",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
SendFallbackSCSV: true,
},
},
},
{
testType: serverTest,
name: "FallbackSCSV-VersionMatch-TLS12",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
SendFallbackSCSV: true,
},
},
flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
},
// Regression test for CVE-2014-3511. Even when the ClientHello is
// maximally fragmented, version negotiation works correctly.
{
testType: serverTest,
name: "FragmentedClientVersion",
config: Config{
Bugs: ProtocolBugs{
MaxHandshakeRecordLength: 1,
},
},
expectations: connectionExpectations{
version: VersionTLS13,
},
},
{
testType: serverTest,
name: "HttpGET",
sendPrefix: "GET / HTTP/1.0\n",
shouldFail: true,
expectedError: ":HTTP_REQUEST:",
},
{
testType: serverTest,
name: "HttpPOST",
sendPrefix: "POST / HTTP/1.0\n",
shouldFail: true,
expectedError: ":HTTP_REQUEST:",
},
{
testType: serverTest,
name: "HttpHEAD",
sendPrefix: "HEAD / HTTP/1.0\n",
shouldFail: true,
expectedError: ":HTTP_REQUEST:",
},
{
testType: serverTest,
name: "HttpPUT",
sendPrefix: "PUT / HTTP/1.0\n",
shouldFail: true,
expectedError: ":HTTP_REQUEST:",
},
{
testType: serverTest,
name: "HttpCONNECT",
sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n",
shouldFail: true,
expectedError: ":HTTPS_PROXY_REQUEST:",
},
{
testType: serverTest,
name: "Garbage",
sendPrefix: "blah",
shouldFail: true,
expectedError: ":WRONG_VERSION_NUMBER:",
},
{
name: "RSAEphemeralKey",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
Bugs: ProtocolBugs{
RSAEphemeralKey: true,
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_MESSAGE:",
},
{
name: "DisableEverything",
flags: []string{"-no-tls13", "-no-tls12", "-no-tls11", "-no-tls1"},
shouldFail: true,
expectedError: ":NO_SUPPORTED_VERSIONS_ENABLED:",
},
{
protocol: dtls,
name: "DisableEverything-DTLS",
flags: []string{"-no-tls13", "-no-tls12", "-no-tls1"},
shouldFail: true,
expectedError: ":NO_SUPPORTED_VERSIONS_ENABLED:",
},
{
protocol: dtls,
testType: serverTest,
name: "MTU-DTLS12-AEAD",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
Bugs: ProtocolBugs{
MaxPacketLength: 256,
},
},
flags: []string{"-mtu", "256"},
},
{
protocol: dtls,
testType: serverTest,
name: "MTU-DTLS12-AES-CBC",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
Bugs: ProtocolBugs{
MaxPacketLength: 256,
},
},
flags: []string{"-mtu", "256"},
},
{
protocol: dtls,
testType: serverTest,
name: "MTU-DTLS12-3DES-CBC",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
Bugs: ProtocolBugs{
MaxPacketLength: 256,
},
},
flags: []string{"-mtu", "256", "-cipher", "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
},
{
protocol: dtls,
testType: serverTest,
name: "MTU-DTLS13",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
MaxPacketLength: 256,
},
},
flags: []string{"-mtu", "256"},
},
{
name: "EmptyCertificateList",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
EmptyCertificateList: true,
},
},
shouldFail: true,
expectedError: ":DECODE_ERROR:",
},
{
name: "EmptyCertificateList-TLS13",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
EmptyCertificateList: true,
},
},
shouldFail: true,
expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
},
{
name: "TLSFatalBadPackets",
damageFirstWrite: true,
shouldFail: true,
expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
},
{
protocol: dtls,
name: "DTLSIgnoreBadPackets",
damageFirstWrite: true,
},
{
protocol: dtls,
name: "DTLSIgnoreBadPackets-Async",
damageFirstWrite: true,
flags: []string{"-async"},
},
{
name: "AppDataBeforeHandshake",
config: Config{
Bugs: ProtocolBugs{
AppDataBeforeHandshake: []byte("TEST MESSAGE"),
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
},
{
name: "AppDataBeforeHandshake-Empty",
config: Config{
Bugs: ProtocolBugs{
AppDataBeforeHandshake: []byte{},
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
},
{
protocol: dtls,
name: "AppDataBeforeHandshake-DTLS",
config: Config{
Bugs: ProtocolBugs{
AppDataBeforeHandshake: []byte("TEST MESSAGE"),
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
},
{
protocol: dtls,
name: "AppDataBeforeHandshake-DTLS-Empty",
config: Config{
Bugs: ProtocolBugs{
AppDataBeforeHandshake: []byte{},
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
},
{
name: "AppDataBeforeTLS13KeyChange",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
AppDataBeforeTLS13KeyChange: []byte("TEST MESSAGE"),
},
},
// The shim should fail to decrypt this record.
shouldFail: true,
expectedError: ":BAD_DECRYPT:",
expectedLocalError: "remote error: bad record MAC",
},
{
name: "AppDataBeforeTLS13KeyChange-Empty",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
AppDataBeforeTLS13KeyChange: []byte{},
},
},
// The shim should fail to decrypt this record.
shouldFail: true,
expectedError: ":BAD_DECRYPT:",
expectedLocalError: "remote error: bad record MAC",
},
{
protocol: dtls,
name: "AppDataBeforeTLS13KeyChange-DTLS",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
AppDataBeforeTLS13KeyChange: []byte("TEST MESSAGE"),
},
},
// The shim will decrypt the record, because it has not
// yet applied the key change, but it should know to
// reject the record.
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
expectedLocalError: "remote error: unexpected message",
},
{
protocol: dtls,
name: "AppDataBeforeTLS13KeyChange-DTLS-Empty",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
AppDataBeforeTLS13KeyChange: []byte{},
},
},
// The shim will decrypt the record, because it has not
// yet applied the key change, but it should know to
// reject the record.
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
expectedLocalError: "remote error: unexpected message",
},
{
name: "UnencryptedEncryptedExtensions",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
UnencryptedEncryptedExtensions: true,
},
},
// The shim should fail to decrypt this record.
shouldFail: true,
expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
expectedLocalError: "remote error: bad record MAC",
},
{
protocol: dtls,
name: "UnencryptedEncryptedExtensions-DTLS",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
UnencryptedEncryptedExtensions: true,
},
},
// The shim will decrypt the record, because it has not
// yet applied the key change, but it should know to
// reject new handshake data on the previous epoch.
shouldFail: true,
expectedError: ":EXCESS_HANDSHAKE_DATA:",
expectedLocalError: "remote error: unexpected message",
},
{
name: "AppDataAfterChangeCipherSpec",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
},
{
name: "AppDataAfterChangeCipherSpec-Empty",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
AppDataAfterChangeCipherSpec: []byte{},
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
},
{
protocol: dtls,
name: "AppDataAfterChangeCipherSpec-DTLS",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
},
},
// BoringSSL's DTLS implementation will drop the out-of-order
// application data.
},
{
protocol: dtls,
name: "AppDataAfterChangeCipherSpec-DTLS-Empty",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
AppDataAfterChangeCipherSpec: []byte{},
},
},
// BoringSSL's DTLS implementation will drop the out-of-order
// application data.
},
{
name: "AlertAfterChangeCipherSpec",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
AlertAfterChangeCipherSpec: alertRecordOverflow,
},
},
shouldFail: true,
expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
},
{
protocol: dtls,
name: "AlertAfterChangeCipherSpec-DTLS",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
AlertAfterChangeCipherSpec: alertRecordOverflow,
},
},
shouldFail: true,
expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
},
{
name: "SendInvalidRecordType",
config: Config{
Bugs: ProtocolBugs{
SendInvalidRecordType: true,
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
},
{
protocol: dtls,
name: "SendInvalidRecordType-DTLS",
config: Config{
Bugs: ProtocolBugs{
SendInvalidRecordType: true,
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
},
{
name: "FalseStart-SkipServerSecondLeg",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
NextProtos: []string{"foo"},
Bugs: ProtocolBugs{
SkipNewSessionTicket: true,
SkipChangeCipherSpec: true,
SkipFinished: true,
ExpectFalseStart: true,
},
},
flags: []string{
"-false-start",
"-handshake-never-done",
"-advertise-alpn", "\x03foo",
"-expect-alpn", "foo",
},
shimWritesFirst: true,
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
},
{
name: "FalseStart-SkipServerSecondLeg-Implicit",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
NextProtos: []string{"foo"},
Bugs: ProtocolBugs{
SkipNewSessionTicket: true,
SkipChangeCipherSpec: true,
SkipFinished: true,
},
},
flags: []string{
"-implicit-handshake",
"-false-start",
"-handshake-never-done",
"-advertise-alpn", "\x03foo",
},
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
},
{
testType: serverTest,
name: "FailEarlyCallback",
flags: []string{"-fail-early-callback"},
shouldFail: true,
expectedError: ":CONNECTION_REJECTED:",
expectedLocalError: "remote error: handshake failure",
},
{
name: "FailCertCallback-Client-TLS12",
config: Config{
MaxVersion: VersionTLS12,
ClientAuth: RequestClientCert,
},
flags: []string{"-fail-cert-callback"},
shouldFail: true,
expectedError: ":CERT_CB_ERROR:",
expectedLocalError: "remote error: internal error",
},
{
testType: serverTest,
name: "FailCertCallback-Server-TLS12",
config: Config{
MaxVersion: VersionTLS12,
},
flags: []string{"-fail-cert-callback"},
shouldFail: true,
expectedError: ":CERT_CB_ERROR:",
expectedLocalError: "remote error: internal error",
},
{
name: "FailCertCallback-Client-TLS13",
config: Config{
MaxVersion: VersionTLS13,
ClientAuth: RequestClientCert,
},
flags: []string{"-fail-cert-callback"},
shouldFail: true,
expectedError: ":CERT_CB_ERROR:",
expectedLocalError: "remote error: internal error",
},
{
testType: serverTest,
name: "FailCertCallback-Server-TLS13",
config: Config{
MaxVersion: VersionTLS13,
},
flags: []string{"-fail-cert-callback"},
shouldFail: true,
expectedError: ":CERT_CB_ERROR:",
expectedLocalError: "remote error: internal error",
},
{
protocol: dtls,
name: "FragmentMessageTypeMismatch-DTLS",
config: Config{
Bugs: ProtocolBugs{
WriteFlightDTLS: func(c *DTLSController, prev, received, next []DTLSMessage, records []DTLSRecordNumberInfo) {
f1 := next[0].Fragment(0, 1)
f2 := next[0].Fragment(1, 1)
f2.Type++
c.WriteFragments([]DTLSFragment{f1, f2})
},
},
},
shouldFail: true,
expectedError: ":FRAGMENT_MISMATCH:",
},
{
protocol: dtls,
name: "FragmentMessageLengthMismatch-DTLS",
config: Config{
Bugs: ProtocolBugs{
WriteFlightDTLS: func(c *DTLSController, prev, received, next []DTLSMessage, records []DTLSRecordNumberInfo) {
f1 := next[0].Fragment(0, 1)
f2 := next[0].Fragment(1, 1)
f2.TotalLength++
c.WriteFragments([]DTLSFragment{f1, f2})
},
},
},
shouldFail: true,
expectedError: ":FRAGMENT_MISMATCH:",
},
{
protocol: dtls,
name: "SplitFragments-Header-DTLS",
config: Config{
Bugs: ProtocolBugs{
SplitFragments: 2,
},
},
shouldFail: true,
expectedError: ":BAD_HANDSHAKE_RECORD:",
},
{
protocol: dtls,
name: "SplitFragments-Boundary-DTLS",
config: Config{
Bugs: ProtocolBugs{
SplitFragments: dtlsMaxRecordHeaderLen,
},
},
shouldFail: true,
expectedError: ":BAD_HANDSHAKE_RECORD:",
},
{
protocol: dtls,
name: "SplitFragments-Body-DTLS",
config: Config{
Bugs: ProtocolBugs{
SplitFragments: dtlsMaxRecordHeaderLen + 1,
},
},
shouldFail: true,
expectedError: ":BAD_HANDSHAKE_RECORD:",
},
{
protocol: dtls,
name: "SendEmptyFragments-DTLS",
config: Config{
Bugs: ProtocolBugs{
SendEmptyFragments: true,
},
},
},
{
testType: serverTest,
protocol: dtls,
name: "SendEmptyFragments-Padded-DTLS",
config: Config{
Bugs: ProtocolBugs{
// Test empty fragments for a message with a
// nice power-of-two length.
PadClientHello: 64,
SendEmptyFragments: true,
},
},
},
{
name: "BadFinished-Client",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
BadFinished: true,
},
},
shouldFail: true,
expectedError: ":DIGEST_CHECK_FAILED:",
},
{
name: "BadFinished-Client-TLS13",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
BadFinished: true,
},
},
shouldFail: true,
expectedError: ":DIGEST_CHECK_FAILED:",
},
{
testType: serverTest,
name: "BadFinished-Server",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
BadFinished: true,
},
},
shouldFail: true,
expectedError: ":DIGEST_CHECK_FAILED:",
},
{
testType: serverTest,
name: "BadFinished-Server-TLS13",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
BadFinished: true,
},
},
shouldFail: true,
expectedError: ":DIGEST_CHECK_FAILED:",
},
{
name: "FalseStart-BadFinished",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
NextProtos: []string{"foo"},
Bugs: ProtocolBugs{
BadFinished: true,
ExpectFalseStart: true,
},
},
flags: []string{
"-false-start",
"-handshake-never-done",
"-advertise-alpn", "\x03foo",
"-expect-alpn", "foo",
},
shimWritesFirst: true,
shouldFail: true,
expectedError: ":DIGEST_CHECK_FAILED:",
},
{
name: "NoFalseStart-NoALPN",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
Bugs: ProtocolBugs{
ExpectFalseStart: true,
AlertBeforeFalseStartTest: alertAccessDenied,
},
},
flags: []string{
"-false-start",
},
shimWritesFirst: true,
shouldFail: true,
expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
expectedLocalError: "tls: peer did not false start: EOF",
},
{
name: "FalseStart-NoALPNAllowed",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
Bugs: ProtocolBugs{
ExpectFalseStart: true,
},
},
flags: []string{
"-false-start",
"-allow-false-start-without-alpn",
},
shimWritesFirst: true,
},
{
name: "NoFalseStart-NoAEAD",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
NextProtos: []string{"foo"},
Bugs: ProtocolBugs{
ExpectFalseStart: true,
AlertBeforeFalseStartTest: alertAccessDenied,
},
},
flags: []string{
"-false-start",
"-advertise-alpn", "\x03foo",
},
shimWritesFirst: true,
shouldFail: true,
expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
expectedLocalError: "tls: peer did not false start: EOF",
},
{
name: "NoFalseStart-RSA",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
NextProtos: []string{"foo"},
Bugs: ProtocolBugs{
ExpectFalseStart: true,
AlertBeforeFalseStartTest: alertAccessDenied,
},
},
flags: []string{
"-false-start",
"-advertise-alpn", "\x03foo",
},
shimWritesFirst: true,
shouldFail: true,
expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
expectedLocalError: "tls: peer did not false start: EOF",
},
{
protocol: dtls,
name: "SendSplitAlert-Sync",
config: Config{
Bugs: ProtocolBugs{
SendSplitAlert: true,
},
},
},
{
protocol: dtls,
name: "SendSplitAlert-Async",
config: Config{
Bugs: ProtocolBugs{
SendSplitAlert: true,
},
},
flags: []string{"-async"},
},
{
name: "SendEmptyRecords-Pass",
sendEmptyRecords: 32,
},
{
name: "SendEmptyRecords",
sendEmptyRecords: 33,
shouldFail: true,
expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
},
{
name: "SendEmptyRecords-Async",
sendEmptyRecords: 33,
flags: []string{"-async"},
shouldFail: true,
expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
},
{
name: "SendWarningAlerts-Pass",
config: Config{
MaxVersion: VersionTLS12,
},
sendWarningAlerts: 4,
},
{
protocol: dtls,
name: "SendWarningAlerts-DTLS-Pass",
config: Config{
MaxVersion: VersionTLS12,
},
sendWarningAlerts: 4,
},
{
name: "SendWarningAlerts-TLS13",
config: Config{
MaxVersion: VersionTLS13,
},
sendWarningAlerts: 4,
shouldFail: true,
expectedError: ":BAD_ALERT:",
expectedLocalError: "remote error: error decoding message",
},
// Although TLS 1.3 intended to remove warning alerts, it left in
// user_canceled. JDK11 misuses this alert as a post-handshake
// full-duplex signal. As a workaround, skip user_canceled as in
// TLS 1.2, which is consistent with NSS and OpenSSL.
{
name: "SendUserCanceledAlerts-TLS13",
config: Config{
MaxVersion: VersionTLS13,
},
sendUserCanceledAlerts: 4,
},
{
name: "SendUserCanceledAlerts-TooMany-TLS13",
config: Config{
MaxVersion: VersionTLS13,
},
sendUserCanceledAlerts: 5,
shouldFail: true,
expectedError: ":TOO_MANY_WARNING_ALERTS:",
},
{
name: "SendWarningAlerts-TooMany",
config: Config{
MaxVersion: VersionTLS12,
},
sendWarningAlerts: 5,
shouldFail: true,
expectedError: ":TOO_MANY_WARNING_ALERTS:",
},
{
name: "SendWarningAlerts-TooMany-Async",
config: Config{
MaxVersion: VersionTLS12,
},
sendWarningAlerts: 5,
flags: []string{"-async"},
shouldFail: true,
expectedError: ":TOO_MANY_WARNING_ALERTS:",
},
{
name: "SendBogusAlertType",
sendBogusAlertType: true,
shouldFail: true,
expectedError: ":UNKNOWN_ALERT_TYPE:",
expectedLocalError: "remote error: illegal parameter",
},
{
protocol: dtls,
name: "SendBogusAlertType-DTLS",
sendBogusAlertType: true,
shouldFail: true,
expectedError: ":UNKNOWN_ALERT_TYPE:",
expectedLocalError: "remote error: illegal parameter",
},
{
name: "TooManyKeyUpdates",
config: Config{
MaxVersion: VersionTLS13,
},
sendKeyUpdates: 33,
keyUpdateRequest: keyUpdateNotRequested,
shouldFail: true,
expectedError: ":TOO_MANY_KEY_UPDATES:",
},
{
name: "EmptySessionID",
config: Config{
MaxVersion: VersionTLS12,
SessionTicketsDisabled: true,
},
noSessionCache: true,
flags: []string{"-expect-no-session"},
},
{
name: "Unclean-Shutdown",
config: Config{
Bugs: ProtocolBugs{
NoCloseNotify: true,
ExpectCloseNotify: true,
},
},
shimShutsDown: true,
flags: []string{"-check-close-notify"},
shouldFail: true,
expectedError: "Unexpected SSL_shutdown result: -1 != 1",
},
{
name: "Unclean-Shutdown-Ignored",
config: Config{
Bugs: ProtocolBugs{
NoCloseNotify: true,
},
},
shimShutsDown: true,
},
{
name: "Unclean-Shutdown-Alert",
config: Config{
Bugs: ProtocolBugs{
SendAlertOnShutdown: alertDecompressionFailure,
ExpectCloseNotify: true,
},
},
shimShutsDown: true,
flags: []string{"-check-close-notify"},
shouldFail: true,
expectedError: ":SSLV3_ALERT_DECOMPRESSION_FAILURE:",
},
{
name: "LargePlaintext",
config: Config{
Bugs: ProtocolBugs{
SendLargeRecords: true,
},
},
messageLen: maxPlaintext + 1,
shouldFail: true,
expectedError: ":DATA_LENGTH_TOO_LONG:",
expectedLocalError: "remote error: record overflow",
},
{
protocol: dtls,
name: "LargePlaintext-DTLS",
config: Config{
Bugs: ProtocolBugs{
SendLargeRecords: true,
},
},
messageLen: maxPlaintext + 1,
shouldFail: true,
expectedError: ":DATA_LENGTH_TOO_LONG:",
expectedLocalError: "remote error: record overflow",
},
{
name: "LargePlaintext-TLS13-Padded-8192-8192",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
RecordPadding: 8192,
SendLargeRecords: true,
},
},
messageLen: 8192,
},
{
name: "LargePlaintext-TLS13-Padded-8193-8192",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
RecordPadding: 8193,
SendLargeRecords: true,
},
},
messageLen: 8192,
shouldFail: true,
expectedError: ":DATA_LENGTH_TOO_LONG:",
expectedLocalError: "remote error: record overflow",
},
{
name: "LargePlaintext-TLS13-Padded-16383-1",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
RecordPadding: 1,
SendLargeRecords: true,
},
},
messageLen: 16383,
},
{
name: "LargePlaintext-TLS13-Padded-16384-1",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
RecordPadding: 1,
SendLargeRecords: true,
},
},
messageLen: 16384,
shouldFail: true,
expectedError: ":DATA_LENGTH_TOO_LONG:",
expectedLocalError: "remote error: record overflow",
},
{
name: "LargeCiphertext",
config: Config{
Bugs: ProtocolBugs{
SendLargeRecords: true,
},
},
messageLen: maxPlaintext * 2,
shouldFail: true,
expectedError: ":ENCRYPTED_LENGTH_TOO_LONG:",
},
{
protocol: dtls,
name: "LargeCiphertext-DTLS",
config: Config{
Bugs: ProtocolBugs{
SendLargeRecords: true,
},
},
messageLen: maxPlaintext * 2,
// Unlike the other four cases, DTLS drops records which
// are invalid before authentication, so the connection
// does not fail.
expectMessageDropped: true,
},
{
name: "BadHelloRequest-1",
renegotiate: 1,
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
BadHelloRequest: []byte{typeHelloRequest, 0, 0, 1, 1},
},
},
flags: []string{
"-renegotiate-freely",
"-expect-total-renegotiations", "1",
},
shouldFail: true,
expectedError: ":BAD_HELLO_REQUEST:",
},
{
name: "BadHelloRequest-2",
renegotiate: 1,
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
BadHelloRequest: []byte{typeServerKeyExchange, 0, 0, 0},
},
},
flags: []string{
"-renegotiate-freely",
"-expect-total-renegotiations", "1",
},
shouldFail: true,
expectedError: ":BAD_HELLO_REQUEST:",
},
{
testType: serverTest,
name: "SupportTicketsWithSessionID",
config: Config{
MaxVersion: VersionTLS12,
SessionTicketsDisabled: true,
},
resumeConfig: &Config{
MaxVersion: VersionTLS12,
},
resumeSession: true,
},
{
protocol: dtls,
name: "DTLS12-SendExtraFinished",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
SendExtraFinished: true,
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_RECORD:",
expectedLocalError: "remote error: unexpected message",
},
{
protocol: dtls,
name: "DTLS12-SendExtraFinished-Reordered",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
MaxHandshakeRecordLength: 2,
ReorderHandshakeFragments: true,
SendExtraFinished: true,
},
},
shouldFail: true,
expectedError: ":EXCESS_HANDSHAKE_DATA:",
expectedLocalError: "remote error: unexpected message",
},
{
protocol: dtls,
name: "DTLS12-SendExtraFinished-Packed",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
SendExtraFinished: true,
PackHandshakeFragments: 1000,
},
},
shouldFail: true,
expectedError: ":EXCESS_HANDSHAKE_DATA:",
expectedLocalError: "remote error: unexpected message",
},
{
protocol: dtls,
name: "DTLS13-SendExtraFinished",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
SendExtraFinished: true,
},
},
shouldFail: true,
expectedError: ":EXCESS_HANDSHAKE_DATA:",
expectedLocalError: "remote error: unexpected message",
},
{
protocol: dtls,
name: "DTLS13-SendExtraFinished-Reordered",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
MaxHandshakeRecordLength: 2,
ReorderHandshakeFragments: true,
SendExtraFinished: true,
},
},
shouldFail: true,
expectedError: ":EXCESS_HANDSHAKE_DATA:",
expectedLocalError: "remote error: unexpected message",
},
{
protocol: dtls,
name: "DTLS13-SendExtraFinished-Packed",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
SendExtraFinished: true,
PackHandshakeFragments: 1000,
},
},
shouldFail: true,
expectedError: ":EXCESS_HANDSHAKE_DATA:",
expectedLocalError: "remote error: unexpected message",
},
{
protocol: dtls,
testType: serverTest,
name: "DTLS13-SendExtraFinished-AfterAppData",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
SkipImplicitACKRead: true,
WriteFlightDTLS: func(c *DTLSController, prev, received, next []DTLSMessage, records []DTLSRecordNumberInfo) {
if next[len(next)-1].Type != typeFinished {
c.WriteFlight(next)
return
}
// Complete the handshake.
c.WriteFlight(next)
c.ReadACK(c.InEpoch())
// Send some application data. The shim is now on epoch 3.
msg := []byte("hello")
c.WriteAppData(c.OutEpoch(), msg)
c.ReadAppData(c.InEpoch(), expectedReply(msg))
// The shim is still accepting data from epoch 2, so it can
// ACK a retransmit if needed, but it should not accept new
// messages at epoch three.
extraFinished := next[len(next)-1]
extraFinished.Sequence++
c.WriteFlight([]DTLSMessage{extraFinished})
},
},
},
shouldFail: true,
expectedError: ":EXCESS_HANDSHAKE_DATA:",
expectedLocalError: "remote error: unexpected message",
// Disable tickets on the shim to avoid NewSessionTicket
// interfering with the test callback.
flags: []string{"-no-ticket"},
},
{
testType: serverTest,
name: "V2ClientHello-EmptyRecordPrefix",
config: Config{
// Choose a cipher suite that does not involve
// elliptic curves, so no extensions are
// involved.
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
Bugs: ProtocolBugs{
SendV2ClientHello: true,
},
},
sendPrefix: string([]byte{
byte(recordTypeHandshake),
3, 1, // version
0, 0, // length
}),
// A no-op empty record may not be sent before V2ClientHello.
shouldFail: true,
expectedError: ":WRONG_VERSION_NUMBER:",
},
{
testType: serverTest,
name: "V2ClientHello-WarningAlertPrefix",
config: Config{
// Choose a cipher suite that does not involve
// elliptic curves, so no extensions are
// involved.
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
Bugs: ProtocolBugs{
SendV2ClientHello: true,
},
},
sendPrefix: string([]byte{
byte(recordTypeAlert),
3, 1, // version
0, 2, // length
alertLevelWarning, byte(alertDecompressionFailure),
}),
// A no-op warning alert may not be sent before V2ClientHello.
shouldFail: true,
expectedError: ":WRONG_VERSION_NUMBER:",
},
{
name: "SendSNIWarningAlert",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
SendSNIWarningAlert: true,
},
},
},
{
testType: serverTest,
name: "ExtraCompressionMethods-TLS12",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6},
},
},
},
{
testType: serverTest,
name: "ExtraCompressionMethods-TLS13",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6},
},
},
shouldFail: true,
expectedError: ":INVALID_COMPRESSION_LIST:",
expectedLocalError: "remote error: illegal parameter",
},
{
testType: serverTest,
name: "NoNullCompression-TLS12",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6},
},
},
shouldFail: true,
expectedError: ":INVALID_COMPRESSION_LIST:",
expectedLocalError: "remote error: illegal parameter",
},
{
testType: serverTest,
name: "NoNullCompression-TLS13",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6},
},
},
shouldFail: true,
expectedError: ":INVALID_COMPRESSION_LIST:",
expectedLocalError: "remote error: illegal parameter",
},
// Test that the client rejects invalid compression methods
// from the server.
{
testType: clientTest,
name: "InvalidCompressionMethod",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
SendCompressionMethod: 1,
},
},
shouldFail: true,
expectedError: ":UNSUPPORTED_COMPRESSION_ALGORITHM:",
expectedLocalError: "remote error: illegal parameter",
},
{
testType: clientTest,
name: "TLS13-InvalidCompressionMethod",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
SendCompressionMethod: 1,
},
},
shouldFail: true,
expectedError: ":DECODE_ERROR:",
},
{
testType: clientTest,
name: "TLS13-HRR-InvalidCompressionMethod",
config: Config{
MaxVersion: VersionTLS13,
CurvePreferences: []CurveID{CurveP384},
Bugs: ProtocolBugs{
SendCompressionMethod: 1,
},
},
shouldFail: true,
expectedError: ":DECODE_ERROR:",
expectedLocalError: "remote error: error decoding message",
},
{
name: "GREASE-Client-TLS12",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
ExpectGREASE: true,
},
},
flags: []string{"-enable-grease"},
},
{
name: "GREASE-Client-TLS13",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
ExpectGREASE: true,
},
},
flags: []string{"-enable-grease"},
},
{
testType: serverTest,
name: "GREASE-Server-TLS13",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
// TLS 1.3 servers are expected to
// always enable GREASE. TLS 1.3 is new,
// so there is no existing ecosystem to
// worry about.
ExpectGREASE: true,
},
},
},
{
// Test the TLS 1.2 server so there is a large
// unencrypted certificate as well as application data.
testType: serverTest,
name: "MaxSendFragment-TLS12",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
MaxReceivePlaintext: 512,
},
},
messageLen: 1024,
flags: []string{
"-max-send-fragment", "512",
"-read-size", "1024",
},
},
{
// Test the TLS 1.2 server so there is a large
// unencrypted certificate as well as application data.
testType: serverTest,
name: "MaxSendFragment-TLS12-TooLarge",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
// Ensure that some of the records are
// 512.
MaxReceivePlaintext: 511,
},
},
messageLen: 1024,
flags: []string{
"-max-send-fragment", "512",
"-read-size", "1024",
},
shouldFail: true,
expectedLocalError: "local error: record overflow",
},
{
// Test the TLS 1.3 server so there is a large encrypted
// certificate as well as application data.
testType: serverTest,
name: "MaxSendFragment-TLS13",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
MaxReceivePlaintext: 512,
ExpectPackedEncryptedHandshake: 512,
},
},
messageLen: 1024,
flags: []string{
"-max-send-fragment", "512",
"-read-size", "1024",
},
},
{
// Test the TLS 1.3 server so there is a large encrypted
// certificate as well as application data.
testType: serverTest,
name: "MaxSendFragment-TLS13-TooLarge",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
// Ensure that some of the records are
// 512.
MaxReceivePlaintext: 511,
},
},
messageLen: 1024,
flags: []string{
"-max-send-fragment", "512",
"-read-size", "1024",
},
shouldFail: true,
expectedLocalError: "local error: record overflow",
},
{
// Test that handshake data is tightly packed in TLS 1.3.
testType: serverTest,
name: "PackedEncryptedHandshake-TLS13",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
ExpectPackedEncryptedHandshake: 16384,
},
},
},
{
// Test that DTLS can handle multiple application data
// records in a single packet.
protocol: dtls,
name: "SplitAndPackAppData-DTLS",
config: Config{
Bugs: ProtocolBugs{
SplitAndPackAppData: true,
},
},
},
{
protocol: dtls,
name: "SplitAndPackAppData-DTLS-Async",
config: Config{
Bugs: ProtocolBugs{
SplitAndPackAppData: true,
},
},
flags: []string{"-async"},
},
{
// DTLS 1.2 allows up to a 255-byte HelloVerifyRequest cookie, which
// is the largest encodable value.
protocol: dtls,
name: "DTLS-HelloVerifyRequest-255",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
HelloVerifyRequestCookieLength: 255,
},
},
},
{
// DTLS 1.2 allows up to a 0-byte HelloVerifyRequest cookie, which
// was probably a mistake in the spec but test that it works
// nonetheless.
protocol: dtls,
name: "DTLS-HelloVerifyRequest-0",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
EmptyHelloVerifyRequestCookie: true,
},
},
},
}
testCases = append(testCases, basicTests...)
// Test that very large messages can be received.
cert := rsaCertificate
for i := 0; i < 50; i++ {
cert.Certificate = append(cert.Certificate, cert.Certificate[0])
}
testCases = append(testCases, testCase{
name: "LargeMessage",
config: Config{
Credential: &cert,
},
})
testCases = append(testCases, testCase{
protocol: dtls,
name: "LargeMessage-DTLS",
config: Config{
Credential: &cert,
},
})
// They are rejected if the maximum certificate chain length is capped.
testCases = append(testCases, testCase{
name: "LargeMessage-Reject",
config: Config{
Credential: &cert,
},
flags: []string{"-max-cert-list", "16384"},
shouldFail: true,
expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
})
testCases = append(testCases, testCase{
protocol: dtls,
name: "LargeMessage-Reject-DTLS",
config: Config{
Credential: &cert,
},
flags: []string{"-max-cert-list", "16384"},
shouldFail: true,
expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
})
// Servers echoing the TLS 1.3 compatibility mode session ID should be
// rejected.
testCases = append(testCases, testCase{
name: "EchoTLS13CompatibilitySessionID",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
EchoSessionIDInFullHandshake: true,
},
},
shouldFail: true,
expectedError: ":SERVER_ECHOED_INVALID_SESSION_ID:",
expectedLocalError: "remote error: illegal parameter",
})
// Servers should reject QUIC client hellos that have a legacy
// session ID.
testCases = append(testCases, testCase{
name: "QUICCompatibilityMode",
testType: serverTest,
protocol: quic,
config: Config{
MinVersion: VersionTLS13,
Bugs: ProtocolBugs{
CompatModeWithQUIC: true,
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_COMPATIBILITY_MODE:",
})
// Clients should reject DTLS 1.3 ServerHellos that echo the legacy
// session ID.
testCases = append(testCases, testCase{
protocol: dtls,
name: "DTLS13CompatibilityMode-EchoSessionID",
resumeSession: true,
config: Config{
MaxVersion: VersionTLS12,
},
resumeConfig: &Config{
MinVersion: VersionTLS13,
Bugs: ProtocolBugs{
DTLS13EchoSessionID: true,
},
},
shouldFail: true,
expectedError: ":DECODE_ERROR:",
})
// DTLS 1.3 should work with record headers that don't set the
// length bit or that use the short sequence number format.
testCases = append(testCases, testCase{
testType: clientTest,
protocol: dtls,
name: "DTLS13RecordHeader-NoLength-Client",
config: Config{
MinVersion: VersionTLS13,
DTLSRecordHeaderOmitLength: true,
},
})
testCases = append(testCases, testCase{
testType: serverTest,
protocol: dtls,
name: "DTLS13RecordHeader-NoLength-Server",
config: Config{
MinVersion: VersionTLS13,
DTLSRecordHeaderOmitLength: true,
},
})
testCases = append(testCases, testCase{
testType: clientTest,
protocol: dtls,
name: "DTLS13RecordHeader-ShortSeqNums-Client",
config: Config{
MinVersion: VersionTLS13,
DTLSUseShortSeqNums: true,
},
})
testCases = append(testCases, testCase{
testType: serverTest,
protocol: dtls,
name: "DTLS13RecordHeader-ShortSeqNums-Server",
config: Config{
MinVersion: VersionTLS13,
DTLSUseShortSeqNums: true,
},
})
testCases = append(testCases, testCase{
protocol: dtls,
name: "DTLS13RecordHeader-OldHeader",
config: Config{
MinVersion: VersionTLS13,
Bugs: ProtocolBugs{
DTLSUsePlaintextRecordHeader: true,
},
},
expectMessageDropped: true,
})
testCases = append(testCases, testCase{
protocol: dtls,
name: "DTLS13RecordHeader-CIDBit",
config: Config{
MinVersion: VersionTLS13,
Bugs: ProtocolBugs{
DTLS13RecordHeaderSetCIDBit: true,
},
},
expectMessageDropped: true,
})
testCases = append(testCases, testCase{
protocol: dtls,
name: "DTLS13-MessageCallback-Client",
config: Config{
MaxVersion: VersionTLS13,
MinVersion: VersionTLS13,
},
flags: []string{
"-expect-msg-callback",
`write hs 1
read hs 2
read hs 8
read hs 11
read hs 15
read hs 20
write hs 20
read ack
read hs 4
read hs 4
read alert 1 0
`,
},
})
testCases = append(testCases, testCase{
testType: serverTest,
protocol: dtls,
name: "DTLS13-MessageCallback-Server",
config: Config{
MaxVersion: VersionTLS13,
MinVersion: VersionTLS13,
},
flags: []string{
"-expect-msg-callback",
`read hs 1
write hs 2
write hs 8
write hs 11
write hs 15
write hs 20
read hs 20
write ack
write hs 4
write hs 4
read ack
read ack
read alert 1 0
`,
},
})
}