Add TLS 1.3 1-RTT. This adds the machinery for doing TLS 1.3 1RTT. Change-Id: I736921ffe9dc6f6e64a08a836df6bb166d20f504 Reviewed-on: https://boringssl-review.googlesource.com/8720 Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc index 0bdfc94..d1aadb8 100644 --- a/ssl/test/bssl_shim.cc +++ b/ssl/test/bssl_shim.cc
@@ -1045,7 +1045,9 @@ if (expect_handshake_done && !config->is_server) { bool expect_new_session = !config->expect_no_session && - (!SSL_session_reused(ssl) || config->expect_ticket_renewal); + (!SSL_session_reused(ssl) || config->expect_ticket_renewal) && + /* TODO(svaldez): Implement Session Resumption. */ + SSL_version(ssl) != TLS1_3_VERSION; if (expect_new_session != GetTestState(ssl)->got_new_session) { fprintf(stderr, "new session was%s cached, but we expected the opposite\n", @@ -1264,7 +1266,8 @@ if (config->no_ssl3) { SSL_set_options(ssl.get(), SSL_OP_NO_SSLv3); } - if (!config->expected_channel_id.empty()) { + if (!config->expected_channel_id.empty() || + config->enable_channel_id) { SSL_enable_tls_channel_id(ssl.get()); } if (!config->send_channel_id.empty()) {
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go index 5fd3436..0ae360a 100644 --- a/ssl/test/runner/common.go +++ b/ssl/test/runner/common.go
@@ -18,8 +18,7 @@ "time" ) -// TODO(davidben): Flip this to true when the C code lands. -const enableTLS13Handshake = false +const enableTLS13Handshake = true const ( VersionSSL30 = 0x0300 @@ -919,6 +918,43 @@ // IgnoreSignatureVersionChecks, if true, causes all signature // algorithms to be enabled at all TLS versions. IgnoreSignatureVersionChecks bool + + // NegotiateRenegotiationInfoAtAllVersions, if true, causes + // Renegotiation Info to be negotiated at all versions. + NegotiateRenegotiationInfoAtAllVersions bool + + // NegotiateChannelIDAtAllVersions, if true, causes Channel ID to be + // negotiated at all versions. + NegotiateChannelIDAtAllVersions bool + + // NegotiateNPNAtAllVersions, if true, causes NPN to be negotiated at + // all versions. + NegotiateNPNAtAllVersions bool + + // NegotiateEMSAtAllVersions, if true, causes EMS to be negotiated at + // all versions. + NegotiateEMSAtAllVersions bool + + // AdvertiseTicketExtension, if true, causes the ticket extension to be + // advertised in server extensions + AdvertiseTicketExtension bool + + // MissingKeyShare, if true, causes the TLS 1.3 implementation to skip + // sending a key_share extension and use the zero ECDHE secret + // instead. + MissingKeyShare bool + + // DuplicateKeyShares, if true, causes the TLS 1.3 client to send two + // copies of each KeyShareEntry. + DuplicateKeyShares bool + + // EmptyEncryptedExtensions, if true, causes the TLS 1.3 server to + // emit an empty EncryptedExtensions block. + EmptyEncryptedExtensions bool + + // EncryptedExtensionsWithKeyShare, if true, causes the TLS 1.3 server to + // include the KeyShare extension in the EncryptedExtensions block. + EncryptedExtensionsWithKeyShare bool } func (c *Config) serverInit() {
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go index a2ea50e..3d9fa5a 100644 --- a/ssl/test/runner/handshake_client.go +++ b/ssl/test/runner/handshake_client.go
@@ -133,6 +133,14 @@ keyExchange: publicKey, }) keyShares[curveID] = curve + + if c.config.Bugs.DuplicateKeyShares { + hello.keyShares = append(hello.keyShares, hello.keyShares[len(hello.keyShares)-1]) + } + } + + if c.config.Bugs.MissingKeyShare { + hello.keyShares = nil } } @@ -477,7 +485,7 @@ // Resolve ECDHE and compute the handshake secret. var ecdheSecret []byte - if hs.suite.flags&suiteECDHE != 0 { + if hs.suite.flags&suiteECDHE != 0 && !c.config.Bugs.MissingKeyShare { if !hs.serverHello.hasKeyShare { c.sendAlert(alertMissingExtension) return errors.New("tls: server omitted the key share extension") @@ -1014,6 +1022,10 @@ return errors.New("tls: server advertised extended master secret over TLS 1.3") } + if serverExtensions.ticketSupported && c.vers >= VersionTLS13 && enableTLS13Handshake { + return errors.New("tls: server advertised ticket extension over TLS 1.3") + } + if serverExtensions.srtpProtectionProfile != 0 { if serverExtensions.srtpMasterKeyIdentifier != "" { return errors.New("tls: server selected SRTP MKI value")
diff --git a/ssl/test/runner/handshake_messages.go b/ssl/test/runner/handshake_messages.go index 6d0f920..376d88c 100644 --- a/ssl/test/runner/handshake_messages.go +++ b/ssl/test/runner/handshake_messages.go
@@ -847,6 +847,7 @@ type encryptedExtensionsMsg struct { raw []byte extensions serverExtensions + empty bool } func (m *encryptedExtensionsMsg) marshal() []byte { @@ -857,8 +858,10 @@ encryptedExtensionsMsg := newByteBuilder() encryptedExtensionsMsg.addU8(typeEncryptedExtensions) encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed() - extensions := encryptedExtensions.addU16LengthPrefixed() - m.extensions.marshal(extensions, VersionTLS13) + if !m.empty { + extensions := encryptedExtensions.addU16LengthPrefixed() + m.extensions.marshal(extensions, VersionTLS13) + } m.raw = encryptedExtensionsMsg.finish() return m.raw @@ -902,6 +905,8 @@ sctList []byte customExtension string npnLast bool + hasKeyShare bool + keyShare keyShareEntry } func (m *serverExtensions) marshal(extensions *byteBuilder, version uint16) { @@ -999,6 +1004,13 @@ npn.addBytes([]byte(v)) } } + if m.hasKeyShare { + extensions.addU16(extensionKeyShare) + keyShare := extensions.addU16LengthPrefixed() + keyShare.addU16(uint16(m.keyShare.group)) + keyExchange := keyShare.addU16LengthPrefixed() + keyExchange.addBytes(m.keyShare.keyExchange) + } } func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go index d4dba75..24d6425 100644 --- a/ssl/test/runner/handshake_server.go +++ b/ssl/test/runner/handshake_server.go
@@ -279,6 +279,7 @@ // Prepare an EncryptedExtensions message, but do not send it yet. encryptedExtensions := new(encryptedExtensionsMsg) + encryptedExtensions.empty = config.Bugs.EmptyEncryptedExtensions if err := hs.processClientExtensions(&encryptedExtensions.extensions); err != nil { return err } @@ -341,7 +342,7 @@ // Resolve ECDHE and compute the handshake secret. var ecdheSecret []byte - if hs.suite.flags&suiteECDHE != 0 { + if hs.suite.flags&suiteECDHE != 0 && !config.Bugs.MissingKeyShare { // Look for the key share corresponding to our selected curve. var selectedKeyShare *keyShareEntry for i := range hs.clientHello.keyShares { @@ -384,6 +385,14 @@ group: curveID, keyExchange: publicKey, } + + if config.Bugs.EncryptedExtensionsWithKeyShare { + encryptedExtensions.extensions.hasKeyShare = true + encryptedExtensions.extensions.keyShare = keyShareEntry{ + group: curveID, + keyExchange: publicKey, + } + } } else { ecdheSecret = hs.finishedHash.zeroSecret() } @@ -700,7 +709,7 @@ config := hs.c.config c := hs.c - if c.vers < VersionTLS13 || !enableTLS13Handshake { + if c.vers < VersionTLS13 || config.Bugs.NegotiateRenegotiationInfoAtAllVersions || !enableTLS13Handshake { if !bytes.Equal(c.clientVerify, hs.clientHello.secureRenegotiation) { c.sendAlert(alertHandshakeFailure) return errors.New("tls: renegotiation mismatch") @@ -751,7 +760,7 @@ } } - if c.vers < VersionTLS13 || !enableTLS13Handshake { + if c.vers < VersionTLS13 || config.Bugs.NegotiateNPNAtAllVersions || !enableTLS13Handshake { if len(hs.clientHello.alpnProtocols) == 0 || c.config.Bugs.NegotiateALPNAndNPN { // Although sending an empty NPN extension is reasonable, Firefox has // had a bug around this. Best to send nothing at all if @@ -763,9 +772,13 @@ serverExtensions.npnLast = config.Bugs.SwapNPNAndALPN } } + } + if c.vers < VersionTLS13 || config.Bugs.NegotiateEMSAtAllVersions || !enableTLS13Handshake { serverExtensions.extendedMasterSecret = c.vers >= VersionTLS10 && hs.clientHello.extendedMasterSecret && !c.config.Bugs.NoExtendedMasterSecret + } + if c.vers < VersionTLS13 || config.Bugs.NegotiateChannelIDAtAllVersions || !enableTLS13Handshake { if hs.clientHello.channelIDSupported && config.RequestChannelID { serverExtensions.channelIDRequested = true } @@ -795,6 +808,10 @@ } serverExtensions.customExtension = config.Bugs.CustomExtension + if c.config.Bugs.AdvertiseTicketExtension { + serverExtensions.ticketSupported = true + } + return nil }
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index a0edf77..e5faae5 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go
@@ -941,8 +941,7 @@ {"TLS1", VersionTLS10, "-no-tls1", true}, {"TLS11", VersionTLS11, "-no-tls11", false}, {"TLS12", VersionTLS12, "-no-tls12", true}, - // TODO(nharper): Once we have a real implementation of TLS 1.3, update the name here. - {"FakeTLS13", VersionTLS13, "-no-tls13", false}, + {"TLS13", VersionTLS13, "-no-tls13", false}, } var testCipherSuites = []struct { @@ -1340,7 +1339,6 @@ { name: "CertMismatchRSA", config: Config{ - // TODO(davidben): Add a TLS 1.3 version of this test. MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, Certificates: []Certificate{ecdsaP256Certificate}, @@ -1352,9 +1350,21 @@ expectedError: ":WRONG_CERTIFICATE_TYPE:", }, { + name: "CertMismatchRSA-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + Certificates: []Certificate{ecdsaP256Certificate}, + Bugs: ProtocolBugs{ + SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + }, + }, + shouldFail: true, + expectedError: ":WRONG_CERTIFICATE_TYPE:", + }, + { name: "CertMismatchECDSA", config: Config{ - // TODO(davidben): Add a TLS 1.3 version of this test. MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, Certificates: []Certificate{rsaCertificate}, @@ -1366,9 +1376,21 @@ expectedError: ":WRONG_CERTIFICATE_TYPE:", }, { + name: "CertMismatchECDSA-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + Certificates: []Certificate{rsaCertificate}, + Bugs: ProtocolBugs{ + SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }, + }, + shouldFail: true, + expectedError: ":WRONG_CERTIFICATE_TYPE:", + }, + { name: "EmptyCertificateList", config: Config{ - // TODO(davidben): Add a TLS 1.3 version of this test. MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, Bugs: ProtocolBugs{ @@ -1694,7 +1716,6 @@ { name: "BadFinished-Client", config: Config{ - // TODO(davidben): Add a TLS 1.3 version of this. MaxVersion: VersionTLS12, Bugs: ProtocolBugs{ BadFinished: true, @@ -1704,10 +1725,20 @@ 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{ - // TODO(davidben): Add a TLS 1.3 version of this. MaxVersion: VersionTLS12, Bugs: ProtocolBugs{ BadFinished: true, @@ -1717,6 +1748,18 @@ 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, @@ -2182,7 +2225,6 @@ testCases = append(testCases, testCase{ name: "NoSharedCipher", config: Config{ - // TODO(davidben): Add a TLS 1.3 version of this test. MaxVersion: VersionTLS12, CipherSuites: []uint16{}, }, @@ -2191,6 +2233,16 @@ }) testCases = append(testCases, testCase{ + name: "NoSharedCipher-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + CipherSuites: []uint16{}, + }, + shouldFail: true, + expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:", + }) + + testCases = append(testCases, testCase{ name: "UnsupportedCipherSuite", config: Config{ MaxVersion: VersionTLS12, @@ -2509,9 +2561,6 @@ } } - // TODO(davidben): These tests will need TLS 1.3 versions when the - // handshake is separate. - testCases = append(testCases, testCase{ name: "NoClientCertificate", config: Config{ @@ -2523,6 +2572,16 @@ }) testCases = append(testCases, testCase{ + name: "NoClientCertificate-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + ClientAuth: RequireAnyClientCert, + }, + shouldFail: true, + expectedLocalError: "client didn't provide a certificate", + }) + + testCases = append(testCases, testCase{ testType: serverTest, name: "RequireAnyClientCertificate", config: Config{ @@ -2535,6 +2594,17 @@ testCases = append(testCases, testCase{ testType: serverTest, + name: "RequireAnyClientCertificate-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + }, + flags: []string{"-require-any-client-certificate"}, + shouldFail: true, + expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", + }) + + testCases = append(testCases, testCase{ + testType: serverTest, name: "RequireAnyClientCertificate-SSL3", config: Config{ MaxVersion: VersionSSL30, @@ -2559,6 +2629,21 @@ expectedError: ":UNEXPECTED_MESSAGE:", }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "SkipClientCertificate-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SkipClientCertificate: true, + }, + }, + // Setting SSL_VERIFY_PEER allows anonymous clients. + flags: []string{"-verify-peer"}, + shouldFail: true, + expectedError: ":UNEXPECTED_MESSAGE:", + }) + // Client auth is only legal in certificate-based ciphers. testCases = append(testCases, testCase{ testType: clientTest, @@ -2616,10 +2701,8 @@ for _, with := range []bool{false, true} { prefix := "No" - var flags []string if with { prefix = "" - flags = []string{expectEMSFlag} } for _, isClient := range []bool{false, true} { @@ -2630,10 +2713,14 @@ testType = clientTest } - // TODO(davidben): Once the new TLS 1.3 handshake is in, - // test that the extension is irrelevant, but the API - // acts as if it is enabled. for _, ver := range tlsVersions { + // In TLS 1.3, the extension is irrelevant and + // always reports as enabled. + var flags []string + if with || ver.version >= VersionTLS13 { + flags = []string{expectEMSFlag} + } + test := testCase{ testType: testType, name: prefix + "ExtendedMasterSecret-" + ver.name + suffix, @@ -2784,9 +2871,6 @@ // Basic handshake, with resumption. Client and server, // session ID and session ticket. - // - // TODO(davidben): Add TLS 1.3 tests for all of its different handshake - // shapes. tests = append(tests, testCase{ name: "Basic-Client", config: Config{ @@ -2862,9 +2946,22 @@ resumeSession: true, }) + // TLS 1.3 basic handshake shapes. + tests = append(tests, testCase{ + name: "TLS13-1RTT-Client", + config: Config{ + MaxVersion: VersionTLS13, + }, + }) + tests = append(tests, testCase{ + testType: serverTest, + name: "TLS13-1RTT-Server", + config: Config{ + MaxVersion: VersionTLS13, + }, + }) + // TLS client auth. - // - // TODO(davidben): Add TLS 1.3 client auth tests. tests = append(tests, testCase{ testType: clientTest, name: "ClientAuth-NoCertificate-Client", @@ -2900,6 +2997,23 @@ // Setting SSL_VERIFY_PEER allows anonymous clients. flags: []string{"-verify-peer"}, }) + tests = append(tests, testCase{ + testType: clientTest, + name: "ClientAuth-NoCertificate-Client-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + ClientAuth: RequestClientCert, + }, + }) + tests = append(tests, testCase{ + testType: serverTest, + name: "ClientAuth-NoCertificate-Server-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + }, + // Setting SSL_VERIFY_PEER allows anonymous clients. + flags: []string{"-verify-peer"}, + }) } tests = append(tests, testCase{ testType: clientTest, @@ -2915,6 +3029,18 @@ }) tests = append(tests, testCase{ testType: clientTest, + name: "ClientAuth-RSA-Client-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + ClientAuth: RequireAnyClientCert, + }, + flags: []string{ + "-cert-file", path.Join(*resourceDir, rsaCertificateFile), + "-key-file", path.Join(*resourceDir, rsaKeyFile), + }, + }) + tests = append(tests, testCase{ + testType: clientTest, name: "ClientAuth-ECDSA-Client", config: Config{ MaxVersion: VersionTLS12, @@ -2927,6 +3053,18 @@ }) tests = append(tests, testCase{ testType: clientTest, + name: "ClientAuth-ECDSA-Client-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + ClientAuth: RequireAnyClientCert, + }, + flags: []string{ + "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), + "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), + }, + }) + tests = append(tests, testCase{ + testType: clientTest, name: "ClientAuth-NoCertificate-OldCallback", config: Config{ MaxVersion: VersionTLS12, @@ -2936,6 +3074,15 @@ }) tests = append(tests, testCase{ testType: clientTest, + name: "ClientAuth-NoCertificate-OldCallback-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + ClientAuth: RequestClientCert, + }, + flags: []string{"-use-old-client-cert-callback"}, + }) + tests = append(tests, testCase{ + testType: clientTest, name: "ClientAuth-OldCallback", config: Config{ MaxVersion: VersionTLS12, @@ -2948,6 +3095,19 @@ }, }) tests = append(tests, testCase{ + testType: clientTest, + name: "ClientAuth-OldCallback-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + ClientAuth: RequireAnyClientCert, + }, + flags: []string{ + "-cert-file", path.Join(*resourceDir, rsaCertificateFile), + "-key-file", path.Join(*resourceDir, rsaKeyFile), + "-use-old-client-cert-callback", + }, + }) + tests = append(tests, testCase{ testType: serverTest, name: "ClientAuth-Server", config: Config{ @@ -2956,10 +3116,17 @@ }, flags: []string{"-require-any-client-certificate"}, }) + tests = append(tests, testCase{ + testType: serverTest, + name: "ClientAuth-Server-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + Certificates: []Certificate{rsaCertificate}, + }, + flags: []string{"-require-any-client-certificate"}, + }) // Test each key exchange on the server side for async keys. - // - // TODO(davidben): Add TLS 1.3 versions of these. tests = append(tests, testCase{ testType: serverTest, name: "Basic-Server-RSA", @@ -3068,42 +3235,45 @@ }) // Certificate verification tests. - // - // TODO(davidben): Test the TLS 1.3 version. - tests = append(tests, testCase{ - testType: clientTest, - name: "CertificateVerificationSucceed", - config: Config{ - MaxVersion: VersionTLS12, - }, - flags: []string{ - "-verify-peer", - }, - }) - tests = append(tests, testCase{ - testType: clientTest, - name: "CertificateVerificationFail", - config: Config{ - MaxVersion: VersionTLS12, - }, - flags: []string{ - "-verify-fail", - "-verify-peer", - }, - shouldFail: true, - expectedError: ":CERTIFICATE_VERIFY_FAILED:", - }) - tests = append(tests, testCase{ - testType: clientTest, - name: "CertificateVerificationSoftFail", - config: Config{ - MaxVersion: VersionTLS12, - }, - flags: []string{ - "-verify-fail", - "-expect-verify-result", - }, - }) + for _, vers := range tlsVersions { + if config.protocol == dtls && !vers.hasDTLS { + continue + } + tests = append(tests, testCase{ + testType: clientTest, + name: "CertificateVerificationSucceed-" + vers.name, + config: Config{ + MaxVersion: vers.version, + }, + flags: []string{ + "-verify-peer", + }, + }) + tests = append(tests, testCase{ + testType: clientTest, + name: "CertificateVerificationFail-" + vers.name, + config: Config{ + MaxVersion: vers.version, + }, + flags: []string{ + "-verify-fail", + "-verify-peer", + }, + shouldFail: true, + expectedError: ":CERTIFICATE_VERIFY_FAILED:", + }) + tests = append(tests, testCase{ + testType: clientTest, + name: "CertificateVerificationSoftFail-" + vers.name, + config: Config{ + MaxVersion: vers.version, + }, + flags: []string{ + "-verify-fail", + "-expect-verify-result", + }, + }) + } if config.protocol == tls { tests = append(tests, testCase{ @@ -3391,15 +3561,13 @@ func addDDoSCallbackTests() { // DDoS callback. - + // TODO(davidben): Implement DDoS resumption tests for TLS 1.3. for _, resume := range []bool{false, true} { suffix := "Resume" if resume { suffix = "No" + suffix } - // TODO(davidben): Test TLS 1.3's version of the DDoS callback. - testCases = append(testCases, testCase{ testType: serverTest, name: "Server-DDoS-OK-" + suffix, @@ -3409,6 +3577,17 @@ flags: []string{"-install-ddos-callback"}, resumeSession: resume, }) + if !resume { + testCases = append(testCases, testCase{ + testType: serverTest, + name: "Server-DDoS-OK-" + suffix + "-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + }, + flags: []string{"-install-ddos-callback"}, + resumeSession: resume, + }) + } failFlag := "-fail-ddos-callback" if resume { @@ -3425,6 +3604,19 @@ shouldFail: true, expectedError: ":CONNECTION_REJECTED:", }) + if !resume { + testCases = append(testCases, testCase{ + testType: serverTest, + name: "Server-DDoS-Reject-" + suffix + "-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + }, + flags: []string{"-install-ddos-callback", failFlag}, + resumeSession: resume, + shouldFail: true, + expectedError: ":CONNECTION_REJECTED:", + }) + } } } @@ -4228,6 +4420,95 @@ }, }, }) + + // Test that illegal extensions in TLS 1.3 are rejected by the client if + // in ServerHello. + testCases = append(testCases, testCase{ + name: "NPN-Forbidden-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + NextProtos: []string{"foo"}, + Bugs: ProtocolBugs{ + NegotiateNPNAtAllVersions: true, + }, + }, + flags: []string{"-select-next-proto", "foo"}, + shouldFail: true, + expectedError: ":ERROR_PARSING_EXTENSION:", + }) + testCases = append(testCases, testCase{ + name: "EMS-Forbidden-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + NegotiateEMSAtAllVersions: true, + }, + }, + shouldFail: true, + expectedError: ":ERROR_PARSING_EXTENSION:", + }) + testCases = append(testCases, testCase{ + name: "RenegotiationInfo-Forbidden-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + NegotiateRenegotiationInfoAtAllVersions: true, + }, + }, + shouldFail: true, + expectedError: ":ERROR_PARSING_EXTENSION:", + }) + testCases = append(testCases, testCase{ + name: "ChannelID-Forbidden-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + RequestChannelID: true, + Bugs: ProtocolBugs{ + NegotiateChannelIDAtAllVersions: true, + }, + }, + flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)}, + shouldFail: true, + expectedError: ":ERROR_PARSING_EXTENSION:", + }) + testCases = append(testCases, testCase{ + name: "Ticket-Forbidden-TLS13", + config: Config{ + MaxVersion: VersionTLS12, + }, + resumeConfig: &Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + AdvertiseTicketExtension: true, + }, + }, + resumeSession: true, + shouldFail: true, + expectedError: ":ERROR_PARSING_EXTENSION:", + }) + + // Test that illegal extensions in TLS 1.3 are declined by the server if + // offered in ClientHello. The runner's server will fail if this occurs, + // so we exercise the offering path. (EMS and Renegotiation Info are + // implicit in every test.) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "ChannelID-Declined-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + ChannelID: channelIDKey, + }, + flags: []string{"-enable-channel-id"}, + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "NPN-Server", + config: Config{ + MaxVersion: VersionTLS13, + NextProtos: []string{"bar"}, + }, + flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"}, + }) } func addResumptionVersionTests() { @@ -4636,17 +4917,21 @@ }) // Renegotiation is forbidden in TLS 1.3. + // + // TODO(davidben): This test current asserts that we ignore + // HelloRequests, but we actually should hard reject them. Fix this + // test once we actually parse post-handshake messages. testCases = append(testCases, testCase{ name: "Renegotiate-Client-TLS13", config: Config{ MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendHelloRequestBeforeEveryAppDataRecord: true, + }, }, - renegotiate: 1, flags: []string{ "-renegotiate-freely", }, - shouldFail: true, - expectedError: ":NO_RENEGOTIATION:", }) // Stray HelloRequests during the handshake are forbidden in TLS 1.3. @@ -4948,8 +5233,6 @@ } // Test that algorithm selection takes the key type into account. - // - // TODO(davidben): Test this in TLS 1.3. testCases = append(testCases, testCase{ name: "ClientAuth-SignatureType", config: Config{ @@ -4969,6 +5252,25 @@ }) testCases = append(testCases, testCase{ + name: "ClientAuth-SignatureType-TLS13", + config: Config{ + ClientAuth: RequireAnyClientCert, + MaxVersion: VersionTLS13, + VerifySignatureAlgorithms: []signatureAlgorithm{ + signatureECDSAWithP521AndSHA512, + signatureRSAPKCS1WithSHA384, + signatureRSAPSSWithSHA384, + signatureECDSAWithSHA1, + }, + }, + flags: []string{ + "-cert-file", path.Join(*resourceDir, rsaCertificateFile), + "-key-file", path.Join(*resourceDir, rsaKeyFile), + }, + expectedPeerSignatureAlgorithm: signatureRSAPSSWithSHA384, + }) + + testCases = append(testCases, testCase{ testType: serverTest, name: "ServerAuth-SignatureType", config: Config{ @@ -4983,9 +5285,23 @@ expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA384, }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "ServerAuth-SignatureType-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + VerifySignatureAlgorithms: []signatureAlgorithm{ + signatureECDSAWithP521AndSHA512, + signatureRSAPKCS1WithSHA384, + signatureRSAPSSWithSHA384, + signatureECDSAWithSHA1, + }, + }, + expectedPeerSignatureAlgorithm: signatureRSAPSSWithSHA384, + }) + // Test that signature verification takes the key type into account. - // - // TODO(davidben): Test this in TLS 1.3. testCases = append(testCases, testCase{ testType: serverTest, name: "Verify-ClientAuth-SignatureType", @@ -5007,6 +5323,26 @@ }) testCases = append(testCases, testCase{ + testType: serverTest, + name: "Verify-ClientAuth-SignatureType-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + Certificates: []Certificate{rsaCertificate}, + SignSignatureAlgorithms: []signatureAlgorithm{ + signatureRSAPSSWithSHA256, + }, + Bugs: ProtocolBugs{ + SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, + }, + }, + flags: []string{ + "-require-any-client-certificate", + }, + shouldFail: true, + expectedError: ":WRONG_SIGNATURE_TYPE:", + }) + + testCases = append(testCases, testCase{ name: "Verify-ServerAuth-SignatureType", config: Config{ MaxVersion: VersionTLS12, @@ -5022,6 +5358,22 @@ expectedError: ":WRONG_SIGNATURE_TYPE:", }) + testCases = append(testCases, testCase{ + name: "Verify-ServerAuth-SignatureType-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + SignSignatureAlgorithms: []signatureAlgorithm{ + signatureRSAPSSWithSHA256, + }, + Bugs: ProtocolBugs{ + SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, + }, + }, + shouldFail: true, + expectedError: ":WRONG_SIGNATURE_TYPE:", + }) + // Test that, if the list is missing, the peer falls back to SHA-1 in // TLS 1.2, but not TLS 1.3. testCases = append(testCases, testCase{ @@ -5137,8 +5489,6 @@ // Test that the agreed upon digest respects the client preferences and // the server digests. - // - // TODO(davidben): Add TLS 1.3 versions of these. testCases = append(testCases, testCase{ name: "NoCommonAlgorithms-Digests", config: Config{ @@ -5421,7 +5771,7 @@ // shim must send flight N again, testing that the shim implements DTLS // retransmit on a timeout. - // TODO(davidben): Add TLS 1.3 versions of these tests. There will + // TODO(davidben): Add DTLS 1.3 versions of these tests. There will // likely be more epochs to cross and the final message's retransmit may // be more complex. @@ -5658,7 +6008,6 @@ expectedContents := "custom extension" emptyString := "" - // TODO(davidben): Add TLS 1.3 versions of these tests. for _, isClient := range []bool{false, true} { suffix := "Server" flag := "-enable-server-custom-extension" @@ -5681,6 +6030,18 @@ }, flags: []string{flag}, }) + testCases = append(testCases, testCase{ + testType: testType, + name: "CustomExtensions-" + suffix + "-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + CustomExtension: expectedContents, + ExpectedCustomExtension: &expectedContents, + }, + }, + flags: []string{flag}, + }) // If the parse callback fails, the handshake should also fail. testCases = append(testCases, testCase{ @@ -5697,6 +6058,20 @@ shouldFail: true, expectedError: ":CUSTOM_EXTENSION_ERROR:", }) + testCases = append(testCases, testCase{ + testType: testType, + name: "CustomExtensions-ParseError-" + suffix + "-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + CustomExtension: expectedContents + "foo", + ExpectedCustomExtension: &expectedContents, + }, + }, + flags: []string{flag}, + shouldFail: true, + expectedError: ":CUSTOM_EXTENSION_ERROR:", + }) // If the add callback fails, the handshake should also fail. testCases = append(testCases, testCase{ @@ -5713,6 +6088,20 @@ shouldFail: true, expectedError: ":CUSTOM_EXTENSION_ERROR:", }) + testCases = append(testCases, testCase{ + testType: testType, + name: "CustomExtensions-FailAdd-" + suffix + "-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + CustomExtension: expectedContents, + ExpectedCustomExtension: &expectedContents, + }, + }, + flags: []string{flag, "-custom-extension-fail-add"}, + shouldFail: true, + expectedError: ":CUSTOM_EXTENSION_ERROR:", + }) // If the add callback returns zero, no extension should be // added. @@ -5734,6 +6123,18 @@ }, flags: []string{flag, "-custom-extension-skip"}, }) + testCases = append(testCases, testCase{ + testType: testType, + name: "CustomExtensions-Skip-" + suffix + "-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + CustomExtension: skipCustomExtension, + ExpectedCustomExtension: &emptyString, + }, + }, + flags: []string{flag, "-custom-extension-skip"}, + }) } // The custom extension add callback should not be called if the client @@ -5750,6 +6151,18 @@ flags: []string{"-enable-server-custom-extension", "-custom-extension-fail-add"}, }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "CustomExtensions-NotCalled-Server-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + ExpectedCustomExtension: &emptyString, + }, + }, + flags: []string{"-enable-server-custom-extension", "-custom-extension-fail-add"}, + }) + // Test an unknown extension from the server. testCases = append(testCases, testCase{ testType: clientTest, @@ -5763,6 +6176,18 @@ shouldFail: true, expectedError: ":UNEXPECTED_EXTENSION:", }) + testCases = append(testCases, testCase{ + testType: clientTest, + name: "UnknownExtension-Client-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + CustomExtension: expectedContents, + }, + }, + shouldFail: true, + expectedError: ":UNEXPECTED_EXTENSION:", + }) } func addRSAClientKeyExchangeTests() { @@ -5797,7 +6222,6 @@ } func addCurveTests() { - // TODO(davidben): Add a TLS 1.3 versions of these tests. for _, curve := range testCurves { testCases = append(testCases, testCase{ name: "CurveTest-Client-" + curve.name, @@ -5809,6 +6233,15 @@ flags: []string{"-enable-all-curves"}, }) testCases = append(testCases, testCase{ + name: "CurveTest-Client-" + curve.name + "-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + CurvePreferences: []CurveID{curve.id}, + }, + flags: []string{"-enable-all-curves"}, + }) + testCases = append(testCases, testCase{ testType: serverTest, name: "CurveTest-Server-" + curve.name, config: Config{ @@ -5818,6 +6251,16 @@ }, flags: []string{"-enable-all-curves"}, }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "CurveTest-Server-" + curve.name + "-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + CurvePreferences: []CurveID{curve.id}, + }, + flags: []string{"-enable-all-curves"}, + }) } // The server must be tolerant to bogus curves. @@ -5837,7 +6280,6 @@ testType: serverTest, name: "NoSupportedCurves", config: Config{ - // TODO(davidben): Add a TLS 1.3 version of this. MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, Bugs: ProtocolBugs{ @@ -5847,6 +6289,19 @@ shouldFail: true, expectedError: ":NO_SHARED_CIPHER:", }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "NoSupportedCurves-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + Bugs: ProtocolBugs{ + NoSupportedCurves: true, + }, + }, + shouldFail: true, + expectedError: ":NO_SHARED_CIPHER:", + }) // The server must fall back to another cipher when there are no // supported curves. @@ -5868,7 +6323,6 @@ testCases = append(testCases, testCase{ name: "BadECDHECurve", config: Config{ - // TODO(davidben): Add a TLS 1.3 version of this. MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, Bugs: ProtocolBugs{ @@ -5878,11 +6332,23 @@ shouldFail: true, expectedError: ":WRONG_CURVE:", }) + testCases = append(testCases, testCase{ + name: "BadECDHECurve-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + Bugs: ProtocolBugs{ + SendCurve: bogusCurve, + }, + }, + shouldFail: true, + expectedError: ":WRONG_CURVE:", + }) testCases = append(testCases, testCase{ name: "UnsupportedCurve", config: Config{ - // TODO(davidben): Add a TLS 1.3 version of this. + // TODO(davidben): Add a TLS 1.3 version of this test. MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, CurvePreferences: []CurveID{CurveP256}, @@ -5899,7 +6365,6 @@ testCases = append(testCases, testCase{ name: "InvalidECDHPoint-Client", config: Config{ - // TODO(davidben): Add a TLS 1.3 version of this test. MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, CurvePreferences: []CurveID{CurveP256}, @@ -5911,10 +6376,22 @@ expectedError: ":INVALID_ENCODING:", }) testCases = append(testCases, testCase{ + name: "InvalidECDHPoint-Client-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + CurvePreferences: []CurveID{CurveP256}, + Bugs: ProtocolBugs{ + InvalidECDHPoint: true, + }, + }, + shouldFail: true, + expectedError: ":INVALID_ENCODING:", + }) + testCases = append(testCases, testCase{ testType: serverTest, name: "InvalidECDHPoint-Server", config: Config{ - // TODO(davidben): Add a TLS 1.3 version of this test. MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, CurvePreferences: []CurveID{CurveP256}, @@ -5925,6 +6402,20 @@ shouldFail: true, expectedError: ":INVALID_ENCODING:", }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "InvalidECDHPoint-Server-TLS13", + config: Config{ + MaxVersion: VersionTLS13, + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + CurvePreferences: []CurveID{CurveP256}, + Bugs: ProtocolBugs{ + InvalidECDHPoint: true, + }, + }, + shouldFail: true, + expectedError: ":INVALID_ENCODING:", + }) } func addCECPQ1Tests() { @@ -6016,9 +6507,6 @@ flags: []string{"-expect-dhe-group-size", "2048"}, }) - // TODO(davidben): Add TLS 1.3 versions of these tests once the - // handshake is separate. - testCases = append(testCases, testCase{ name: "KeyExchangeInfo-ECDHE-Client", config: Config{ @@ -6242,6 +6730,32 @@ expectedError: ":BUFFERED_MESSAGES_ON_CIPHER_CHANGE:", }) + // Test synchronization between encryption changes and the handshake in + // TLS 1.3, where ChangeCipherSpec is implicit. + testCases = append(testCases, testCase{ + name: "PartialEncryptedExtensionsWithServerHello", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + PartialEncryptedExtensionsWithServerHello: true, + }, + }, + shouldFail: true, + expectedError: ":BUFFERED_MESSAGES_ON_CIPHER_CHANGE:", + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "PartialClientFinishedWithClientHello", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + PartialClientFinishedWithClientHello: true, + }, + }, + shouldFail: true, + expectedError: ":BUFFERED_MESSAGES_ON_CIPHER_CHANGE:", + }) + // Test that early ChangeCipherSpecs are handled correctly. testCases = append(testCases, testCase{ testType: serverTest, @@ -6589,6 +7103,238 @@ } } +func addTLS13WrongMessageTypeTests() { + testCases = append(testCases, testCase{ + testType: serverTest, + name: "WrongMessageType-TLS13-ClientHello", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendWrongMessageType: typeClientHello, + }, + }, + shouldFail: true, + expectedError: ":UNEXPECTED_MESSAGE:", + expectedLocalError: "remote error: unexpected message", + }) + + testCases = append(testCases, testCase{ + name: "WrongMessageType-TLS13-ServerHello", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendWrongMessageType: typeServerHello, + }, + }, + shouldFail: true, + expectedError: ":UNEXPECTED_MESSAGE:", + // The alert comes in with the wrong encryption. + expectedLocalError: "local error: bad record MAC", + }) + + testCases = append(testCases, testCase{ + name: "WrongMessageType-TLS13-EncryptedExtensions", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendWrongMessageType: typeEncryptedExtensions, + }, + }, + shouldFail: true, + expectedError: ":UNEXPECTED_MESSAGE:", + expectedLocalError: "remote error: unexpected message", + }) + + testCases = append(testCases, testCase{ + name: "WrongMessageType-TLS13-CertificateRequest", + config: Config{ + MaxVersion: VersionTLS13, + ClientAuth: RequireAnyClientCert, + Bugs: ProtocolBugs{ + SendWrongMessageType: typeCertificateRequest, + }, + }, + shouldFail: true, + expectedError: ":UNEXPECTED_MESSAGE:", + expectedLocalError: "remote error: unexpected message", + }) + + testCases = append(testCases, testCase{ + name: "WrongMessageType-TLS13-ServerCertificate", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendWrongMessageType: typeCertificate, + }, + }, + shouldFail: true, + expectedError: ":UNEXPECTED_MESSAGE:", + expectedLocalError: "remote error: unexpected message", + }) + + testCases = append(testCases, testCase{ + name: "WrongMessageType-TLS13-ServerCertificateVerify", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendWrongMessageType: typeCertificateVerify, + }, + }, + shouldFail: true, + expectedError: ":UNEXPECTED_MESSAGE:", + expectedLocalError: "remote error: unexpected message", + }) + + testCases = append(testCases, testCase{ + name: "WrongMessageType-TLS13-ServerFinished", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendWrongMessageType: typeFinished, + }, + }, + shouldFail: true, + expectedError: ":UNEXPECTED_MESSAGE:", + expectedLocalError: "remote error: unexpected message", + }) + + testCases = append(testCases, testCase{ + testType: serverTest, + name: "WrongMessageType-TLS13-ClientCertificate", + config: Config{ + Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendWrongMessageType: typeCertificate, + }, + }, + flags: []string{"-require-any-client-certificate"}, + shouldFail: true, + expectedError: ":UNEXPECTED_MESSAGE:", + expectedLocalError: "remote error: unexpected message", + }) + + testCases = append(testCases, testCase{ + testType: serverTest, + name: "WrongMessageType-TLS13-ClientCertificateVerify", + config: Config{ + Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendWrongMessageType: typeCertificateVerify, + }, + }, + flags: []string{"-require-any-client-certificate"}, + shouldFail: true, + expectedError: ":UNEXPECTED_MESSAGE:", + expectedLocalError: "remote error: unexpected message", + }) + + testCases = append(testCases, testCase{ + testType: serverTest, + name: "WrongMessageType-TLS13-ClientFinished", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendWrongMessageType: typeFinished, + }, + }, + shouldFail: true, + expectedError: ":UNEXPECTED_MESSAGE:", + expectedLocalError: "remote error: unexpected message", + }) +} + +func addTLS13HandshakeTests() { + testCases = append(testCases, testCase{ + testType: clientTest, + name: "MissingKeyShare-Client", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + MissingKeyShare: true, + }, + }, + shouldFail: true, + expectedError: ":MISSING_KEY_SHARE:", + }) + + testCases = append(testCases, testCase{ + name: "MissingKeyShare-Server", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + MissingKeyShare: true, + }, + }, + shouldFail: true, + expectedError: ":MISSING_KEY_SHARE:", + }) + + testCases = append(testCases, testCase{ + testType: clientTest, + name: "ClientHelloMissingKeyShare", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + MissingKeyShare: true, + }, + }, + shouldFail: true, + expectedError: ":MISSING_KEY_SHARE:", + }) + + testCases = append(testCases, testCase{ + testType: clientTest, + name: "MissingKeyShare", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + MissingKeyShare: true, + }, + }, + shouldFail: true, + expectedError: ":MISSING_KEY_SHARE:", + }) + + testCases = append(testCases, testCase{ + testType: serverTest, + name: "DuplicateKeyShares", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + DuplicateKeyShares: true, + }, + }, + }) + + testCases = append(testCases, testCase{ + testType: clientTest, + name: "EmptyEncryptedExtensions", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + EmptyEncryptedExtensions: true, + }, + }, + shouldFail: true, + expectedLocalError: "remote error: error decoding message", + }) + + testCases = append(testCases, testCase{ + testType: clientTest, + name: "EncryptedExtensionsWithKeyShare", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + EncryptedExtensionsWithKeyShare: true, + }, + }, + shouldFail: true, + expectedLocalError: "remote error: unsupported extension", + }) +} + func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) { defer wg.Done() @@ -6694,6 +7440,8 @@ addAllStateMachineCoverageTests() addChangeCipherSpecTests() addWrongMessageTypeTests() + addTLS13WrongMessageTypeTests() + addTLS13HandshakeTests() var wg sync.WaitGroup
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc index 24a4646..b1a0792 100644 --- a/ssl/test/test_config.cc +++ b/ssl/test/test_config.cc
@@ -61,6 +61,7 @@ { "-no-tls11", &TestConfig::no_tls11 }, { "-no-tls1", &TestConfig::no_tls1 }, { "-no-ssl3", &TestConfig::no_ssl3 }, + { "-enable-channel-id", &TestConfig::enable_channel_id }, { "-shim-writes-first", &TestConfig::shim_writes_first }, { "-expect-session-miss", &TestConfig::expect_session_miss }, { "-decline-alpn", &TestConfig::decline_alpn },
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h index 4ee717e..73bdc6e 100644 --- a/ssl/test/test_config.h +++ b/ssl/test/test_config.h
@@ -46,6 +46,7 @@ bool no_tls1 = false; bool no_ssl3 = false; std::string expected_channel_id; + bool enable_channel_id = false; std::string send_channel_id; bool shim_writes_first = false; std::string host_name;