diff options
author | David Benjamin <davidben@google.com> | 2016-09-27 02:20:48 +0300 |
---|---|---|
committer | CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> | 2016-09-27 18:09:38 +0300 |
commit | b1dd8cdab508dc3f9761c2d7fbe9d25f09a3d383 (patch) | |
tree | a21f856a9b1aad29cdbc62d8c399146ffbda13c8 | |
parent | 3c6a1ea6747a026e74cf2c2dc179ccffa03f3e57 (diff) |
Prepare runner's wire/version conversions for the version extension.
This mirror's 2dc0204603f777597e2f97662e42887d1af5013f on the C side.
BUG=90
Change-Id: Iebb72df5a5ae98cb2fd8db519d973cd734ff05ea
Reviewed-on: https://boringssl-review.googlesource.com/11320
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
-rw-r--r-- | ssl/test/runner/common.go | 4 | ||||
-rw-r--r-- | ssl/test/runner/dtls.go | 38 | ||||
-rw-r--r-- | ssl/test/runner/handshake_client.go | 6 | ||||
-rw-r--r-- | ssl/test/runner/handshake_messages.go | 22 | ||||
-rw-r--r-- | ssl/test/runner/handshake_server.go | 61 | ||||
-rw-r--r-- | ssl/test/runner/runner.go | 4 |
6 files changed, 96 insertions, 39 deletions
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go index 7aa984e7..e35d2f54 100644 --- a/ssl/test/runner/common.go +++ b/ssl/test/runner/common.go @@ -736,8 +736,8 @@ type ProtocolBugs struct { // across a renego. RequireSameRenegoClientVersion bool - // ExpectInitialRecordVersion, if non-zero, is the expected - // version of the records before the version is determined. + // ExpectInitialRecordVersion, if non-zero, is the expected value of + // record-layer version field before the version is determined. ExpectInitialRecordVersion uint16 // MaxPacketLength, if non-zero, is the maximum acceptable size for a diff --git a/ssl/test/runner/dtls.go b/ssl/test/runner/dtls.go index 788bec86..ca7a51d9 100644 --- a/ssl/test/runner/dtls.go +++ b/ssl/test/runner/dtls.go @@ -25,16 +25,38 @@ import ( func versionToWire(vers uint16, isDTLS bool) uint16 { if isDTLS { - return ^(vers - 0x0201) + switch vers { + case VersionTLS12: + return 0xfefd + case VersionTLS10: + return 0xfeff + } + } else { + switch vers { + case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13: + return vers + } } - return vers + + panic("unknown version") } -func wireToVersion(vers uint16, isDTLS bool) uint16 { +func wireToVersion(vers uint16, isDTLS bool) (uint16, bool) { if isDTLS { - return ^vers + 0x0201 + switch vers { + case 0xfefd: + return VersionTLS12, true + case 0xfeff: + return VersionTLS10, true + } + } else { + switch vers { + case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13: + return vers, true + } } - return vers + + return 0, false } func (c *Conn) dtlsDoReadRecord(want recordType) (recordType, *block, error) { @@ -70,15 +92,15 @@ func (c *Conn) dtlsDoReadRecord(want recordType) (recordType, *block, error) { return 0, nil, errors.New("dtls: failed to read record header") } typ := recordType(b.data[0]) - vers := wireToVersion(uint16(b.data[1])<<8|uint16(b.data[2]), c.isDTLS) + vers := uint16(b.data[1])<<8 | uint16(b.data[2]) // Alerts sent near version negotiation do not have a well-defined // record-layer version prior to TLS 1.3. (In TLS 1.3, the record-layer // version is irrelevant.) if typ != recordTypeAlert { if c.haveVers { - if vers != c.vers { + if wireVers := versionToWire(c.vers, c.isDTLS); vers != wireVers { c.sendAlert(alertProtocolVersion) - return 0, nil, c.in.setErrorLocked(fmt.Errorf("dtls: received record with version %x when expecting version %x", vers, c.vers)) + return 0, nil, c.in.setErrorLocked(fmt.Errorf("dtls: received record with version %x when expecting version %x", vers, wireVers)) } } else { // Pre-version-negotiation alerts may be sent with any version. diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go index bdddfb42..cb241536 100644 --- a/ssl/test/runner/handshake_client.go +++ b/ssl/test/runner/handshake_client.go @@ -364,8 +364,10 @@ NextCipherSuite: return fmt.Errorf("tls: received unexpected message of type %T when waiting for HelloRetryRequest or ServerHello", msg) } - var ok bool - c.vers, ok = c.config.mutualVersion(wireToVersion(serverWireVersion, c.isDTLS), c.isDTLS) + serverVersion, ok := wireToVersion(serverWireVersion, c.isDTLS) + if ok { + c.vers, ok = c.config.mutualVersion(serverVersion, c.isDTLS) + } if !ok { c.sendAlert(alertProtocolVersion) return fmt.Errorf("tls: server selected unsupported protocol version %x", c.vers) diff --git a/ssl/test/runner/handshake_messages.go b/ssl/test/runner/handshake_messages.go index 329be7f9..6538dc62 100644 --- a/ssl/test/runner/handshake_messages.go +++ b/ssl/test/runner/handshake_messages.go @@ -719,6 +719,7 @@ type serverHelloMsg struct { raw []byte isDTLS bool vers uint16 + versOverride uint16 random []byte sessionId []byte cipherSuite uint16 @@ -739,8 +740,20 @@ func (m *serverHelloMsg) marshal() []byte { handshakeMsg := newByteBuilder() handshakeMsg.addU8(typeServerHello) hello := handshakeMsg.addU24LengthPrefixed() - vers := wireToVersion(m.vers, m.isDTLS) - hello.addU16(m.vers) + + // m.vers is used both to determine the format of the rest of the + // ServerHello and to override the value, so include a second version + // field. + vers, ok := wireToVersion(m.vers, m.isDTLS) + if !ok { + panic("unknown version") + } + if m.versOverride != 0 { + hello.addU16(m.versOverride) + } else { + hello.addU16(m.vers) + } + hello.addBytes(m.random) if vers < VersionTLS13 { sessionId := hello.addU8LengthPrefixed() @@ -787,7 +800,10 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool { } m.raw = data m.vers = uint16(data[4])<<8 | uint16(data[5]) - vers := wireToVersion(m.vers, m.isDTLS) + vers, ok := wireToVersion(m.vers, m.isDTLS) + if !ok { + return false + } m.random = data[6:38] data = data[38:] if vers < VersionTLS13 { diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go index 55bc9cc1..85d4ca85 100644 --- a/ssl/test/runner/handshake_server.go +++ b/ssl/test/runner/handshake_server.go @@ -205,7 +205,39 @@ func (hs *serverHandshakeState) readClientHello() error { } } c.clientVersion = hs.clientHello.vers - clientVersion := wireToVersion(c.clientVersion, c.isDTLS) + var clientVersion uint16 + if c.isDTLS { + if hs.clientHello.vers <= 0xfefd { + clientVersion = VersionTLS12 + } else if hs.clientHello.vers <= 0xfeff { + clientVersion = VersionTLS10 + } + } else { + if hs.clientHello.vers >= VersionTLS13 { + clientVersion = VersionTLS13 + } else if hs.clientHello.vers >= VersionTLS12 { + clientVersion = VersionTLS12 + } else if hs.clientHello.vers >= VersionTLS11 { + clientVersion = VersionTLS11 + } else if hs.clientHello.vers >= VersionTLS10 { + clientVersion = VersionTLS10 + } else if hs.clientHello.vers >= VersionSSL30 { + clientVersion = VersionSSL30 + } + } + + if config.Bugs.NegotiateVersion != 0 { + c.vers = config.Bugs.NegotiateVersion + } else if c.haveVers && config.Bugs.NegotiateVersionOnRenego != 0 { + c.vers = config.Bugs.NegotiateVersionOnRenego + } else { + c.vers, ok = config.mutualVersion(clientVersion, c.isDTLS) + if !ok { + c.sendAlert(alertProtocolVersion) + return fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", hs.clientHello.vers) + } + } + c.haveVers = true // Reject < 1.2 ClientHellos with signature_algorithms. if clientVersion < VersionTLS12 && len(hs.clientHello.signatureAlgorithms) > 0 { @@ -234,19 +266,6 @@ func (hs *serverHandshakeState) readClientHello() error { return fmt.Errorf("tls: client offered unexpected PSK identities") } - if config.Bugs.NegotiateVersion != 0 { - c.vers = config.Bugs.NegotiateVersion - } else if c.haveVers && config.Bugs.NegotiateVersionOnRenego != 0 { - c.vers = config.Bugs.NegotiateVersionOnRenego - } else { - c.vers, ok = config.mutualVersion(clientVersion, c.isDTLS) - if !ok { - c.sendAlert(alertProtocolVersion) - return fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", clientVersion) - } - } - c.haveVers = true - var scsvFound, greaseFound bool for _, cipherSuite := range hs.clientHello.cipherSuites { if cipherSuite == fallbackSCSV { @@ -311,12 +330,9 @@ func (hs *serverHandshakeState) doTLS13Handshake() error { config := c.config hs.hello = &serverHelloMsg{ - isDTLS: c.isDTLS, - vers: versionToWire(c.vers, c.isDTLS), - } - - if config.Bugs.SendServerHelloVersion != 0 { - hs.hello.vers = config.Bugs.SendServerHelloVersion + isDTLS: c.isDTLS, + vers: versionToWire(c.vers, c.isDTLS), + versOverride: config.Bugs.SendServerHelloVersion, } hs.hello.random = make([]byte, 32) @@ -818,13 +834,10 @@ func (hs *serverHandshakeState) processClientHello() (isResume bool, err error) hs.hello = &serverHelloMsg{ isDTLS: c.isDTLS, vers: versionToWire(c.vers, c.isDTLS), + versOverride: config.Bugs.SendServerHelloVersion, compressionMethod: compressionNone, } - if config.Bugs.SendServerHelloVersion != 0 { - hs.hello.vers = config.Bugs.SendServerHelloVersion - } - hs.hello.random = make([]byte, 32) _, err = io.ReadFull(config.rand(), hs.hello.random) if err != nil { diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index ea29ef50..19f67b1e 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go @@ -4102,14 +4102,18 @@ func addVersionNegotiationTests() { shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls))) + // Determine the expected initial record-layer versions. clientVers := shimVers.version if clientVers > VersionTLS10 { clientVers = VersionTLS10 } + clientVers = versionToWire(clientVers, protocol == dtls) serverVers := expectedVersion if expectedVersion >= VersionTLS13 { serverVers = VersionTLS10 } + serverVers = versionToWire(serverVers, protocol == dtls) + testCases = append(testCases, testCase{ protocol: protocol, testType: clientTest, |