diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index a6c2880a..17709bca 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -593,9 +593,7 @@ OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl); #define DTLS1_VERSION 0xfeff #define DTLS1_2_VERSION 0xfefd -#define TLS1_3_DRAFT22_VERSION 0x7f16 #define TLS1_3_DRAFT23_VERSION 0x7f17 -#define TLS1_3_EXPERIMENT2_VERSION 0x7e02 // SSL_CTX_set_min_proto_version sets the minimum protocol version for |ctx| to // |version|. If |version| is zero, the default minimum version is used. It @@ -3304,8 +3302,6 @@ OPENSSL_EXPORT int SSL_total_renegotiations(const SSL *ssl); enum tls13_variant_t { tls13_default = 0, - tls13_experiment2 = 1, - tls13_draft22 = 2, }; // SSL_CTX_set_tls13_variant sets which variant of TLS 1.3 we negotiate. On the diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h index 105ab8eb..3424f3dc 100644 --- a/include/openssl/tls1.h +++ b/include/openssl/tls1.h @@ -213,15 +213,13 @@ extern "C" { // ExtensionType values from draft-ietf-tls-tls13-18 #define TLSEXT_TYPE_supported_groups 10 -#define TLSEXT_TYPE_old_key_share 40 #define TLSEXT_TYPE_pre_shared_key 41 #define TLSEXT_TYPE_early_data 42 #define TLSEXT_TYPE_supported_versions 43 #define TLSEXT_TYPE_cookie 44 #define TLSEXT_TYPE_psk_key_exchange_modes 45 -#define TLSEXT_TYPE_ticket_early_data_info 46 #define TLSEXT_TYPE_certificate_authorities 47 -#define TLSEXT_TYPE_new_key_share 51 +#define TLSEXT_TYPE_key_share 51 // ExtensionType value from RFC5746 #define TLSEXT_TYPE_renegotiate 0xff01 diff --git a/ssl/handshake_client.cc b/ssl/handshake_client.cc index 1f91adbf..e8dd0d37 100644 --- a/ssl/handshake_client.cc +++ b/ssl/handshake_client.cc @@ -493,8 +493,7 @@ static enum ssl_hs_wait_t do_enter_early_data(SSL_HANDSHAKE *hs) { } ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->session->ssl_version); - if (ssl_is_draft22(ssl->session->ssl_version) && - !ssl->method->add_change_cipher_spec(ssl)) { + if (!ssl->method->add_change_cipher_spec(ssl)) { return ssl_hs_error; } diff --git a/ssl/internal.h b/ssl/internal.h index af4eaaef..f2b2f6d1 100644 --- a/ssl/internal.h +++ b/ssl/internal.h @@ -392,18 +392,6 @@ bool ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert, // call this function before the version is determined. uint16_t ssl_protocol_version(const SSL *ssl); -// ssl_is_draft22 returns whether the version corresponds to a draft22 TLS 1.3 -// variant. -bool ssl_is_draft22(uint16_t version); - -// ssl_is_draft23 returns whether the version corresponds to a draft23 TLS 1.3 -// variant. -bool ssl_is_draft23(uint16_t version); - -// ssl_is_draft23_variant returns whether the variant corresponds to a -// draft23 TLS 1.3 variant. - bool ssl_is_draft23_variant(enum tls13_variant_t variant); - // Cipher suites. } // namespace bssl diff --git a/ssl/s3_pkt.cc b/ssl/s3_pkt.cc index e14d551a..5eb68f6b 100644 --- a/ssl/s3_pkt.cc +++ b/ssl/s3_pkt.cc @@ -304,14 +304,6 @@ ssl_open_record_t ssl3_open_app_data(SSL *ssl, Span *out, const bool is_early_data_read = ssl->server && SSL_in_early_data(ssl); if (type == SSL3_RT_HANDSHAKE) { - // If reading 0-RTT data, reject handshake data. 0-RTT data is terminated - // by an alert. - if (!ssl_is_draft22(ssl->version) && is_early_data_read) { - OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); - *out_alert = SSL_AD_UNEXPECTED_MESSAGE; - return ssl_open_record_error; - } - // Post-handshake data prior to TLS 1.3 is always renegotiation, which we // never accept as a server. Otherwise |ssl3_get_message| will send // |SSL_R_EXCESSIVE_MESSAGE_SIZE|. @@ -332,16 +324,6 @@ ssl_open_record_t ssl3_open_app_data(SSL *ssl, Span *out, return ssl_open_record_discard; } - // Handle the end_of_early_data alert. - static const uint8_t kEndOfEarlyData[2] = {SSL3_AL_WARNING, - TLS1_AD_END_OF_EARLY_DATA}; - if (!ssl_is_draft22(ssl->version) && is_early_data_read && - type == SSL3_RT_ALERT && body == kEndOfEarlyData) { - // Stop accepting early data. - ssl->s3->hs->can_early_read = false; - return ssl_open_record_discard; - } - if (type != SSL3_RT_APPLICATION_DATA) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); *out_alert = SSL_AD_UNEXPECTED_MESSAGE; diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc index 6c4282e4..b2042ead 100644 --- a/ssl/ssl_test.cc +++ b/ssl/ssl_test.cc @@ -2618,7 +2618,7 @@ TEST(SSLTest, SetVersion) { // TLS1_3_DRAFT_VERSION is not an API-level version. EXPECT_FALSE( - SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_DRAFT22_VERSION)); + SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_DRAFT23_VERSION)); ERR_clear_error(); ctx.reset(SSL_CTX_new(DTLS_method())); diff --git a/ssl/ssl_versions.cc b/ssl/ssl_versions.cc index 15012dc8..aeb41d3d 100644 --- a/ssl/ssl_versions.cc +++ b/ssl/ssl_versions.cc @@ -34,9 +34,7 @@ bool ssl_protocol_version_from_wire(uint16_t *out, uint16_t version) { *out = version; return true; - case TLS1_3_DRAFT22_VERSION: case TLS1_3_DRAFT23_VERSION: - case TLS1_3_EXPERIMENT2_VERSION: *out = TLS1_3_VERSION; return true; @@ -59,8 +57,6 @@ bool ssl_protocol_version_from_wire(uint16_t *out, uint16_t version) { static const uint16_t kTLSVersions[] = { TLS1_3_DRAFT23_VERSION, - TLS1_3_DRAFT22_VERSION, - TLS1_3_EXPERIMENT2_VERSION, TLS1_2_VERSION, TLS1_1_VERSION, TLS1_VERSION, @@ -103,9 +99,7 @@ static bool method_supports_version(const SSL_PROTOCOL_METHOD *method, static const char *ssl_version_to_string(uint16_t version) { switch (version) { - case TLS1_3_DRAFT22_VERSION: case TLS1_3_DRAFT23_VERSION: - case TLS1_3_EXPERIMENT2_VERSION: return "TLSv1.3"; case TLS1_2_VERSION: @@ -134,9 +128,7 @@ static const char *ssl_version_to_string(uint16_t version) { static uint16_t wire_version_to_api(uint16_t version) { switch (version) { // Report TLS 1.3 draft versions as TLS 1.3 in the public API. - case TLS1_3_DRAFT22_VERSION: case TLS1_3_DRAFT23_VERSION: - case TLS1_3_EXPERIMENT2_VERSION: return TLS1_3_VERSION; default: return version; @@ -147,13 +139,11 @@ static uint16_t wire_version_to_api(uint16_t version) { // particular, it picks an arbitrary TLS 1.3 representative. This should only be // used in context where that does not matter. static bool api_version_to_wire(uint16_t *out, uint16_t version) { - if (version == TLS1_3_DRAFT22_VERSION || - version == TLS1_3_DRAFT23_VERSION || - version == TLS1_3_EXPERIMENT2_VERSION) { + if (version == TLS1_3_DRAFT23_VERSION) { return false; } if (version == TLS1_3_VERSION) { - version = TLS1_3_DRAFT22_VERSION; + version = TLS1_3_DRAFT23_VERSION; } // Check it is a real protocol version. @@ -304,12 +294,10 @@ bool ssl_supports_version(SSL_HANDSHAKE *hs, uint16_t version) { return false; } - // TLS 1.3 variants must additionally match |tls13_variant|. + // This logic is part of the TLS 1.3 variants mechanism used in TLS 1.3 + // experimentation. Although we currently only have one variant, TLS 1.3 does + // not a final stable deployment yet, so leave the logic in place for now. if (protocol_version != TLS1_3_VERSION || - (ssl->tls13_variant == tls13_experiment2 && - version == TLS1_3_EXPERIMENT2_VERSION) || - (ssl->tls13_variant == tls13_draft22 && - version == TLS1_3_DRAFT22_VERSION) || (ssl->tls13_variant == tls13_default && version == TLS1_3_DRAFT23_VERSION)) { return true; @@ -368,18 +356,6 @@ bool ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert, return false; } -bool ssl_is_draft22(uint16_t version) { - return version == TLS1_3_DRAFT22_VERSION || version == TLS1_3_DRAFT23_VERSION; -} - -bool ssl_is_draft23(uint16_t version) { - return version == TLS1_3_DRAFT23_VERSION; -} - -bool ssl_is_draft23_variant(tls13_variant_t variant) { - return variant == tls13_default; -} - } // namespace bssl using namespace bssl; diff --git a/ssl/t1_lib.cc b/ssl/t1_lib.cc index d9729499..02ed22be 100644 --- a/ssl/t1_lib.cc +++ b/ssl/t1_lib.cc @@ -551,10 +551,6 @@ static bool forbid_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, return true; } -static bool dont_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { - return true; -} - static bool ignore_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents) { // This extension from the client is handled elsewhere. @@ -1821,7 +1817,6 @@ static bool ext_pre_shared_key_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { // selected cipher in HelloRetryRequest does not match. This avoids performing // the transcript hash transformation for multiple hashes. if (hs->received_hello_retry_request && - ssl_is_draft22(ssl->version) && ssl->session->cipher->algorithm_prf != hs->new_cipher->algorithm_prf) { return true; } @@ -2091,9 +2086,7 @@ static bool ext_key_share_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { } CBB contents, kse_bytes; - if (!CBB_add_u16(out, ssl_is_draft23_variant(ssl->tls13_variant) - ? TLSEXT_TYPE_new_key_share - : TLSEXT_TYPE_old_key_share) || + if (!CBB_add_u16(out, TLSEXT_TYPE_key_share) || !CBB_add_u16_length_prefixed(out, &contents) || !CBB_add_u16_length_prefixed(&contents, &kse_bytes)) { return false; @@ -2250,9 +2243,7 @@ bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { uint16_t group_id; CBB kse_bytes, public_key; if (!tls1_get_shared_group(hs, &group_id) || - !CBB_add_u16(out, ssl_is_draft23(hs->ssl->version) - ? TLSEXT_TYPE_new_key_share - : TLSEXT_TYPE_old_key_share) || + !CBB_add_u16(out, TLSEXT_TYPE_key_share) || !CBB_add_u16_length_prefixed(out, &kse_bytes) || !CBB_add_u16(&kse_bytes, group_id) || !CBB_add_u16_length_prefixed(&kse_bytes, &public_key) || @@ -2760,16 +2751,7 @@ static const struct tls_extension kExtensions[] = { ext_ec_point_add_serverhello, }, { - TLSEXT_TYPE_old_key_share, - // This is added by TLSEXT_TYPE_new_key_share's callback. - NULL, - dont_add_clienthello, - forbid_parse_serverhello, - ignore_parse_clienthello, - dont_add_serverhello, - }, - { - TLSEXT_TYPE_new_key_share, + TLSEXT_TYPE_key_share, NULL, ext_key_share_add_clienthello, forbid_parse_serverhello, diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go index dcf8afeb..fef51291 100644 --- a/ssl/test/runner/common.go +++ b/ssl/test/runner/common.go @@ -33,21 +33,15 @@ const ( // A draft version of TLS 1.3 that is sent over the wire for the current draft. const ( - tls13Experiment2Version = 0x7e02 - tls13Draft22Version = 0x7f16 - tls13Draft23Version = 0x7f17 + tls13Draft23Version = 0x7f17 ) const ( - TLS13Draft23 = 0 - TLS13Experiment2 = 1 - TLS13Draft22 = 2 + TLS13Draft23 = 0 ) var allTLSWireVersions = []uint16{ tls13Draft23Version, - tls13Draft22Version, - tls13Experiment2Version, VersionTLS12, VersionTLS11, VersionTLS10, @@ -125,7 +119,6 @@ const ( extensionTokenBinding uint16 = 24 extensionQUICTransportParams uint16 = 26 extensionSessionTicket uint16 = 35 - extensionOldKeyShare uint16 = 40 // draft-ietf-tls-tls13-16 extensionPreSharedKey uint16 = 41 // draft-ietf-tls-tls13-16 extensionEarlyData uint16 = 42 // draft-ietf-tls-tls13-16 extensionSupportedVersions uint16 = 43 // draft-ietf-tls-tls13-16 @@ -133,7 +126,7 @@ const ( extensionPSKKeyExchangeModes uint16 = 45 // draft-ietf-tls-tls13-18 extensionTicketEarlyDataInfo uint16 = 46 // draft-ietf-tls-tls13-18 extensionCertificateAuthorities uint16 = 47 // draft-ietf-tls-tls13-21 - extensionNewKeyShare uint16 = 51 // draft-ietf-tls-tls13-23 + extensionKeyShare uint16 = 51 // draft-ietf-tls-tls13-23 extensionCustom uint16 = 1234 // not IANA assigned extensionNextProtoNeg uint16 = 13172 // not IANA assigned extensionRenegotiationInfo uint16 = 0xff01 @@ -1670,7 +1663,7 @@ func wireToVersion(vers uint16, isDTLS bool) (uint16, bool) { switch vers { case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12: return vers, true - case tls13Draft23Version, tls13Draft22Version, tls13Experiment2Version: + case tls13Draft23Version: return VersionTLS13, true } } @@ -1678,21 +1671,11 @@ func wireToVersion(vers uint16, isDTLS bool) (uint16, bool) { return 0, false } -func isDraft22(vers uint16) bool { - return vers == tls13Draft22Version || vers == tls13Draft23Version -} - -func isDraft23(vers uint16) bool { - return vers == tls13Draft23Version -} - // isSupportedVersion checks if the specified wire version is acceptable. If so, // it returns true and the corresponding protocol version. Otherwise, it returns // false. func (c *Config) isSupportedVersion(wireVers uint16, isDTLS bool) (uint16, bool) { - if (c.TLS13Variant != TLS13Experiment2 && wireVers == tls13Experiment2Version) || - (c.TLS13Variant != TLS13Draft23 && wireVers == tls13Draft23Version) || - (c.TLS13Variant != TLS13Draft22 && wireVers == tls13Draft22Version) { + if c.TLS13Variant != TLS13Draft23 && wireVers == tls13Draft23Version { return 0, false } diff --git a/ssl/test/runner/conn.go b/ssl/test/runner/conn.go index 1bf4c5e8..79cd06a7 100644 --- a/ssl/test/runner/conn.go +++ b/ssl/test/runner/conn.go @@ -1566,9 +1566,7 @@ func (c *Conn) processTLS13NewSessionTicket(newSessionTicket *newSessionTicketMs earlyALPN: c.clientProtocol, } - if isDraft22(c.wireVersion) { - session.masterSecret = deriveSessionPSK(cipherSuite, c.wireVersion, c.resumptionSecret, newSessionTicket.ticketNonce) - } + session.masterSecret = deriveSessionPSK(cipherSuite, c.wireVersion, c.resumptionSecret, newSessionTicket.ticketNonce) cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config) _, ok := c.config.ClientSessionCache.Get(cacheKey) @@ -1860,16 +1858,13 @@ func (c *Conn) exportKeyingMaterialTLS13(length int, secret, label, context []by if cipherSuite == nil { cipherSuite = c.earlyCipherSuite } - if isDraft22(c.wireVersion) { - hash := cipherSuite.hash() - exporterKeyingLabel := []byte("exporter") - contextHash := hash.New() - contextHash.Write(context) - exporterContext := hash.New().Sum(nil) - derivedSecret := hkdfExpandLabel(cipherSuite.hash(), c.wireVersion, secret, label, exporterContext, hash.Size()) - return hkdfExpandLabel(cipherSuite.hash(), c.wireVersion, derivedSecret, exporterKeyingLabel, contextHash.Sum(nil), length) - } - return hkdfExpandLabel(cipherSuite.hash(), c.wireVersion, secret, label, context, length) + hash := cipherSuite.hash() + exporterKeyingLabel := []byte("exporter") + contextHash := hash.New() + contextHash.Write(context) + exporterContext := hash.New().Sum(nil) + derivedSecret := hkdfExpandLabel(cipherSuite.hash(), secret, label, exporterContext, hash.Size()) + return hkdfExpandLabel(cipherSuite.hash(), derivedSecret, exporterKeyingLabel, contextHash.Sum(nil), length) } // ExportKeyingMaterial exports keying material from the current connection @@ -1954,13 +1949,10 @@ func (c *Conn) SendNewSessionTicket(nonce []byte) error { duplicateEarlyDataExtension: c.config.Bugs.DuplicateTicketEarlyData, customExtension: c.config.Bugs.CustomTicketExtension, ticketAgeAdd: ticketAgeAdd, + ticketNonce: nonce, maxEarlyDataSize: c.config.MaxEarlyDataSize, } - if isDraft22(c.wireVersion) { - m.ticketNonce = nonce - } - if c.config.Bugs.SendTicketLifetime != 0 { m.ticketLifetime = uint32(c.config.Bugs.SendTicketLifetime / time.Second) } @@ -1968,7 +1960,7 @@ func (c *Conn) SendNewSessionTicket(nonce []byte) error { state := sessionState{ vers: c.vers, cipherSuite: c.cipherSuite.id, - masterSecret: c.resumptionSecret, + masterSecret: deriveSessionPSK(c.cipherSuite, c.wireVersion, c.resumptionSecret, nonce), certificates: peerCertificatesRaw, ticketCreationTime: c.config.time(), ticketExpiration: c.config.time().Add(time.Duration(m.ticketLifetime) * time.Second), @@ -1976,10 +1968,6 @@ func (c *Conn) SendNewSessionTicket(nonce []byte) error { earlyALPN: []byte(c.clientProtocol), } - if isDraft22(c.wireVersion) { - state.masterSecret = deriveSessionPSK(c.cipherSuite, c.wireVersion, c.resumptionSecret, nonce) - } - if !c.config.Bugs.SendEmptySessionTicket { var err error m.ticket, err = c.encryptTicket(&state) diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go index b2abc400..11402698 100644 --- a/ssl/test/runner/handshake_client.go +++ b/ssl/test/runner/handshake_client.go @@ -162,11 +162,6 @@ func (c *Conn) clientHandshake() error { if maxVersion >= VersionTLS13 { keyShares = make(map[CurveID]ecdhCurve) hello.hasKeyShares = true - if c.config.TLS13Variant == TLS13Draft23 { - hello.keyShareExtension = extensionNewKeyShare - } else { - hello.keyShareExtension = extensionOldKeyShare - } hello.trailingKeyShareData = c.config.Bugs.TrailingKeyShareData curvesToSend := c.config.defaultCurves() for _, curveID := range hello.supportedCurves { @@ -385,7 +380,7 @@ NextCipherSuite: // set. Fill in an arbitrary TLS 1.3 version to compute // the binder. if session.vers < VersionTLS13 { - version = tls13Draft22Version + version = tls13Draft23Version } generatePSKBinders(version, hello, pskCipherSuite, session.masterSecret, []byte{}, []byte{}, c.config) } @@ -422,7 +417,7 @@ NextCipherSuite: finishedHash.addEntropy(session.masterSecret) finishedHash.Write(helloBytes) - if !c.config.Bugs.SkipChangeCipherSpec && isDraft22(session.wireVersion) { + if !c.config.Bugs.SkipChangeCipherSpec { c.wireVersion = session.wireVersion c.vers = VersionTLS13 c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) @@ -430,14 +425,8 @@ NextCipherSuite: c.vers = 0 } - var earlyTrafficSecret []byte - if isDraft22(session.wireVersion) { - earlyTrafficSecret = finishedHash.deriveSecret(earlyTrafficLabelDraft22) - c.earlyExporterSecret = finishedHash.deriveSecret(earlyExporterLabelDraft22) - } else { - earlyTrafficSecret = finishedHash.deriveSecret(earlyTrafficLabel) - c.earlyExporterSecret = finishedHash.deriveSecret(earlyExporterLabel) - } + earlyTrafficSecret := finishedHash.deriveSecret(earlyTrafficLabel) + c.earlyExporterSecret = finishedHash.deriveSecret(earlyExporterLabel) c.useOutTrafficSecret(session.wireVersion, pskCipherSuite, earlyTrafficSecret) for _, earlyData := range c.config.Bugs.SendEarlyData { @@ -498,7 +487,7 @@ NextCipherSuite: c.vers = serverVersion c.haveVers = true - if isDraft22(c.wireVersion) { + if c.vers >= VersionTLS13 { // The first server message must be followed by a ChangeCipherSpec. c.expectTLS13ChangeCipherSpec = true } @@ -506,12 +495,10 @@ NextCipherSuite: helloRetryRequest, haveHelloRetryRequest := msg.(*helloRetryRequestMsg) var secondHelloBytes []byte if haveHelloRetryRequest { - if isDraft22(c.wireVersion) { - // Explicitly read the ChangeCipherSpec now; it should - // be attached to the first flight, not the second flight. - if err := c.readTLS13ChangeCipherSpec(); err != nil { - return err - } + // Explicitly read the ChangeCipherSpec now; it should + // be attached to the first flight, not the second flight. + if err := c.readTLS13ChangeCipherSpec(); err != nil { + return err } c.out.resetCipher() @@ -639,11 +626,9 @@ NextCipherSuite: hs.writeHash(helloBytes, hs.c.sendHandshakeSeq-1) if haveHelloRetryRequest { - if isDraft22(c.wireVersion) { - err = hs.finishedHash.UpdateForHelloRetryRequest() - if err != nil { - return err - } + err = hs.finishedHash.UpdateForHelloRetryRequest() + if err != nil { + return err } hs.writeServerHash(helloRetryRequest.marshal()) hs.writeClientHash(secondHelloBytes) @@ -740,12 +725,6 @@ NextCipherSuite: func (hs *clientHandshakeState) doTLS13Handshake() error { c := hs.c - if !isDraft22(c.wireVersion) { - // Early versions of the middlebox hacks inserted - // ChangeCipherSpec differently on 0-RTT and 2-RTT handshakes. - c.expectTLS13ChangeCipherSpec = true - } - if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) { return errors.New("tls: session IDs did not match.") } @@ -802,17 +781,10 @@ func (hs *clientHandshakeState) doTLS13Handshake() error { hs.finishedHash.addEntropy(zeroSecret) } - clientLabel := clientHandshakeTrafficLabel - serverLabel := serverHandshakeTrafficLabel - if isDraft22(c.wireVersion) { - clientLabel = clientHandshakeTrafficLabelDraft22 - serverLabel = serverHandshakeTrafficLabelDraft22 - } - // Derive handshake traffic keys and switch read key to handshake // traffic key. - clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(clientLabel) - serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(serverLabel) + clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(clientHandshakeTrafficLabel) + serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(serverHandshakeTrafficLabel) if err := c.useInTrafficSecret(c.wireVersion, hs.suite, serverHandshakeTrafficSecret); err != nil { return err } @@ -949,18 +921,9 @@ func (hs *clientHandshakeState) doTLS13Handshake() error { hs.finishedHash.nextSecret() hs.finishedHash.addEntropy(zeroSecret) - clientLabel = clientApplicationTrafficLabel - serverLabel = serverApplicationTrafficLabel - exportLabel := exporterLabel - if isDraft22(c.wireVersion) { - clientLabel = clientApplicationTrafficLabelDraft22 - serverLabel = serverApplicationTrafficLabelDraft22 - exportLabel = exporterLabelDraft22 - } - - clientTrafficSecret := hs.finishedHash.deriveSecret(clientLabel) - serverTrafficSecret := hs.finishedHash.deriveSecret(serverLabel) - c.exporterSecret = hs.finishedHash.deriveSecret(exportLabel) + clientTrafficSecret := hs.finishedHash.deriveSecret(clientApplicationTrafficLabel) + serverTrafficSecret := hs.finishedHash.deriveSecret(serverApplicationTrafficLabel) + c.exporterSecret = hs.finishedHash.deriveSecret(exporterLabel) // Switch to application data keys on read. In particular, any alerts // from the client certificate are read over these keys. @@ -1004,14 +967,10 @@ func (hs *clientHandshakeState) doTLS13Handshake() error { helloRequest := new(helloRequestMsg) c.writeRecord(recordTypeHandshake, helloRequest.marshal()) } - if isDraft22(c.wireVersion) { - endOfEarlyData := new(endOfEarlyDataMsg) - endOfEarlyData.nonEmpty = c.config.Bugs.NonEmptyEndOfEarlyData - c.writeRecord(recordTypeHandshake, endOfEarlyData.marshal()) - hs.writeClientHash(endOfEarlyData.marshal()) - } else { - c.sendAlert(alertEndOfEarlyData) - } + endOfEarlyData := new(endOfEarlyDataMsg) + endOfEarlyData.nonEmpty = c.config.Bugs.NonEmptyEndOfEarlyData + c.writeRecord(recordTypeHandshake, endOfEarlyData.marshal()) + hs.writeClientHash(endOfEarlyData.marshal()) } if !c.config.Bugs.SkipChangeCipherSpec && !hs.hello.hasEarlyData { @@ -1109,13 +1068,7 @@ func (hs *clientHandshakeState) doTLS13Handshake() error { // Switch to application data keys. c.useOutTrafficSecret(c.wireVersion, hs.suite, clientTrafficSecret) - - resumeLabel := resumptionLabel - if isDraft22(c.wireVersion) { - resumeLabel = resumptionLabelDraft22 - } - - c.resumptionSecret = hs.finishedHash.deriveSecret(resumeLabel) + c.resumptionSecret = hs.finishedHash.deriveSecret(resumptionLabel) for _, ticket := range deferredTickets { if err := c.processTLS13NewSessionTicket(ticket, hs.suite); err != nil { return err @@ -1887,11 +1840,7 @@ func generatePSKBinders(version uint16, hello *clientHelloMsg, pskCipherSuite *c helloBytes := hello.marshal() binderSize := len(hello.pskBinders)*(binderLen+1) + 2 truncatedHello := helloBytes[:len(helloBytes)-binderSize] - binderLabel := resumptionPSKBinderLabel - if isDraft22(version) { - binderLabel = resumptionPSKBinderLabelDraft22 - } - binder := computePSKBinder(psk, version, binderLabel, pskCipherSuite, firstClientHello, helloRetryRequest, truncatedHello) + binder := computePSKBinder(psk, version, resumptionPSKBinderLabel, pskCipherSuite, firstClientHello, helloRetryRequest, truncatedHello) if config.Bugs.SendShortPSKBinder { binder = binder[:binderLen] } diff --git a/ssl/test/runner/handshake_messages.go b/ssl/test/runner/handshake_messages.go index 2f1f7656..b19506d3 100644 --- a/ssl/test/runner/handshake_messages.go +++ b/ssl/test/runner/handshake_messages.go @@ -265,7 +265,6 @@ type clientHelloMsg struct { supportedCurves []CurveID supportedPoints []uint8 hasKeyShares bool - keyShareExtension uint16 keyShares []keyShareEntry trailingKeyShareData bool pskIdentities []pskIdentity @@ -453,7 +452,7 @@ func (m *clientHelloMsg) marshal() []byte { supportedPoints.addBytes(m.supportedPoints) } if m.hasKeyShares { - extensions.addU16(m.keyShareExtension) + extensions.addU16(extensionKeyShare) keyShareList := extensions.addU16LengthPrefixed() keyShares := keyShareList.addU16LengthPrefixed() @@ -740,12 +739,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool { // http://tools.ietf.org/html/rfc5077#section-3.2 m.ticketSupported = true m.sessionTicket = []byte(body) - case extensionOldKeyShare, extensionNewKeyShare: - // We assume the client only supports one of draft-22 or draft-23. - if m.keyShareExtension != 0 { - return false - } - m.keyShareExtension = extension + case extensionKeyShare: // draft-ietf-tls-tls13 section 6.3.2.3 var keyShares byteReader if !body.readU16LengthPrefixed(&keyShares) || len(body) != 0 { @@ -951,11 +945,7 @@ func (m *serverHelloMsg) marshal() []byte { if vers >= VersionTLS13 { if m.hasKeyShare { - if isDraft23(m.vers) { - extensions.addU16(extensionNewKeyShare) - } else { - extensions.addU16(extensionOldKeyShare) - } + extensions.addU16(extensionKeyShare) keyShare := extensions.addU16LengthPrefixed() keyShare.addU16(uint16(m.keyShare.group)) keyExchange := keyShare.addU16LengthPrefixed() @@ -1058,10 +1048,6 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool { } if vers >= VersionTLS13 { - extensionKeyShare := extensionOldKeyShare - if isDraft23(m.vers) { - extensionKeyShare = extensionNewKeyShare - } for len(extensions) > 0 { var extension uint16 var body byteReader @@ -1252,7 +1238,7 @@ func (m *serverExtensions) marshal(extensions *byteBuilder) { } } if m.hasKeyShare { - extensions.addU16(extensionOldKeyShare) + extensions.addU16(extensionKeyShare) keyShare := extensions.addU16LengthPrefixed() keyShare.addU16(uint16(m.keyShare.group)) keyExchange := keyShare.addU16LengthPrefixed() @@ -1425,26 +1411,15 @@ func (m *helloRetryRequestMsg) marshal() []byte { } retryRequestMsg := newByteBuilder() - if isDraft22(m.vers) { - retryRequestMsg.addU8(typeServerHello) - } else { - retryRequestMsg.addU8(typeHelloRetryRequest) - } + retryRequestMsg.addU8(typeServerHello) retryRequest := retryRequestMsg.addU24LengthPrefixed() + retryRequest.addU16(VersionTLS12) + retryRequest.addBytes(tls13HelloRetryRequest) + sessionId := retryRequest.addU8LengthPrefixed() + sessionId.addBytes(m.sessionId) + retryRequest.addU16(m.cipherSuite) + retryRequest.addU8(m.compressionMethod) - if isDraft22(m.vers) { - retryRequest.addU16(VersionTLS12) - retryRequest.addBytes(tls13HelloRetryRequest) - sessionId := retryRequest.addU8LengthPrefixed() - sessionId.addBytes(m.sessionId) - retryRequest.addU16(m.cipherSuite) - retryRequest.addU8(m.compressionMethod) - } else { - retryRequest.addU16(m.vers) - if isDraft22(m.vers) { - retryRequest.addU16(m.cipherSuite) - } - } extensions := retryRequest.addU16LengthPrefixed() count := 1 @@ -1453,17 +1428,11 @@ func (m *helloRetryRequestMsg) marshal() []byte { } for i := 0; i < count; i++ { - if isDraft22(m.vers) { - extensions.addU16(extensionSupportedVersions) - extensions.addU16(2) // Length - extensions.addU16(m.vers) - } + extensions.addU16(extensionSupportedVersions) + extensions.addU16(2) // Length + extensions.addU16(m.vers) if m.hasSelectedGroup { - if isDraft23(m.vers) { - extensions.addU16(extensionNewKeyShare) - } else { - extensions.addU16(extensionOldKeyShare) - } + extensions.addU16(extensionKeyShare) extensions.addU16(2) // length extensions.addU16(uint16(m.selectedGroup)) } @@ -1499,7 +1468,7 @@ func (m *helloRetryRequestMsg) unmarshal(data []byte) bool { compressionMethod != 0 { return false } - } else if isDraft22(m.vers) && !reader.readU16(&m.cipherSuite) { + } else if !reader.readU16(&m.cipherSuite) { return false } var extensions byteReader @@ -1524,10 +1493,6 @@ func (m *helloRetryRequestMsg) unmarshal(data []byte) bool { default: } } - extensionKeyShare := extensionOldKeyShare - if isDraft23(m.vers) { - extensionKeyShare = extensionNewKeyShare - } for len(extensions) > 0 { var extension uint16 var body byteReader @@ -1883,37 +1848,21 @@ func (m *certificateRequestMsg) marshal() []byte { requestContext := body.addU8LengthPrefixed() requestContext.addBytes(m.requestContext) extensions := newByteBuilder() - if isDraft22(m.vers) { - extensions = body.addU16LengthPrefixed() - if m.hasSignatureAlgorithm { - extensions.addU16(extensionSignatureAlgorithms) - signatureAlgorithms := extensions.addU16LengthPrefixed().addU16LengthPrefixed() - for _, sigAlg := range m.signatureAlgorithms { - signatureAlgorithms.addU16(uint16(sigAlg)) - } - } - if len(m.certificateAuthorities) > 0 { - extensions.addU16(extensionCertificateAuthorities) - certificateAuthorities := extensions.addU16LengthPrefixed().addU16LengthPrefixed() - for _, ca := range m.certificateAuthorities { - caEntry := certificateAuthorities.addU16LengthPrefixed() - caEntry.addBytes(ca) - } - } - } else { - if m.hasSignatureAlgorithm { - signatureAlgorithms := body.addU16LengthPrefixed() - for _, sigAlg := range m.signatureAlgorithms { - signatureAlgorithms.addU16(uint16(sigAlg)) - } + extensions = body.addU16LengthPrefixed() + if m.hasSignatureAlgorithm { + extensions.addU16(extensionSignatureAlgorithms) + signatureAlgorithms := extensions.addU16LengthPrefixed().addU16LengthPrefixed() + for _, sigAlg := range m.signatureAlgorithms { + signatureAlgorithms.addU16(uint16(sigAlg)) } - - certificateAuthorities := body.addU16LengthPrefixed() + } + if len(m.certificateAuthorities) > 0 { + extensions.addU16(extensionCertificateAuthorities) + certificateAuthorities := extensions.addU16LengthPrefixed().addU16LengthPrefixed() for _, ca := range m.certificateAuthorities { caEntry := certificateAuthorities.addU16LengthPrefixed() caEntry.addBytes(ca) } - extensions = body.addU16LengthPrefixed() } if m.customExtension > 0 { @@ -1961,7 +1910,7 @@ func (m *certificateRequestMsg) unmarshal(data []byte) bool { m.raw = data reader := byteReader(data[4:]) - if isDraft22(m.vers) { + if m.hasRequestContext { var extensions byteReader if !reader.readU8LengthPrefixedBytes(&m.requestContext) || !reader.readU16LengthPrefixed(&extensions) || @@ -1987,16 +1936,6 @@ func (m *certificateRequestMsg) unmarshal(data []byte) bool { m.hasCAExtension = true } } - } else if m.hasRequestContext { - var extensions byteReader - if !reader.readU8LengthPrefixedBytes(&m.requestContext) || - !parseSignatureAlgorithms(&reader, &m.signatureAlgorithms) || - !parseCAs(&reader, &m.certificateAuthorities) || - !reader.readU16LengthPrefixed(&extensions) || - len(reader) != 0 { - return false - } - // Ignore certificate extensions. } else { if !reader.readU8LengthPrefixedBytes(&m.certificateTypes) { return false @@ -2114,9 +2053,7 @@ func (m *newSessionTicketMsg) marshal() []byte { body.addU32(m.ticketLifetime) if version >= VersionTLS13 { body.addU32(m.ticketAgeAdd) - if isDraft22(m.vers) { - body.addU8LengthPrefixed().addBytes(m.ticketNonce) - } + body.addU8LengthPrefixed().addBytes(m.ticketNonce) } ticket := body.addU16LengthPrefixed() @@ -2125,14 +2062,10 @@ func (m *newSessionTicketMsg) marshal() []byte { if version >= VersionTLS13 { extensions := body.addU16LengthPrefixed() if m.maxEarlyDataSize > 0 { - extID := extensionTicketEarlyDataInfo - if isDraft22(m.vers) { - extID = extensionEarlyData - } - extensions.addU16(extID) + extensions.addU16(extensionEarlyData) extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize) if m.duplicateEarlyDataExtension { - extensions.addU16(extID) + extensions.addU16(extensionEarlyData) extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize) } } @@ -2166,15 +2099,13 @@ func (m *newSessionTicketMsg) unmarshal(data []byte) bool { } m.ticketAgeAdd = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) data = data[4:] - if isDraft22(m.vers) { - nonceLen := int(data[0]) - data = data[1:] - if len(data) < nonceLen { - return false - } - m.ticketNonce = data[:nonceLen] - data = data[nonceLen:] + nonceLen := int(data[0]) + data = data[1:] + if len(data) < nonceLen { + return false } + m.ticketNonce = data[:nonceLen] + data = data[nonceLen:] } if len(data) < 2 { @@ -2204,11 +2135,6 @@ func (m *newSessionTicketMsg) unmarshal(data []byte) bool { return false } - extID := extensionTicketEarlyDataInfo - if isDraft22(m.vers) { - extID = extensionEarlyData - } - for len(data) != 0 { if len(data) < 4 { return false @@ -2221,7 +2147,7 @@ func (m *newSessionTicketMsg) unmarshal(data []byte) bool { } switch extension { - case extID: + case extensionEarlyData: if length != 4 { return false } diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go index 79443778..caa66eda 100644 --- a/ssl/test/runner/handshake_server.go +++ b/ssl/test/runner/handshake_server.go @@ -280,14 +280,6 @@ func (hs *serverHandshakeState) readClientHello() error { } } - // Check that we received the expected version of the key_share extension. - if c.vers >= VersionTLS13 { - if (isDraft23(c.wireVersion) && hs.clientHello.keyShareExtension != extensionNewKeyShare) || - (!isDraft23(c.wireVersion) && hs.clientHello.keyShareExtension != extensionOldKeyShare) { - return fmt.Errorf("tls: client offered wrong key_share extension") - } - } - if config.Bugs.ExpectNoTLS12Session { if len(hs.clientHello.sessionId) > 0 && c.vers >= VersionTLS13 { return fmt.Errorf("tls: client offered an unexpected session ID") @@ -370,11 +362,8 @@ func (hs *serverHandshakeState) doTLS13Handshake() error { c := hs.c config := c.config - // We've read the ClientHello, so the next record in draft 22 must be - // preceded with ChangeCipherSpec. - if isDraft22(c.wireVersion) { - c.expectTLS13ChangeCipherSpec = true - } + // We've read the ClientHello, so the next record must be preceded with ChangeCipherSpec. + c.expectTLS13ChangeCipherSpec = true hs.hello = &serverHelloMsg{ isDTLS: c.isDTLS, @@ -597,10 +586,8 @@ ResendHelloRetryRequest: } if sendHelloRetryRequest { - if isDraft22(c.wireVersion) { - if err := hs.finishedHash.UpdateForHelloRetryRequest(); err != nil { - return err - } + if err := hs.finishedHash.UpdateForHelloRetryRequest(); err != nil { + return err } oldClientHelloBytes := hs.clientHello.marshal() @@ -608,7 +595,7 @@ ResendHelloRetryRequest: c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal()) c.flushHandshake() - if !c.config.Bugs.SkipChangeCipherSpec && isDraft22(c.wireVersion) { + if !c.config.Bugs.SkipChangeCipherSpec { c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) } @@ -666,7 +653,7 @@ ResendHelloRetryRequest: // PSK binders and obfuscated ticket age are both updated in the // second ClientHello. - if isDraft22(c.wireVersion) && len(oldClientHelloCopy.pskIdentities) != len(newClientHelloCopy.pskIdentities) { + if len(oldClientHelloCopy.pskIdentities) != len(newClientHelloCopy.pskIdentities) { newClientHelloCopy.pskIdentities = oldClientHelloCopy.pskIdentities } else { if len(oldClientHelloCopy.pskIdentities) != len(newClientHelloCopy.pskIdentities) { @@ -706,14 +693,8 @@ ResendHelloRetryRequest: } } if encryptedExtensions.extensions.hasEarlyData { - var earlyTrafficSecret []byte - if isDraft22(c.wireVersion) { - earlyTrafficSecret = hs.finishedHash.deriveSecret(earlyTrafficLabelDraft22) - c.earlyExporterSecret = hs.finishedHash.deriveSecret(earlyExporterLabelDraft22) - } else { - earlyTrafficSecret = hs.finishedHash.deriveSecret(earlyTrafficLabel) - c.earlyExporterSecret = hs.finishedHash.deriveSecret(earlyExporterLabel) - } + earlyTrafficSecret := hs.finishedHash.deriveSecret(earlyTrafficLabel) + c.earlyExporterSecret = hs.finishedHash.deriveSecret(earlyExporterLabel) if err := c.useInTrafficSecret(c.wireVersion, hs.suite, earlyTrafficSecret); err != nil { return err @@ -829,18 +810,11 @@ ResendHelloRetryRequest: c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) } - clientLabel := clientHandshakeTrafficLabel - serverLabel := serverHandshakeTrafficLabel - if isDraft22(c.wireVersion) { - clientLabel = clientHandshakeTrafficLabelDraft22 - serverLabel = serverHandshakeTrafficLabelDraft22 - } - // Switch to handshake traffic keys. - serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(serverLabel) + serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(serverHandshakeTrafficLabel) c.useOutTrafficSecret(c.wireVersion, hs.suite, serverHandshakeTrafficSecret) // Derive handshake traffic read key, but don't switch yet. - clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(clientLabel) + clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(clientHandshakeTrafficLabel) // Send EncryptedExtensions. hs.writeServerHash(encryptedExtensions.marshal()) @@ -977,18 +951,9 @@ ResendHelloRetryRequest: hs.finishedHash.nextSecret() hs.finishedHash.addEntropy(hs.finishedHash.zeroSecret()) - clientLabel = clientApplicationTrafficLabel - serverLabel = serverApplicationTrafficLabel - exportLabel := exporterLabel - if isDraft22(c.wireVersion) { - clientLabel = clientApplicationTrafficLabelDraft22 - serverLabel = serverApplicationTrafficLabelDraft22 - exportLabel = exporterLabelDraft22 - } - - clientTrafficSecret := hs.finishedHash.deriveSecret(clientLabel) - serverTrafficSecret := hs.finishedHash.deriveSecret(serverLabel) - c.exporterSecret = hs.finishedHash.deriveSecret(exportLabel) + clientTrafficSecret := hs.finishedHash.deriveSecret(clientApplicationTrafficLabel) + serverTrafficSecret := hs.finishedHash.deriveSecret(serverApplicationTrafficLabel) + c.exporterSecret = hs.finishedHash.deriveSecret(exporterLabel) // Switch to application data keys on write. In particular, any alerts // from the client certificate are sent over these keys. @@ -1003,31 +968,17 @@ ResendHelloRetryRequest: // Read end_of_early_data. if encryptedExtensions.extensions.hasEarlyData { - if isDraft22(c.wireVersion) { - msg, err := c.readHandshake() - if err != nil { - return err - } + msg, err := c.readHandshake() + if err != nil { + return err + } - endOfEarlyData, ok := msg.(*endOfEarlyDataMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(endOfEarlyData, msg) - } - hs.writeClientHash(endOfEarlyData.marshal()) - } else { - if err := c.readRecord(recordTypeAlert); err != errEndOfEarlyDataAlert { - if err == nil { - panic("readRecord(recordTypeAlert) returned nil") - } - return err - } + endOfEarlyData, ok := msg.(*endOfEarlyDataMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(endOfEarlyData, msg) } - } - if !isDraft22(c.wireVersion) && !hs.clientHello.hasEarlyData { - // Early versions of the middlebox hacks inserted - // ChangeCipherSpec differently on 0-RTT and 2-RTT handshakes. - c.expectTLS13ChangeCipherSpec = true + hs.writeClientHash(endOfEarlyData.marshal()) } // Switch input stream to handshake traffic keys. @@ -1142,13 +1093,7 @@ ResendHelloRetryRequest: } c.cipherSuite = hs.suite - - resumeLabel := resumptionLabel - if isDraft22(c.wireVersion) { - resumeLabel = resumptionLabelDraft22 - } - - c.resumptionSecret = hs.finishedHash.deriveSecret(resumeLabel) + c.resumptionSecret = hs.finishedHash.deriveSecret(resumptionLabel) // TODO(davidben): Allow configuring the number of tickets sent for // testing. @@ -2172,11 +2117,7 @@ func verifyPSKBinder(version uint16, clientHello *clientHelloMsg, sessionState * return errors.New("tls: Unknown cipher suite for PSK in session") } - binderLabel := resumptionPSKBinderLabel - if isDraft22(version) { - binderLabel = resumptionPSKBinderLabelDraft22 - } - binder := computePSKBinder(sessionState.masterSecret, version, binderLabel, pskCipherSuite, firstClientHello, helloRetryRequest, truncatedHello) + binder := computePSKBinder(sessionState.masterSecret, version, resumptionPSKBinderLabel, pskCipherSuite, firstClientHello, helloRetryRequest, truncatedHello) if !bytes.Equal(binder, binderToVerify) { return errors.New("tls: PSK binder does not verify") } diff --git a/ssl/test/runner/prf.go b/ssl/test/runner/prf.go index 62c98b73..8c2da0dd 100644 --- a/ssl/test/runner/prf.go +++ b/ssl/test/runner/prf.go @@ -328,7 +328,7 @@ func (h finishedHash) clientSum(baseKey []byte) []byte { return out } - clientFinishedKey := hkdfExpandLabel(h.hash, h.wireVersion, baseKey, finishedLabel, nil, h.hash.Size()) + clientFinishedKey := hkdfExpandLabel(h.hash, baseKey, finishedLabel, nil, h.hash.Size()) finishedHMAC := hmac.New(h.hash.New, clientFinishedKey) finishedHMAC.Write(h.appendContextHashes(nil)) return finishedHMAC.Sum(nil) @@ -347,7 +347,7 @@ func (h finishedHash) serverSum(baseKey []byte) []byte { return out } - serverFinishedKey := hkdfExpandLabel(h.hash, h.wireVersion, baseKey, finishedLabel, nil, h.hash.Size()) + serverFinishedKey := hkdfExpandLabel(h.hash, baseKey, finishedLabel, nil, h.hash.Size()) finishedHMAC := hmac.New(h.hash.New, serverFinishedKey) finishedHMAC.Write(h.appendContextHashes(nil)) return finishedHMAC.Sum(nil) @@ -396,24 +396,17 @@ func (h *finishedHash) addEntropy(ikm []byte) { } func (h *finishedHash) nextSecret() { - if isDraft22(h.wireVersion) { - derivedLabel := []byte("derived") - h.secret = hkdfExpandLabel(h.hash, h.wireVersion, h.secret, derivedLabel, h.hash.New().Sum(nil), h.hash.Size()) - } + h.secret = hkdfExpandLabel(h.hash, h.secret, []byte("derived"), h.hash.New().Sum(nil), h.hash.Size()) } // hkdfExpandLabel implements TLS 1.3's HKDF-Expand-Label function, as defined // in section 7.1 of draft-ietf-tls-tls13-16. -func hkdfExpandLabel(hash crypto.Hash, version uint16, secret, label, hashValue []byte, length int) []byte { +func hkdfExpandLabel(hash crypto.Hash, secret, label, hashValue []byte, length int) []byte { if len(label) > 255 || len(hashValue) > 255 { panic("hkdfExpandLabel: label or hashValue too long") } - versionLabel := []byte("TLS 1.3, ") - if isDraft22(version) { - versionLabel = []byte("tls13 ") - } - + versionLabel := []byte("tls13 ") hkdfLabel := make([]byte, 3+len(versionLabel)+len(label)+1+len(hashValue)) x := hkdfLabel x[0] = byte(length >> 8) @@ -438,29 +431,17 @@ func (h *finishedHash) appendContextHashes(b []byte) []byte { // The following are labels for traffic secret derivation in TLS 1.3. var ( - externalPSKBinderLabel = []byte("external psk binder key") - resumptionPSKBinderLabel = []byte("resumption psk binder key") - earlyTrafficLabel = []byte("client early traffic secret") - clientHandshakeTrafficLabel = []byte("client handshake traffic secret") - serverHandshakeTrafficLabel = []byte("server handshake traffic secret") - clientApplicationTrafficLabel = []byte("client application traffic secret") - serverApplicationTrafficLabel = []byte("server application traffic secret") - applicationTrafficLabel = []byte("application traffic secret") - earlyExporterLabel = []byte("early exporter master secret") - exporterLabel = []byte("exporter master secret") - resumptionLabel = []byte("resumption master secret") - - externalPSKBinderLabelDraft22 = []byte("ext binder") - resumptionPSKBinderLabelDraft22 = []byte("res binder") - earlyTrafficLabelDraft22 = []byte("c e traffic") - clientHandshakeTrafficLabelDraft22 = []byte("c hs traffic") - serverHandshakeTrafficLabelDraft22 = []byte("s hs traffic") - clientApplicationTrafficLabelDraft22 = []byte("c ap traffic") - serverApplicationTrafficLabelDraft22 = []byte("s ap traffic") - applicationTrafficLabelDraft22 = []byte("traffic upd") - earlyExporterLabelDraft22 = []byte("e exp master") - exporterLabelDraft22 = []byte("exp master") - resumptionLabelDraft22 = []byte("res master") + externalPSKBinderLabel = []byte("ext binder") + resumptionPSKBinderLabel = []byte("res binder") + earlyTrafficLabel = []byte("c e traffic") + clientHandshakeTrafficLabel = []byte("c hs traffic") + serverHandshakeTrafficLabel = []byte("s hs traffic") + clientApplicationTrafficLabel = []byte("c ap traffic") + serverApplicationTrafficLabel = []byte("s ap traffic") + applicationTrafficLabel = []byte("traffic upd") + earlyExporterLabel = []byte("e exp master") + exporterLabel = []byte("exp master") + resumptionLabel = []byte("res master") resumptionPSKLabel = []byte("resumption") ) @@ -468,7 +449,7 @@ var ( // deriveSecret implements TLS 1.3's Derive-Secret function, as defined in // section 7.1 of draft ietf-tls-tls13-16. func (h *finishedHash) deriveSecret(label []byte) []byte { - return hkdfExpandLabel(h.hash, h.wireVersion, h.secret, label, h.appendContextHashes(nil), h.hash.Size()) + return hkdfExpandLabel(h.hash, h.secret, label, h.appendContextHashes(nil), h.hash.Size()) } // The following are context strings for CertificateVerify in TLS 1.3. @@ -507,18 +488,14 @@ var ( // deriveTrafficAEAD derives traffic keys and constructs an AEAD given a traffic // secret. func deriveTrafficAEAD(version uint16, suite *cipherSuite, secret []byte, side trafficDirection) interface{} { - key := hkdfExpandLabel(suite.hash(), version, secret, keyTLS13, nil, suite.keyLen) - iv := hkdfExpandLabel(suite.hash(), version, secret, ivTLS13, nil, suite.ivLen(version)) + key := hkdfExpandLabel(suite.hash(), secret, keyTLS13, nil, suite.keyLen) + iv := hkdfExpandLabel(suite.hash(), secret, ivTLS13, nil, suite.ivLen(version)) return suite.aead(version, key, iv) } func updateTrafficSecret(hash crypto.Hash, version uint16, secret []byte) []byte { - trafficLabel := applicationTrafficLabel - if isDraft22(version) { - trafficLabel = applicationTrafficLabelDraft22 - } - return hkdfExpandLabel(hash, version, secret, trafficLabel, nil, hash.Size()) + return hkdfExpandLabel(hash, secret, applicationTrafficLabel, nil, hash.Size()) } func computePSKBinder(psk []byte, version uint16, label []byte, cipherSuite *cipherSuite, clientHello, helloRetryRequest, truncatedHello []byte) []byte { @@ -526,7 +503,7 @@ func computePSKBinder(psk []byte, version uint16, label []byte, cipherSuite *cip finishedHash.addEntropy(psk) binderKey := finishedHash.deriveSecret(label) finishedHash.Write(clientHello) - if isDraft22(version) && len(helloRetryRequest) != 0 { + if len(helloRetryRequest) != 0 { finishedHash.UpdateForHelloRetryRequest() } finishedHash.Write(helloRetryRequest) @@ -536,5 +513,5 @@ func computePSKBinder(psk []byte, version uint16, label []byte, cipherSuite *cip func deriveSessionPSK(suite *cipherSuite, version uint16, masterSecret []byte, nonce []byte) []byte { hash := suite.hash() - return hkdfExpandLabel(hash, version, masterSecret, resumptionPSKLabel, nonce, hash.Size()) + return hkdfExpandLabel(hash, masterSecret, resumptionPSKLabel, nonce, hash.Size()) } diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index 68848ea9..b7825148 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go @@ -1371,13 +1371,6 @@ var tlsVersions = []tlsVersion{ hasDTLS: true, versionDTLS: VersionDTLS12, }, - { - name: "TLS13Draft22", - version: VersionTLS13, - excludeFlag: "-no-tls13", - versionWire: tls13Draft22Version, - tls13Variant: TLS13Draft22, - }, { name: "TLS13Draft23", version: VersionTLS13, @@ -1385,13 +1378,6 @@ var tlsVersions = []tlsVersion{ versionWire: tls13Draft23Version, tls13Variant: TLS13Draft23, }, - { - name: "TLS13Experiment2", - version: VersionTLS13, - excludeFlag: "-no-tls13", - versionWire: tls13Experiment2Version, - tls13Variant: TLS13Experiment2, - }, } func allVersions(protocol protocol) []tlsVersion { @@ -2854,20 +2840,20 @@ read alert 1 0 }, { testType: clientTest, - name: "TLS13Draft22-InvalidCompressionMethod", + name: "TLS13Draft23-InvalidCompressionMethod", config: Config{ MaxVersion: VersionTLS13, Bugs: ProtocolBugs{ SendCompressionMethod: 1, }, }, - tls13Variant: TLS13Draft22, + tls13Variant: TLS13Draft23, shouldFail: true, expectedError: ":DECODE_ERROR:", }, { testType: clientTest, - name: "TLS13Draft22-HRR-InvalidCompressionMethod", + name: "TLS13Draft23-HRR-InvalidCompressionMethod", config: Config{ MaxVersion: VersionTLS13, CurvePreferences: []CurveID{CurveP384}, @@ -2875,7 +2861,7 @@ read alert 1 0 SendCompressionMethod: 1, }, }, - tls13Variant: TLS13Draft22, + tls13Variant: TLS13Draft23, shouldFail: true, expectedError: ":DECODE_ERROR:", expectedLocalError: "remote error: error decoding message", @@ -3968,7 +3954,7 @@ func addClientAuthTests() { // Test that an empty client CA list doesn't send a CA extension. testCases = append(testCases, testCase{ testType: serverTest, - name: "TLS13Draft22-Empty-Client-CA-List", + name: "TLS13Draft23-Empty-Client-CA-List", config: Config{ MaxVersion: VersionTLS13, Certificates: []Certificate{rsaCertificate}, @@ -3976,7 +3962,7 @@ func addClientAuthTests() { ExpectNoCertificateAuthoritiesExtension: true, }, }, - tls13Variant: TLS13Draft22, + tls13Variant: TLS13Draft23, flags: []string{ "-require-any-client-certificate", "-use-client-ca-list", "", @@ -4334,7 +4320,7 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { }) tests = append(tests, testCase{ - name: "TLS13Draft22-HelloRetryRequest-Client", + name: "TLS13Draft23-HelloRetryRequest-Client", config: Config{ MaxVersion: VersionTLS13, MinVersion: VersionTLS13, @@ -4345,21 +4331,21 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { ExpectMissingKeyShare: true, }, }, - tls13Variant: TLS13Draft22, + tls13Variant: TLS13Draft23, // Cover HelloRetryRequest during an ECDHE-PSK resumption. resumeSession: true, }) tests = append(tests, testCase{ testType: serverTest, - name: "TLS13Draft22-HelloRetryRequest-Server", + name: "TLS13Draft23-HelloRetryRequest-Server", config: Config{ MaxVersion: VersionTLS13, MinVersion: VersionTLS13, // Require a HelloRetryRequest for every curve. DefaultCurves: []CurveID{}, }, - tls13Variant: TLS13Draft22, + tls13Variant: TLS13Draft23, // Cover HelloRetryRequest during an ECDHE-PSK resumption. resumeSession: true, }) @@ -7903,14 +7889,14 @@ func addRenegotiationTests() { }, }) testCases = append(testCases, testCase{ - name: "Renegotiate-Client-TLS13Draft22", + name: "Renegotiate-Client-TLS13Draft23", config: Config{ MaxVersion: VersionTLS12, Bugs: ProtocolBugs{ FailIfResumeOnRenego: true, }, }, - tls13Variant: TLS13Draft22, + tls13Variant: TLS13Draft23, renegotiate: 1, // Test renegotiation after both an initial and resumption // handshake. @@ -11717,7 +11703,7 @@ func makePerMessageTests() []perMessageTest { messageType: typeEndOfEarlyData, test: testCase{ testType: serverTest, - name: "TLS13Draft22-EndOfEarlyData", + name: "TLS13Draft23-EndOfEarlyData", config: Config{ MaxVersion: VersionTLS13, }, @@ -11728,7 +11714,7 @@ func makePerMessageTests() []perMessageTest { ExpectEarlyDataAccepted: true, }, }, - tls13Variant: TLS13Draft22, + tls13Variant: TLS13Draft23, resumeSession: true, flags: []string{"-enable-early-data"}, }, @@ -12275,50 +12261,48 @@ func addTLS13HandshakeTests() { expectedError: ":WRONG_CURVE:", }) - if isDraft22(version.versionWire) { - testCases = append(testCases, testCase{ - name: "HelloRetryRequest-CipherChange-" + name, - config: Config{ - MaxVersion: VersionTLS13, - // P-384 requires HelloRetryRequest in BoringSSL. - CurvePreferences: []CurveID{CurveP384}, - Bugs: ProtocolBugs{ - SendCipherSuite: TLS_AES_128_GCM_SHA256, - SendHelloRetryRequestCipherSuite: TLS_CHACHA20_POLY1305_SHA256, - }, + testCases = append(testCases, testCase{ + name: "HelloRetryRequest-CipherChange-" + name, + config: Config{ + MaxVersion: VersionTLS13, + // P-384 requires HelloRetryRequest in BoringSSL. + CurvePreferences: []CurveID{CurveP384}, + Bugs: ProtocolBugs{ + SendCipherSuite: TLS_AES_128_GCM_SHA256, + SendHelloRetryRequestCipherSuite: TLS_CHACHA20_POLY1305_SHA256, }, - tls13Variant: variant, - shouldFail: true, - expectedError: ":WRONG_CIPHER_RETURNED:", - }) + }, + tls13Variant: variant, + shouldFail: true, + expectedError: ":WRONG_CIPHER_RETURNED:", + }) - // Test that the client does not offer a PSK in the second ClientHello if the - // HelloRetryRequest is incompatible with it. - testCases = append(testCases, testCase{ - testType: clientTest, - name: "HelloRetryRequest-NonResumableCipher-" + name, - config: Config{ - MaxVersion: VersionTLS13, - CipherSuites: []uint16{ - TLS_AES_128_GCM_SHA256, - }, + // Test that the client does not offer a PSK in the second ClientHello if the + // HelloRetryRequest is incompatible with it. + testCases = append(testCases, testCase{ + testType: clientTest, + name: "HelloRetryRequest-NonResumableCipher-" + name, + config: Config{ + MaxVersion: VersionTLS13, + CipherSuites: []uint16{ + TLS_AES_128_GCM_SHA256, }, - resumeConfig: &Config{ - MaxVersion: VersionTLS13, - // P-384 requires HelloRetryRequest in BoringSSL. - CurvePreferences: []CurveID{CurveP384}, - Bugs: ProtocolBugs{ - ExpectNoTLS13PSKAfterHRR: true, - }, - CipherSuites: []uint16{ - TLS_AES_256_GCM_SHA384, - }, + }, + resumeConfig: &Config{ + MaxVersion: VersionTLS13, + // P-384 requires HelloRetryRequest in BoringSSL. + CurvePreferences: []CurveID{CurveP384}, + Bugs: ProtocolBugs{ + ExpectNoTLS13PSKAfterHRR: true, }, - tls13Variant: variant, - resumeSession: true, - expectResumeRejected: true, - }) - } + CipherSuites: []uint16{ + TLS_AES_256_GCM_SHA384, + }, + }, + tls13Variant: variant, + resumeSession: true, + expectResumeRejected: true, + }) testCases = append(testCases, testCase{ name: "DisabledCurve-HelloRetryRequest-" + name, @@ -12562,43 +12546,41 @@ func addTLS13HandshakeTests() { expectedError: ":DECODE_ERROR:", }) - if isDraft22(version.versionWire) { - testCases = append(testCases, testCase{ - name: "UnknownExtensionInCertificateRequest-" + name, - config: Config{ - MaxVersion: VersionTLS13, - MinVersion: VersionTLS13, - ClientAuth: RequireAnyClientCert, - Bugs: ProtocolBugs{ - SendCustomCertificateRequest: 0x1212, - }, - }, - tls13Variant: variant, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), + testCases = append(testCases, testCase{ + name: "UnknownExtensionInCertificateRequest-" + name, + config: Config{ + MaxVersion: VersionTLS13, + MinVersion: VersionTLS13, + ClientAuth: RequireAnyClientCert, + Bugs: ProtocolBugs{ + SendCustomCertificateRequest: 0x1212, }, - }) + }, + tls13Variant: variant, + flags: []string{ + "-cert-file", path.Join(*resourceDir, rsaCertificateFile), + "-key-file", path.Join(*resourceDir, rsaKeyFile), + }, + }) - testCases = append(testCases, testCase{ - name: "MissingSignatureAlgorithmsInCertificateRequest-" + name, - config: Config{ - MaxVersion: VersionTLS13, - MinVersion: VersionTLS13, - ClientAuth: RequireAnyClientCert, - Bugs: ProtocolBugs{ - OmitCertificateRequestAlgorithms: true, - }, - }, - tls13Variant: variant, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), + testCases = append(testCases, testCase{ + name: "MissingSignatureAlgorithmsInCertificateRequest-" + name, + config: Config{ + MaxVersion: VersionTLS13, + MinVersion: VersionTLS13, + ClientAuth: RequireAnyClientCert, + Bugs: ProtocolBugs{ + OmitCertificateRequestAlgorithms: true, }, - shouldFail: true, - expectedError: ":DECODE_ERROR:", - }) - } + }, + tls13Variant: variant, + flags: []string{ + "-cert-file", path.Join(*resourceDir, rsaCertificateFile), + "-key-file", path.Join(*resourceDir, rsaKeyFile), + }, + shouldFail: true, + expectedError: ":DECODE_ERROR:", + }) testCases = append(testCases, testCase{ testType: serverTest, @@ -12795,73 +12777,71 @@ func addTLS13HandshakeTests() { expectedError: ":UNEXPECTED_EXTENSION:", }) - if isDraft22(version.versionWire) { - testCases = append(testCases, testCase{ - testType: clientTest, - name: "SkipChangeCipherSpec-Client-" + name, - config: Config{ - MaxVersion: VersionTLS13, - Bugs: ProtocolBugs{ - SkipChangeCipherSpec: true, - }, + testCases = append(testCases, testCase{ + testType: clientTest, + name: "SkipChangeCipherSpec-Client-" + name, + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SkipChangeCipherSpec: true, }, - tls13Variant: variant, - }) + }, + tls13Variant: variant, + }) - testCases = append(testCases, testCase{ - testType: serverTest, - name: "SkipChangeCipherSpec-Server-" + name, - config: Config{ - MaxVersion: VersionTLS13, - Bugs: ProtocolBugs{ - SkipChangeCipherSpec: true, - }, + testCases = append(testCases, testCase{ + testType: serverTest, + name: "SkipChangeCipherSpec-Server-" + name, + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SkipChangeCipherSpec: true, }, - tls13Variant: variant, - }) + }, + tls13Variant: variant, + }) - testCases = append(testCases, testCase{ - testType: clientTest, - name: "TooManyChangeCipherSpec-Client-" + name, - config: Config{ - MaxVersion: VersionTLS13, - Bugs: ProtocolBugs{ - SendExtraChangeCipherSpec: 33, - }, + testCases = append(testCases, testCase{ + testType: clientTest, + name: "TooManyChangeCipherSpec-Client-" + name, + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendExtraChangeCipherSpec: 33, }, - tls13Variant: variant, - shouldFail: true, - expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", - }) + }, + tls13Variant: variant, + shouldFail: true, + expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", + }) - testCases = append(testCases, testCase{ - testType: serverTest, - name: "TooManyChangeCipherSpec-Server-" + name, - config: Config{ - MaxVersion: VersionTLS13, - Bugs: ProtocolBugs{ - SendExtraChangeCipherSpec: 33, - }, + testCases = append(testCases, testCase{ + testType: serverTest, + name: "TooManyChangeCipherSpec-Server-" + name, + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendExtraChangeCipherSpec: 33, }, - tls13Variant: variant, - shouldFail: true, - expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", - }) + }, + tls13Variant: variant, + shouldFail: true, + expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", + }) - testCases = append(testCases, testCase{ - name: "SendPostHandshakeChangeCipherSpec-" + name, - config: Config{ - MaxVersion: VersionTLS13, - Bugs: ProtocolBugs{ - SendPostHandshakeChangeCipherSpec: true, - }, + testCases = append(testCases, testCase{ + name: "SendPostHandshakeChangeCipherSpec-" + name, + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendPostHandshakeChangeCipherSpec: true, }, - tls13Variant: variant, - shouldFail: true, - expectedError: ":UNEXPECTED_RECORD:", - expectedLocalError: "remote error: unexpected message", - }) - } + }, + tls13Variant: variant, + shouldFail: true, + expectedError: ":UNEXPECTED_RECORD:", + expectedLocalError: "remote error: unexpected message", + }) fooString := "foo" barString := "bar" @@ -13243,13 +13223,6 @@ func addTLS13HandshakeTests() { expectedError: ":BAD_DECRYPT:", }) - expectedError := ":UNEXPECTED_RECORD:" - if isDraft22(version.versionWire) { - // In draft-21 and up, early data is expected to be - // terminated by a handshake message, though we test - // with the wrong one. - expectedError = ":UNEXPECTED_MESSAGE:" - } testCases = append(testCases, testCase{ testType: serverTest, name: "EarlyData-UnexpectedHandshake-Server-" + name, @@ -13267,7 +13240,7 @@ func addTLS13HandshakeTests() { tls13Variant: variant, resumeSession: true, shouldFail: true, - expectedError: expectedError, + expectedError: ":UNEXPECTED_MESSAGE:", expectedLocalError: "remote error: unexpected message", flags: []string{ "-enable-early-data", @@ -13346,32 +13319,30 @@ func addTLS13HandshakeTests() { expectedLocalError: "remote error: error decrypting message", }) - if isDraft22(version.versionWire) { - testCases = append(testCases, testCase{ - testType: serverTest, - name: "Server-NonEmptyEndOfEarlyData-" + name, - config: Config{ - MaxVersion: VersionTLS13, - }, - resumeConfig: &Config{ - MaxVersion: VersionTLS13, - Bugs: ProtocolBugs{ - SendEarlyData: [][]byte{{1, 2, 3, 4}}, - ExpectEarlyDataAccepted: true, - NonEmptyEndOfEarlyData: true, - }, - }, - resumeSession: true, - flags: []string{ - "-enable-early-data", - "-expect-ticket-supports-early-data", - "-expect-accept-early-data", + testCases = append(testCases, testCase{ + testType: serverTest, + name: "Server-NonEmptyEndOfEarlyData-" + name, + config: Config{ + MaxVersion: VersionTLS13, + }, + resumeConfig: &Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendEarlyData: [][]byte{{1, 2, 3, 4}}, + ExpectEarlyDataAccepted: true, + NonEmptyEndOfEarlyData: true, }, - tls13Variant: variant, - shouldFail: true, - expectedError: ":DECODE_ERROR:", - }) - } + }, + resumeSession: true, + flags: []string{ + "-enable-early-data", + "-expect-ticket-supports-early-data", + "-expect-accept-early-data", + }, + tls13Variant: variant, + shouldFail: true, + expectedError: ":DECODE_ERROR:", + }) testCases = append(testCases, testCase{ testType: serverTest, diff --git a/ssl/tls13_client.cc b/ssl/tls13_client.cc index f013afda..aa054563 100644 --- a/ssl/tls13_client.cc +++ b/ssl/tls13_client.cc @@ -58,88 +58,63 @@ static enum ssl_hs_wait_t do_read_hello_retry_request(SSL_HANDSHAKE *hs) { return ssl_hs_read_message; } - CBS extensions; - uint16_t cipher_suite = 0; - if (ssl_is_draft22(ssl->version)) { - // Queue up a ChangeCipherSpec for whenever we next send something. This - // will be before the second ClientHello. If we offered early data, this was - // already done. - if (!hs->early_data_offered && - !ssl->method->add_change_cipher_spec(ssl)) { - return ssl_hs_error; - } - - if (!ssl_check_message_type(ssl, msg, SSL3_MT_SERVER_HELLO)) { - return ssl_hs_error; - } + // Queue up a ChangeCipherSpec for whenever we next send something. This + // will be before the second ClientHello. If we offered early data, this was + // already done. + if (!hs->early_data_offered && + !ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; + } - CBS body = msg.body, server_random, session_id; - uint16_t server_version; - uint8_t compression_method; - if (!CBS_get_u16(&body, &server_version) || - !CBS_get_bytes(&body, &server_random, SSL3_RANDOM_SIZE) || - !CBS_get_u8_length_prefixed(&body, &session_id) || - !CBS_mem_equal(&session_id, hs->session_id, hs->session_id_len) || - !CBS_get_u16(&body, &cipher_suite) || - !CBS_get_u8(&body, &compression_method) || - compression_method != 0 || - !CBS_get_u16_length_prefixed(&body, &extensions) || - CBS_len(&extensions) == 0 || - CBS_len(&body) != 0) { - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); - ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - return ssl_hs_error; - } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_SERVER_HELLO)) { + return ssl_hs_error; + } - if (!CBS_mem_equal(&server_random, kHelloRetryRequest, SSL3_RANDOM_SIZE)) { - hs->tls13_state = state_read_server_hello; - return ssl_hs_ok; - } - } else { - if (msg.type != SSL3_MT_HELLO_RETRY_REQUEST) { - hs->tls13_state = state_read_server_hello; - return ssl_hs_ok; - } + CBS body = msg.body, extensions, server_random, session_id; + uint16_t server_version, cipher_suite; + uint8_t compression_method; + if (!CBS_get_u16(&body, &server_version) || + !CBS_get_bytes(&body, &server_random, SSL3_RANDOM_SIZE) || + !CBS_get_u8_length_prefixed(&body, &session_id) || + !CBS_mem_equal(&session_id, hs->session_id, hs->session_id_len) || + !CBS_get_u16(&body, &cipher_suite) || + !CBS_get_u8(&body, &compression_method) || + compression_method != 0 || + !CBS_get_u16_length_prefixed(&body, &extensions) || + CBS_len(&extensions) == 0 || + CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } - CBS body = msg.body; - uint16_t server_version; - if (!CBS_get_u16(&body, &server_version) || - (ssl_is_draft22(ssl->version) && - !CBS_get_u16(&body, &cipher_suite)) || - !CBS_get_u16_length_prefixed(&body, &extensions) || - CBS_len(&body) != 0) { - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); - ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - return ssl_hs_error; - } + if (!CBS_mem_equal(&server_random, kHelloRetryRequest, SSL3_RANDOM_SIZE)) { + hs->tls13_state = state_read_server_hello; + return ssl_hs_ok; } - if (ssl_is_draft22(ssl->version)) { - const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite); - // Check if the cipher is a TLS 1.3 cipher. - if (cipher == NULL || - SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) || - SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl)) { - OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); - ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); - return ssl_hs_error; - } + const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite); + // Check if the cipher is a TLS 1.3 cipher. + if (cipher == NULL || + SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) || + SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } - hs->new_cipher = cipher; + hs->new_cipher = cipher; - if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) || - !hs->transcript.UpdateForHelloRetryRequest()) { - return ssl_hs_error; - } + if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) || + !hs->transcript.UpdateForHelloRetryRequest()) { + return ssl_hs_error; } bool have_cookie, have_key_share, have_supported_versions; CBS cookie, key_share, supported_versions; SSL_EXTENSION_TYPE ext_types[] = { - {ssl_is_draft23(ssl->version) ? (uint16_t)TLSEXT_TYPE_new_key_share - : (uint16_t)TLSEXT_TYPE_old_key_share, - &have_key_share, &key_share}, + {TLSEXT_TYPE_key_share, &have_key_share, &key_share}, {TLSEXT_TYPE_cookie, &have_cookie, &cookie}, {TLSEXT_TYPE_supported_versions, &have_supported_versions, &supported_versions}, @@ -153,11 +128,6 @@ static enum ssl_hs_wait_t do_read_hello_retry_request(SSL_HANDSHAKE *hs) { return ssl_hs_error; } - if (!ssl_is_draft22(ssl->version) && have_supported_versions) { - OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); - ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); - return ssl_hs_error; - } if (!have_cookie && !have_key_share) { OPENSSL_PUT_ERROR(SSL, SSL_R_EMPTY_HELLO_RETRY_REQUEST); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); @@ -274,8 +244,7 @@ static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { } // Forbid a second HelloRetryRequest. - if (ssl_is_draft22(ssl->version) && - CBS_mem_equal(&server_random, kHelloRetryRequest, SSL3_RANDOM_SIZE)) { + if (CBS_mem_equal(&server_random, kHelloRetryRequest, SSL3_RANDOM_SIZE)) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); return ssl_hs_error; @@ -295,8 +264,7 @@ static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { } // Check that the cipher matches the one in the HelloRetryRequest. - if (ssl_is_draft22(ssl->version) && - hs->received_hello_retry_request && + if (hs->received_hello_retry_request && hs->new_cipher != cipher) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); @@ -308,9 +276,7 @@ static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { have_supported_versions = false; CBS key_share, pre_shared_key, supported_versions; SSL_EXTENSION_TYPE ext_types[] = { - {ssl_is_draft23(ssl->version) ? (uint16_t)TLSEXT_TYPE_new_key_share - : (uint16_t)TLSEXT_TYPE_old_key_share, - &have_key_share, &key_share}, + {TLSEXT_TYPE_key_share, &have_key_share, &key_share}, {TLSEXT_TYPE_pre_shared_key, &have_pre_shared_key, &pre_shared_key}, {TLSEXT_TYPE_supported_versions, &have_supported_versions, &supported_versions}, @@ -416,13 +382,6 @@ static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { } if (!hs->early_data_offered) { - // Earlier versions of the resumption experiment added ChangeCipherSpec just - // before the Finished flight. - if (!ssl_is_draft22(ssl->version) && - !ssl->method->add_change_cipher_spec(ssl)) { - return ssl_hs_error; - } - // If not sending early data, set client traffic keys now so that alerts are // encrypted. if (!tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret, @@ -515,75 +474,45 @@ static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) { } - if (ssl_is_draft22(ssl->version)) { - bool have_sigalgs = false, have_ca = false; - CBS sigalgs, ca; - const SSL_EXTENSION_TYPE ext_types[] = { - {TLSEXT_TYPE_signature_algorithms, &have_sigalgs, &sigalgs}, - {TLSEXT_TYPE_certificate_authorities, &have_ca, &ca}, - }; - - CBS body = msg.body, context, extensions, supported_signature_algorithms; - uint8_t alert = SSL_AD_DECODE_ERROR; - if (!CBS_get_u8_length_prefixed(&body, &context) || - // The request context is always empty during the handshake. - CBS_len(&context) != 0 || - !CBS_get_u16_length_prefixed(&body, &extensions) || - CBS_len(&body) != 0 || - !ssl_parse_extensions(&extensions, &alert, ext_types, - OPENSSL_ARRAY_SIZE(ext_types), - 1 /* accept unknown */) || - (have_ca && CBS_len(&ca) == 0) || - !have_sigalgs || - !CBS_get_u16_length_prefixed(&sigalgs, - &supported_signature_algorithms) || - CBS_len(&supported_signature_algorithms) == 0 || - !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) { - ssl_send_alert(ssl, SSL3_AL_FATAL, alert); - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); - return ssl_hs_error; - } + bool have_sigalgs = false, have_ca = false; + CBS sigalgs, ca; + const SSL_EXTENSION_TYPE ext_types[] = { + {TLSEXT_TYPE_signature_algorithms, &have_sigalgs, &sigalgs}, + {TLSEXT_TYPE_certificate_authorities, &have_ca, &ca}, + }; - if (have_ca) { - hs->ca_names = ssl_parse_client_CA_list(ssl, &alert, &ca); - if (!hs->ca_names) { - ssl_send_alert(ssl, SSL3_AL_FATAL, alert); - return ssl_hs_error; - } - } else { - hs->ca_names.reset(sk_CRYPTO_BUFFER_new_null()); - if (!hs->ca_names) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - return ssl_hs_error; - } - } - } else { - CBS body = msg.body, context, supported_signature_algorithms; - if (!CBS_get_u8_length_prefixed(&body, &context) || - // The request context is always empty during the handshake. - CBS_len(&context) != 0 || - !CBS_get_u16_length_prefixed(&body, &supported_signature_algorithms) || - CBS_len(&supported_signature_algorithms) == 0 || - !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) { - ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); - return ssl_hs_error; - } + CBS body = msg.body, context, extensions, supported_signature_algorithms; + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!CBS_get_u8_length_prefixed(&body, &context) || + // The request context is always empty during the handshake. + CBS_len(&context) != 0 || + !CBS_get_u16_length_prefixed(&body, &extensions) || + CBS_len(&body) != 0 || + !ssl_parse_extensions(&extensions, &alert, ext_types, + OPENSSL_ARRAY_SIZE(ext_types), + 1 /* accept unknown */) || + (have_ca && CBS_len(&ca) == 0) || + !have_sigalgs || + !CBS_get_u16_length_prefixed(&sigalgs, + &supported_signature_algorithms) || + CBS_len(&supported_signature_algorithms) == 0 || + !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } - uint8_t alert = SSL_AD_DECODE_ERROR; - hs->ca_names = ssl_parse_client_CA_list(ssl, &alert, &body); + if (have_ca) { + hs->ca_names = ssl_parse_client_CA_list(ssl, &alert, &ca); if (!hs->ca_names) { ssl_send_alert(ssl, SSL3_AL_FATAL, alert); return ssl_hs_error; } - - // Ignore extensions. - CBS extensions; - if (!CBS_get_u16_length_prefixed(&body, &extensions) || - CBS_len(&body) != 0) { - ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + } else { + hs->ca_names.reset(sk_CRYPTO_BUFFER_new_null()); + if (!hs->ca_names) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return ssl_hs_error; } } @@ -670,19 +599,12 @@ static enum ssl_hs_wait_t do_send_end_of_early_data(SSL_HANDSHAKE *hs) { if (ssl->s3->early_data_accepted) { hs->can_early_write = false; - if (ssl_is_draft22(ssl->version)) { - ScopedCBB cbb; - CBB body; - if (!ssl->method->init_message(ssl, cbb.get(), &body, - SSL3_MT_END_OF_EARLY_DATA) || - !ssl_add_message_cbb(ssl, cbb.get())) { - return ssl_hs_error; - } - } else { - if (!ssl->method->add_alert(ssl, SSL3_AL_WARNING, - TLS1_AD_END_OF_EARLY_DATA)) { - return ssl_hs_error; - } + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_END_OF_EARLY_DATA) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; } } @@ -909,8 +831,7 @@ int tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg) { CBS body = msg.body, ticket_nonce, ticket, extensions; if (!CBS_get_u32(&body, &server_timeout) || !CBS_get_u32(&body, &session->ticket_age_add) || - (ssl_is_draft22(ssl->version) && - !CBS_get_u8_length_prefixed(&body, &ticket_nonce)) || + !CBS_get_u8_length_prefixed(&body, &ticket_nonce) || !CBS_get_u16_length_prefixed(&body, &ticket) || !CBS_stow(&ticket, &session->tlsext_tick, &session->tlsext_ticklen) || !CBS_get_u16_length_prefixed(&body, &extensions) || @@ -933,11 +854,8 @@ int tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg) { // Parse out the extensions. bool have_early_data_info = false; CBS early_data_info; - uint16_t ext_id = ssl_is_draft22(ssl->version) - ? TLSEXT_TYPE_early_data - : TLSEXT_TYPE_ticket_early_data_info; const SSL_EXTENSION_TYPE ext_types[] = { - {ext_id, &have_early_data_info, &early_data_info}, + {TLSEXT_TYPE_early_data, &have_early_data_info, &early_data_info}, }; uint8_t alert = SSL_AD_DECODE_ERROR; diff --git a/ssl/tls13_enc.cc b/ssl/tls13_enc.cc index 1bf820ea..cc7afb8d 100644 --- a/ssl/tls13_enc.cc +++ b/ssl/tls13_enc.cc @@ -66,13 +66,11 @@ int tls13_init_early_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *psk, psk_len, hs->secret, hs->hash_len); } -static int hkdf_expand_label(uint8_t *out, uint16_t version, - const EVP_MD *digest, const uint8_t *secret, - size_t secret_len, const char *label, - size_t label_len, const uint8_t *hash, - size_t hash_len, size_t len) { - const char *kTLS13LabelVersion = - ssl_is_draft22(version) ? "tls13 " : "TLS 1.3, "; +static int hkdf_expand_label(uint8_t *out, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, + const char *label, size_t label_len, + const uint8_t *hash, size_t hash_len, size_t len) { + static const char kTLS13LabelVersion[] = "tls13 "; ScopedCBB cbb; CBB child; @@ -101,23 +99,18 @@ static const char kTLS13LabelDerived[] = "derived"; int tls13_advance_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *in, size_t len) { - SSL *const ssl = hs->ssl; - - // Draft 18 does not include the extra Derive-Secret step. - if (ssl_is_draft22(ssl->version)) { - uint8_t derive_context[EVP_MAX_MD_SIZE]; - unsigned derive_context_len; - if (!EVP_Digest(nullptr, 0, derive_context, &derive_context_len, - hs->transcript.Digest(), nullptr)) { - return 0; - } + uint8_t derive_context[EVP_MAX_MD_SIZE]; + unsigned derive_context_len; + if (!EVP_Digest(nullptr, 0, derive_context, &derive_context_len, + hs->transcript.Digest(), nullptr)) { + return 0; + } - if (!hkdf_expand_label(hs->secret, ssl->version, hs->transcript.Digest(), - hs->secret, hs->hash_len, kTLS13LabelDerived, - strlen(kTLS13LabelDerived), derive_context, - derive_context_len, hs->hash_len)) { - return 0; - } + if (!hkdf_expand_label(hs->secret, hs->transcript.Digest(), hs->secret, + hs->hash_len, kTLS13LabelDerived, + strlen(kTLS13LabelDerived), derive_context, + derive_context_len, hs->hash_len)) { + return 0; } return HKDF_extract(hs->secret, &hs->hash_len, hs->transcript.Digest(), in, @@ -135,10 +128,9 @@ static int derive_secret(SSL_HANDSHAKE *hs, uint8_t *out, size_t len, return 0; } - return hkdf_expand_label(out, SSL_get_session(hs->ssl)->ssl_version, - hs->transcript.Digest(), hs->secret, hs->hash_len, - label, label_len, context_hash, context_hash_len, - len); + return hkdf_expand_label(out, hs->transcript.Digest(), hs->secret, + hs->hash_len, label, label_len, context_hash, + context_hash_len, len); } int tls13_set_traffic_key(SSL *ssl, enum evp_aead_direction_t direction, @@ -165,16 +157,16 @@ int tls13_set_traffic_key(SSL *ssl, enum evp_aead_direction_t direction, // Derive the key. size_t key_len = EVP_AEAD_key_length(aead); uint8_t key[EVP_AEAD_MAX_KEY_LENGTH]; - if (!hkdf_expand_label(key, session->ssl_version, digest, traffic_secret, - traffic_secret_len, "key", 3, NULL, 0, key_len)) { + if (!hkdf_expand_label(key, digest, traffic_secret, traffic_secret_len, "key", + 3, NULL, 0, key_len)) { return 0; } // Derive the IV. size_t iv_len = EVP_AEAD_nonce_length(aead); uint8_t iv[EVP_AEAD_MAX_NONCE_LENGTH]; - if (!hkdf_expand_label(iv, session->ssl_version, digest, traffic_secret, - traffic_secret_len, "iv", 2, NULL, 0, iv_len)) { + if (!hkdf_expand_label(iv, digest, traffic_secret, traffic_secret_len, "iv", + 2, NULL, 0, iv_len)) { return 0; } @@ -210,45 +202,26 @@ int tls13_set_traffic_key(SSL *ssl, enum evp_aead_direction_t direction, return 1; } -static const char kTLS13LabelExporter[] = "exporter master secret"; -static const char kTLS13LabelEarlyExporter[] = "early exporter master secret"; - -static const char kTLS13LabelClientEarlyTraffic[] = - "client early traffic secret"; -static const char kTLS13LabelClientHandshakeTraffic[] = - "client handshake traffic secret"; -static const char kTLS13LabelServerHandshakeTraffic[] = - "server handshake traffic secret"; -static const char kTLS13LabelClientApplicationTraffic[] = - "client application traffic secret"; -static const char kTLS13LabelServerApplicationTraffic[] = - "server application traffic secret"; - -static const char kTLS13Draft22LabelExporter[] = "exp master"; -static const char kTLS13Draft22LabelEarlyExporter[] = "e exp master"; - -static const char kTLS13Draft22LabelClientEarlyTraffic[] = "c e traffic"; -static const char kTLS13Draft22LabelClientHandshakeTraffic[] = "c hs traffic"; -static const char kTLS13Draft22LabelServerHandshakeTraffic[] = "s hs traffic"; -static const char kTLS13Draft22LabelClientApplicationTraffic[] = "c ap traffic"; -static const char kTLS13Draft22LabelServerApplicationTraffic[] = "s ap traffic"; + +static const char kTLS13LabelExporter[] = "exp master"; +static const char kTLS13LabelEarlyExporter[] = "e exp master"; + +static const char kTLS13LabelClientEarlyTraffic[] = "c e traffic"; +static const char kTLS13LabelClientHandshakeTraffic[] = "c hs traffic"; +static const char kTLS13LabelServerHandshakeTraffic[] = "s hs traffic"; +static const char kTLS13LabelClientApplicationTraffic[] = "c ap traffic"; +static const char kTLS13LabelServerApplicationTraffic[] = "s ap traffic"; int tls13_derive_early_secrets(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; - uint16_t version = SSL_get_session(ssl)->ssl_version; - - const char *early_traffic_label = ssl_is_draft22(version) - ? kTLS13Draft22LabelClientEarlyTraffic - : kTLS13LabelClientEarlyTraffic; - const char *early_exporter_label = ssl_is_draft22(version) - ? kTLS13Draft22LabelEarlyExporter - : kTLS13LabelEarlyExporter; if (!derive_secret(hs, hs->early_traffic_secret, hs->hash_len, - early_traffic_label, strlen(early_traffic_label)) || + kTLS13LabelClientEarlyTraffic, + strlen(kTLS13LabelClientEarlyTraffic)) || !ssl_log_secret(ssl, "CLIENT_EARLY_TRAFFIC_SECRET", hs->early_traffic_secret, hs->hash_len) || !derive_secret(hs, ssl->s3->early_exporter_secret, hs->hash_len, - early_exporter_label, strlen(early_exporter_label))) { + kTLS13LabelEarlyExporter, + strlen(kTLS13LabelEarlyExporter))) { return 0; } ssl->s3->early_exporter_secret_len = hs->hash_len; @@ -257,18 +230,14 @@ int tls13_derive_early_secrets(SSL_HANDSHAKE *hs) { int tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; - const char *client_label = ssl_is_draft22(ssl->version) - ? kTLS13Draft22LabelClientHandshakeTraffic - : kTLS13LabelClientHandshakeTraffic; - const char *server_label = ssl_is_draft22(ssl->version) - ? kTLS13Draft22LabelServerHandshakeTraffic - : kTLS13LabelServerHandshakeTraffic; return derive_secret(hs, hs->client_handshake_secret, hs->hash_len, - client_label, strlen(client_label)) && + kTLS13LabelClientHandshakeTraffic, + strlen(kTLS13LabelClientHandshakeTraffic)) && ssl_log_secret(ssl, "CLIENT_HANDSHAKE_TRAFFIC_SECRET", hs->client_handshake_secret, hs->hash_len) && derive_secret(hs, hs->server_handshake_secret, hs->hash_len, - server_label, strlen(server_label)) && + kTLS13LabelServerHandshakeTraffic, + strlen(kTLS13LabelServerHandshakeTraffic)) && ssl_log_secret(ssl, "SERVER_HANDSHAKE_TRAFFIC_SECRET", hs->server_handshake_secret, hs->hash_len); } @@ -276,32 +245,23 @@ int tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) { int tls13_derive_application_secrets(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; ssl->s3->exporter_secret_len = hs->hash_len; - const char *client_label = ssl_is_draft22(ssl->version) - ? kTLS13Draft22LabelClientApplicationTraffic - : kTLS13LabelClientApplicationTraffic; - const char *server_label = ssl_is_draft22(ssl->version) - ? kTLS13Draft22LabelServerApplicationTraffic - : kTLS13LabelServerApplicationTraffic; - const char *exporter_label = ssl_is_draft22(ssl->version) - ? kTLS13Draft22LabelExporter - : kTLS13LabelExporter; return derive_secret(hs, hs->client_traffic_secret_0, hs->hash_len, - client_label, strlen(client_label)) && + kTLS13LabelClientApplicationTraffic, + strlen(kTLS13LabelClientApplicationTraffic)) && ssl_log_secret(ssl, "CLIENT_TRAFFIC_SECRET_0", hs->client_traffic_secret_0, hs->hash_len) && derive_secret(hs, hs->server_traffic_secret_0, hs->hash_len, - server_label, strlen(server_label)) && + kTLS13LabelServerApplicationTraffic, + strlen(kTLS13LabelServerApplicationTraffic)) && ssl_log_secret(ssl, "SERVER_TRAFFIC_SECRET_0", hs->server_traffic_secret_0, hs->hash_len) && derive_secret(hs, ssl->s3->exporter_secret, hs->hash_len, - exporter_label, strlen(exporter_label)) && + kTLS13LabelExporter, strlen(kTLS13LabelExporter)) && ssl_log_secret(ssl, "EXPORTER_SECRET", ssl->s3->exporter_secret, hs->hash_len); } -static const char kTLS13LabelApplicationTraffic[] = - "application traffic secret"; -static const char kTLS13Draft22LabelApplicationTraffic[] = "traffic upd"; +static const char kTLS13LabelApplicationTraffic[] = "traffic upd"; int tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction) { uint8_t *secret; @@ -314,35 +274,27 @@ int tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction) { secret_len = ssl->s3->write_traffic_secret_len; } - const char *traffic_label = ssl_is_draft22(ssl->version) - ? kTLS13Draft22LabelApplicationTraffic - : kTLS13LabelApplicationTraffic; - const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl)); - if (!hkdf_expand_label(secret, ssl->version, digest, secret, secret_len, - traffic_label, strlen(traffic_label), NULL, 0, - secret_len)) { + if (!hkdf_expand_label( + secret, digest, secret, secret_len, kTLS13LabelApplicationTraffic, + strlen(kTLS13LabelApplicationTraffic), NULL, 0, secret_len)) { return 0; } return tls13_set_traffic_key(ssl, direction, secret, secret_len); } -static const char kTLS13LabelResumption[] = "resumption master secret"; -static const char kTLS13Draft22LabelResumption[] = "res master"; +static const char kTLS13LabelResumption[] = "res master"; int tls13_derive_resumption_secret(SSL_HANDSHAKE *hs) { if (hs->hash_len > SSL_MAX_MASTER_KEY_LENGTH) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return 0; } - const char *resumption_label = ssl_is_draft22(hs->ssl->version) - ? kTLS13Draft22LabelResumption - : kTLS13LabelResumption; hs->new_session->master_key_length = hs->hash_len; return derive_secret(hs, hs->new_session->master_key, - hs->new_session->master_key_length, resumption_label, - strlen(resumption_label)); + hs->new_session->master_key_length, + kTLS13LabelResumption, strlen(kTLS13LabelResumption)); } static const char kTLS13LabelFinished[] = "finished"; @@ -355,9 +307,8 @@ static int tls13_verify_data(const EVP_MD *digest, uint16_t version, uint8_t *context, size_t context_len) { uint8_t key[EVP_MAX_MD_SIZE]; unsigned len; - if (!hkdf_expand_label(key, version, digest, secret, hash_len, - kTLS13LabelFinished, strlen(kTLS13LabelFinished), NULL, - 0, hash_len) || + if (!hkdf_expand_label(key, digest, secret, hash_len, kTLS13LabelFinished, + strlen(kTLS13LabelFinished), NULL, 0, hash_len) || HMAC(digest, key, hash_len, context, context_len, out, &len) == NULL) { return 0; } @@ -388,14 +339,9 @@ int tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, static const char kTLS13LabelResumptionPSK[] = "resumption"; bool tls13_derive_session_psk(SSL_SESSION *session, Span nonce) { - if (!ssl_is_draft22(session->ssl_version)) { - return true; - } - const EVP_MD *digest = ssl_session_get_digest(session); - return hkdf_expand_label(session->master_key, session->ssl_version, digest, - session->master_key, session->master_key_length, - kTLS13LabelResumptionPSK, + return hkdf_expand_label(session->master_key, digest, session->master_key, + session->master_key_length, kTLS13LabelResumptionPSK, strlen(kTLS13LabelResumptionPSK), nonce.data(), nonce.size(), session->master_key_length); } @@ -412,14 +358,6 @@ int tls13_export_keying_material(SSL *ssl, Span out, return 0; } - uint16_t version = SSL_get_session(ssl)->ssl_version; - if (!ssl_is_draft22(version)) { - const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl)); - return hkdf_expand_label(out.data(), version, digest, secret.data(), - secret.size(), label.data(), label.size(), - context.data(), context.size(), out.size()); - } - const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl)); uint8_t hash[EVP_MAX_MD_SIZE]; @@ -432,18 +370,16 @@ int tls13_export_keying_material(SSL *ssl, Span out, nullptr) && EVP_Digest(nullptr, 0, export_context, &export_context_len, digest, nullptr) && - hkdf_expand_label(derived_secret, version, digest, secret.data(), - secret.size(), label.data(), label.size(), - export_context, export_context_len, - derived_secret_len) && - hkdf_expand_label(out.data(), version, digest, derived_secret, + hkdf_expand_label(derived_secret, digest, secret.data(), secret.size(), + label.data(), label.size(), export_context, + export_context_len, derived_secret_len) && + hkdf_expand_label(out.data(), digest, derived_secret, derived_secret_len, kTLS13LabelExportKeying, strlen(kTLS13LabelExportKeying), hash, hash_len, out.size()); } -static const char kTLS13LabelPSKBinder[] = "resumption psk binder key"; -static const char kTLS13Draft22LabelPSKBinder[] = "res binder"; +static const char kTLS13LabelPSKBinder[] = "res binder"; static int tls13_psk_binder(uint8_t *out, uint16_t version, const EVP_MD *digest, uint8_t *psk, size_t psk_len, @@ -461,15 +397,12 @@ static int tls13_psk_binder(uint8_t *out, uint16_t version, NULL, 0)) { return 0; } - const char *binder_label = ssl_is_draft22(version) - ? kTLS13Draft22LabelPSKBinder - : kTLS13LabelPSKBinder; uint8_t binder_key[EVP_MAX_MD_SIZE] = {0}; size_t len; - if (!hkdf_expand_label(binder_key, version, digest, early_secret, hash_len, - binder_label, strlen(binder_label), binder_context, - binder_context_len, hash_len) || + if (!hkdf_expand_label(binder_key, digest, early_secret, hash_len, + kTLS13LabelPSKBinder, strlen(kTLS13LabelPSKBinder), + binder_context, binder_context_len, hash_len) || !tls13_verify_data(digest, version, out, &len, binder_key, hash_len, context, context_len)) { return 0; diff --git a/ssl/tls13_server.cc b/ssl/tls13_server.cc index a6a3a0a5..3bd67866 100644 --- a/ssl/tls13_server.cc +++ b/ssl/tls13_server.cc @@ -63,15 +63,10 @@ static int resolve_ecdhe_secret(SSL_HANDSHAKE *hs, bool *out_need_retry, SSL *const ssl = hs->ssl; *out_need_retry = false; - uint16_t key_share_ext = TLSEXT_TYPE_old_key_share; - if (ssl_is_draft23(ssl->version)) { - key_share_ext = TLSEXT_TYPE_new_key_share; - } - // We only support connections that include an ECDHE key exchange. CBS key_share; if (!ssl_client_hello_get_extension(client_hello, &key_share, - key_share_ext)) { + TLSEXT_TYPE_key_share)) { OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION); return 0; @@ -187,9 +182,8 @@ static int add_new_session_tickets(SSL_HANDSHAKE *hs) { SSL3_MT_NEW_SESSION_TICKET) || !CBB_add_u32(&body, session->timeout) || !CBB_add_u32(&body, session->ticket_age_add) || - (ssl_is_draft22(ssl->version) && - (!CBB_add_u8_length_prefixed(&body, &nonce_cbb) || - !CBB_add_bytes(&nonce_cbb, nonce, sizeof(nonce)))) || + !CBB_add_u8_length_prefixed(&body, &nonce_cbb) || + !CBB_add_bytes(&nonce_cbb, nonce, sizeof(nonce)) || !CBB_add_u16_length_prefixed(&body, &ticket) || !tls13_derive_session_psk(session.get(), nonce) || !ssl_encrypt_ticket(ssl, &ticket, session.get()) || @@ -199,9 +193,7 @@ static int add_new_session_tickets(SSL_HANDSHAKE *hs) { if (ssl->cert->enable_early_data) { CBB early_data_info; - if (!CBB_add_u16(&extensions, ssl_is_draft22(ssl->version) - ? TLSEXT_TYPE_early_data - : TLSEXT_TYPE_ticket_early_data_info) || + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_early_data) || !CBB_add_u16_length_prefixed(&extensions, &early_data_info) || !CBB_add_u32(&early_data_info, session->ticket_max_early_data) || !CBB_flush(&extensions)) { @@ -479,8 +471,7 @@ static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) { ssl->s3->early_data_accepted = false; ssl->s3->skip_early_data = true; ssl->method->next_message(ssl); - if (ssl_is_draft22(ssl->version) && - !hs->transcript.UpdateForHelloRetryRequest()) { + if (!hs->transcript.UpdateForHelloRetryRequest()) { return ssl_hs_error; } hs->tls13_state = state_send_hello_retry_request; @@ -498,52 +489,30 @@ static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; - if (ssl_is_draft22(ssl->version)) { - ScopedCBB cbb; - CBB body, session_id, extensions; - uint16_t group_id; - if (!ssl->method->init_message(ssl, cbb.get(), &body, - SSL3_MT_SERVER_HELLO) || - !CBB_add_u16(&body, TLS1_2_VERSION) || - !CBB_add_bytes(&body, kHelloRetryRequest, SSL3_RANDOM_SIZE) || - !CBB_add_u8_length_prefixed(&body, &session_id) || - !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len) || - !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) || - !CBB_add_u8(&body, 0 /* no compression */) || - !tls1_get_shared_group(hs, &group_id) || - !CBB_add_u16_length_prefixed(&body, &extensions) || - !CBB_add_u16(&extensions, TLSEXT_TYPE_supported_versions) || - !CBB_add_u16(&extensions, 2 /* length */) || - !CBB_add_u16(&extensions, ssl->version) || - !CBB_add_u16(&extensions, ssl_is_draft23(ssl->version) - ? TLSEXT_TYPE_new_key_share - : TLSEXT_TYPE_old_key_share) || - !CBB_add_u16(&extensions, 2 /* length */) || - !CBB_add_u16(&extensions, group_id) || - !ssl_add_message_cbb(ssl, cbb.get())) { - return ssl_hs_error; - } + ScopedCBB cbb; + CBB body, session_id, extensions; + uint16_t group_id; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) || + !CBB_add_u16(&body, TLS1_2_VERSION) || + !CBB_add_bytes(&body, kHelloRetryRequest, SSL3_RANDOM_SIZE) || + !CBB_add_u8_length_prefixed(&body, &session_id) || + !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len) || + !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) || + !CBB_add_u8(&body, 0 /* no compression */) || + !tls1_get_shared_group(hs, &group_id) || + !CBB_add_u16_length_prefixed(&body, &extensions) || + !CBB_add_u16(&extensions, TLSEXT_TYPE_supported_versions) || + !CBB_add_u16(&extensions, 2 /* length */) || + !CBB_add_u16(&extensions, ssl->version) || + !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) || + !CBB_add_u16(&extensions, 2 /* length */) || + !CBB_add_u16(&extensions, group_id) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } - if (!ssl->method->add_change_cipher_spec(ssl)) { - return ssl_hs_error; - } - } else { - ScopedCBB cbb; - CBB body, extensions; - uint16_t group_id; - if (!ssl->method->init_message(ssl, cbb.get(), &body, - SSL3_MT_HELLO_RETRY_REQUEST) || - !CBB_add_u16(&body, ssl->version) || - (ssl_is_draft22(ssl->version) && - !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher))) || - !tls1_get_shared_group(hs, &group_id) || - !CBB_add_u16_length_prefixed(&body, &extensions) || - !CBB_add_u16(&extensions, TLSEXT_TYPE_old_key_share) || - !CBB_add_u16(&extensions, 2 /* length */) || - !CBB_add_u16(&extensions, group_id) || - !ssl_add_message_cbb(ssl, cbb.get())) { - return ssl_hs_error; - } + if (!ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; } hs->sent_hello_retry_request = true; @@ -608,7 +577,7 @@ static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { return ssl_hs_error; } - if ((!ssl_is_draft22(ssl->version) || !hs->sent_hello_retry_request) && + if (!hs->sent_hello_retry_request && !ssl->method->add_change_cipher_spec(ssl)) { return ssl_hs_error; } @@ -640,48 +609,34 @@ static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { // Send a CertificateRequest, if necessary. if (hs->cert_request) { - if (ssl_is_draft22(ssl->version)) { - CBB cert_request_extensions, sigalg_contents, sigalgs_cbb; - if (!ssl->method->init_message(ssl, cbb.get(), &body, - SSL3_MT_CERTIFICATE_REQUEST) || - !CBB_add_u8(&body, 0 /* no certificate_request_context. */) || - !CBB_add_u16_length_prefixed(&body, &cert_request_extensions) || - !CBB_add_u16(&cert_request_extensions, - TLSEXT_TYPE_signature_algorithms) || + CBB cert_request_extensions, sigalg_contents, sigalgs_cbb; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_REQUEST) || + !CBB_add_u8(&body, 0 /* no certificate_request_context. */) || + !CBB_add_u16_length_prefixed(&body, &cert_request_extensions) || + !CBB_add_u16(&cert_request_extensions, + TLSEXT_TYPE_signature_algorithms) || + !CBB_add_u16_length_prefixed(&cert_request_extensions, + &sigalg_contents) || + !CBB_add_u16_length_prefixed(&sigalg_contents, &sigalgs_cbb) || + !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb)) { + return ssl_hs_error; + } + + if (ssl_has_client_CAs(ssl)) { + CBB ca_contents; + if (!CBB_add_u16(&cert_request_extensions, + TLSEXT_TYPE_certificate_authorities) || !CBB_add_u16_length_prefixed(&cert_request_extensions, - &sigalg_contents) || - !CBB_add_u16_length_prefixed(&sigalg_contents, &sigalgs_cbb) || - !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb)) { + &ca_contents) || + !ssl_add_client_CA_list(ssl, &ca_contents) || + !CBB_flush(&cert_request_extensions)) { return ssl_hs_error; } + } - if (ssl_has_client_CAs(ssl)) { - CBB ca_contents; - if (!CBB_add_u16(&cert_request_extensions, - TLSEXT_TYPE_certificate_authorities) || - !CBB_add_u16_length_prefixed(&cert_request_extensions, - &ca_contents) || - !ssl_add_client_CA_list(ssl, &ca_contents) || - !CBB_flush(&cert_request_extensions)) { - return ssl_hs_error; - } - } - - if (!ssl_add_message_cbb(ssl, cbb.get())) { - return ssl_hs_error; - } - } else { - CBB sigalgs_cbb; - if (!ssl->method->init_message(ssl, cbb.get(), &body, - SSL3_MT_CERTIFICATE_REQUEST) || - !CBB_add_u8(&body, 0 /* no certificate_request_context. */) || - !CBB_add_u16_length_prefixed(&body, &sigalgs_cbb) || - !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb) || - !ssl_add_client_CA_list(ssl, &body) || - !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) || - !ssl_add_message_cbb(ssl, cbb.get())) { - return ssl_hs_error; - } + if (!ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; } } @@ -738,13 +693,11 @@ static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) { // the wire sooner and also avoids triggering a write on |SSL_read| when // processing the client Finished. This requires computing the client // Finished early. See draft-ietf-tls-tls13-18, section 4.5.1. - if (ssl_is_draft22(ssl->version)) { - static const uint8_t kEndOfEarlyData[4] = {SSL3_MT_END_OF_EARLY_DATA, 0, - 0, 0}; - if (!hs->transcript.Update(kEndOfEarlyData)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - return ssl_hs_error; - } + static const uint8_t kEndOfEarlyData[4] = {SSL3_MT_END_OF_EARLY_DATA, 0, + 0, 0}; + if (!hs->transcript.Update(kEndOfEarlyData)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; } size_t finished_len; @@ -801,22 +754,20 @@ static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) { // If early data was not accepted, the EndOfEarlyData and ChangeCipherSpec // message will be in the discarded early data. if (hs->ssl->s3->early_data_accepted) { - if (ssl_is_draft22(ssl->version)) { - SSLMessage msg; - if (!ssl->method->get_message(ssl, &msg)) { - return ssl_hs_read_message; - } - - if (!ssl_check_message_type(ssl, msg, SSL3_MT_END_OF_EARLY_DATA)) { - return ssl_hs_error; - } - if (CBS_len(&msg.body) != 0) { - ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); - return ssl_hs_error; - } - ssl->method->next_message(ssl); + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_END_OF_EARLY_DATA)) { + return ssl_hs_error; + } + if (CBS_len(&msg.body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + ssl->method->next_message(ssl); } } if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret, diff --git a/ssl/tls_record.cc b/ssl/tls_record.cc index 3d34951d..05a3d569 100644 --- a/ssl/tls_record.cc +++ b/ssl/tls_record.cc @@ -356,15 +356,6 @@ ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, } if (type == SSL3_RT_ALERT) { - // Return end_of_early_data alerts as-is for the caller to process. - if (!ssl_is_draft22(ssl->version) && - out->size() == 2 && - (*out)[0] == SSL3_AL_WARNING && - (*out)[1] == TLS1_AD_END_OF_EARLY_DATA) { - *out_type = type; - return ssl_open_record_success; - } - return ssl_process_alert(ssl, out_alert, *out); } diff --git a/tool/client.cc b/tool/client.cc index de1a8ca3..41626982 100644 --- a/tool/client.cc +++ b/tool/client.cc @@ -332,12 +332,8 @@ static bool DoConnection(SSL_CTX *ctx, } static bool GetTLS13Variant(tls13_variant_t *out, const std::string &in) { - if (in == "draft22") { - *out = tls13_draft22; - return true; - } - if (in == "experiment2") { - *out = tls13_experiment2; + if (in == "draft23") { + *out = tls13_default; return true; } return false; diff --git a/tool/server.cc b/tool/server.cc index 37235a78..896aa867 100644 --- a/tool/server.cc +++ b/tool/server.cc @@ -308,7 +308,7 @@ bool Server(const std::vector &args) { } if (args_map.count("-tls13-variant") != 0) { - SSL_CTX_set_tls13_variant(ctx.get(), tls13_experiment2); + SSL_CTX_set_tls13_variant(ctx.get(), tls13_default); } if (args_map.count("-debug") != 0) {