diff options
author | David Benjamin <davidben@google.com> | 2016-09-21 00:58:14 +0300 |
---|---|---|
committer | CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> | 2016-09-21 20:18:40 +0300 |
commit | 7a4aaa4ce715cff03b5eebd68f942258863597f2 (patch) | |
tree | ff1afaff3e11002c67f0f85212b1d8a4ddefd189 | |
parent | e0ff7670253bf6525bd827125cdf7409f05d32ce (diff) |
Fix TLS 1.3 fuzzer mode in Go.
Runner needs to implement fuzzer mode as well so we can record
transcripts from it. A bunch of tests were failing:
- C and Go disagreed on what fuzzer mode did to TLS 1.3 padding. So we
fuzz more code, align Go with C. Fuzzer mode TLS 1.3 still pads but
just skips the final AEAD.
- The deterministic RNG should be applied per test, not per exchange. It
turns out, if your RNG is deterministic, one tends to pick the same
session ID over and over which confuses clients. (Resumption is
signaled by echoing the session ID.)
Now the only failing tests are the ones one would expect to fail.
BUG=79
Change-Id: Ica23881a6e726adae71e6767730519214ebcd62a
Reviewed-on: https://boringssl-review.googlesource.com/11126
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
-rw-r--r-- | ssl/test/bssl_shim.cc | 2 | ||||
-rw-r--r-- | ssl/test/runner/conn.go | 64 | ||||
-rw-r--r-- | ssl/test/runner/dtls.go | 2 | ||||
-rw-r--r-- | ssl/test/runner/runner.go | 7 |
4 files changed, 39 insertions, 36 deletions
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc index bef323ee..7196e49e 100644 --- a/ssl/test/bssl_shim.cc +++ b/ssl/test/bssl_shim.cc @@ -640,7 +640,7 @@ static int DDoSCallback(const struct ssl_early_callback_ctx *early_context) { static void InfoCallback(const SSL *ssl, int type, int val) { if (type == SSL_CB_HANDSHAKE_DONE) { if (GetTestConfig(ssl)->handshake_never_done) { - fprintf(stderr, "handshake completed\n"); + fprintf(stderr, "Handshake unexpectedly completed.\n"); // Abort before any expected error code is printed, to ensure the overall // test fails. abort(); diff --git a/ssl/test/runner/conn.go b/ssl/test/runner/conn.go index 9969f8b5..f532237c 100644 --- a/ssl/test/runner/conn.go +++ b/ssl/test/runner/conn.go @@ -200,7 +200,7 @@ func (hc *halfConn) changeCipherSpec(config *Config) error { hc.incEpoch() if config.Bugs.NullAllCiphers { - hc.cipher = nil + hc.cipher = nullCipher{} hc.mac = nil } return nil @@ -210,6 +210,9 @@ func (hc *halfConn) changeCipherSpec(config *Config) error { func (hc *halfConn) useTrafficSecret(version uint16, suite *cipherSuite, secret, phase []byte, side trafficDirection) { hc.version = version hc.cipher = deriveTrafficAEAD(version, suite, secret, phase, side) + if hc.config.Bugs.NullAllCiphers { + hc.cipher = nullCipher{} + } hc.trafficSecret = secret hc.incEpoch() } @@ -423,18 +426,6 @@ func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, contentType recor if err != nil { return false, 0, 0, alertBadRecordMAC } - if hc.version >= VersionTLS13 { - i := len(payload) - for i > 0 && payload[i-1] == 0 { - i-- - } - payload = payload[:i] - if len(payload) == 0 { - return false, 0, 0, alertUnexpectedMessage - } - contentType = recordType(payload[len(payload)-1]) - payload = payload[:len(payload)-1] - } b.resize(recordHeaderLen + explicitIVLen + len(payload)) case cbcMode: blockSize := c.BlockSize() @@ -473,6 +464,20 @@ func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, contentType recor default: panic("unknown cipher type") } + + if hc.version >= VersionTLS13 { + i := len(payload) + for i > 0 && payload[i-1] == 0 { + i-- + } + payload = payload[:i] + if len(payload) == 0 { + return false, 0, 0, alertUnexpectedMessage + } + contentType = recordType(payload[len(payload)-1]) + payload = payload[:len(payload)-1] + b.resize(recordHeaderLen + len(payload)) + } } // check, strip mac @@ -545,29 +550,26 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int, typ recordType) (bool, // encrypt if hc.cipher != nil { + // Add TLS 1.3 padding. + if hc.version >= VersionTLS13 { + paddingLen := hc.config.Bugs.RecordPadding + if hc.config.Bugs.OmitRecordContents { + b.resize(recordHeaderLen + paddingLen) + } else { + b.resize(len(b.data) + 1 + paddingLen) + b.data[len(b.data)-paddingLen-1] = byte(typ) + } + for i := 0; i < paddingLen; i++ { + b.data[len(b.data)-paddingLen+i] = 0 + } + } + switch c := hc.cipher.(type) { case cipher.Stream: c.XORKeyStream(payload, payload) case *tlsAead: payloadLen := len(b.data) - recordHeaderLen - explicitIVLen - paddingLen := 0 - if hc.version >= VersionTLS13 { - payloadLen++ - paddingLen = hc.config.Bugs.RecordPadding - } - if hc.config.Bugs.OmitRecordContents { - payloadLen = 0 - } - b.resize(recordHeaderLen + explicitIVLen + payloadLen + paddingLen + c.Overhead()) - if hc.version >= VersionTLS13 { - if !hc.config.Bugs.OmitRecordContents { - b.data[payloadLen+recordHeaderLen-1] = byte(typ) - } - for i := 0; i < hc.config.Bugs.RecordPadding; i++ { - b.data[payloadLen+recordHeaderLen+i] = 0 - } - payloadLen += paddingLen - } + b.resize(len(b.data) + c.Overhead()) nonce := hc.outSeq[:] if c.explicitNonce { nonce = b.data[recordHeaderLen : recordHeaderLen+explicitIVLen] diff --git a/ssl/test/runner/dtls.go b/ssl/test/runner/dtls.go index b873ae6d..788bec86 100644 --- a/ssl/test/runner/dtls.go +++ b/ssl/test/runner/dtls.go @@ -335,7 +335,7 @@ func (c *Conn) dtlsSealRecord(typ recordType, data []byte) (b *block, err error) // use the sequence number as the nonce. explicitIVIsSeq = true } - } else if c.out.cipher != nil { + } else if _, ok := c.out.cipher.(nullCipher); !ok && c.out.cipher != nil { panic("Unknown cipher") } b.resize(recordHeaderLen + explicitIVLen + len(data)) diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index 9ae72ef5..0523042d 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go @@ -442,9 +442,6 @@ func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) er if *fuzzer { config.Bugs.NullAllCiphers = true } - if *deterministic { - config.Rand = &deterministicRand{} - } conn = &timeoutConn{conn, *idleTimeout} @@ -903,6 +900,10 @@ func runTest(test *testCase, shimPath string, mallocNumToFail int64) error { config := test.config + if *deterministic { + config.Rand = &deterministicRand{} + } + conn, err := acceptOrWait(listener, waitChan) if err == nil { err = doExchange(test, &config, conn, false /* not a resumption */) |