Skip to content

Commit

Permalink
[dev.boringcrypto] all: merge master into dev.boringcrypto
Browse files Browse the repository at this point in the history
Change-Id: I429a190472368dd88a2bf2f1be5adefa459d3087
  • Loading branch information
FiloSottile committed Nov 14, 2018
2 parents 0007017 + 30cc978 commit bfd6d30
Show file tree
Hide file tree
Showing 87 changed files with 3,909 additions and 3,284 deletions.
3 changes: 3 additions & 0 deletions src/crypto/tls/boring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ func TestBoringServerSignatureAndHash(t *testing.T) {
serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
}
serverConfig.BuildNameToCertificate()
// PKCS#1 v1.5 signature algorithms can't be used standalone in TLS
// 1.3, and the ECDSA ones bind to the curve used.
serverConfig.MaxVersion = VersionTLS12

clientErr, _ := boringHandshake(t, testConfig, serverConfig)
if clientErr != nil {
Expand Down
31 changes: 20 additions & 11 deletions src/crypto/tls/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ const (
VersionTLS10 = 0x0301
VersionTLS11 = 0x0302
VersionTLS12 = 0x0303

// VersionTLS13 is under development in this library and can't be selected
// nor negotiated yet on either side.
VersionTLS13 = 0x0304
)

Expand Down Expand Up @@ -190,6 +187,14 @@ var helloRetryRequestRandom = []byte{ // See RFC 8446, Section 4.1.3.
0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C,
}

const (
// downgradeCanaryTLS12 or downgradeCanaryTLS11 is embedded in the server
// random as a downgrade protection if the server would be capable of
// negotiating a higher version. See RFC 8446, Section 4.1.3.
downgradeCanaryTLS12 = "DOWNGRD\x01"
downgradeCanaryTLS11 = "DOWNGRD\x00"
)

// ConnectionState records basic TLS details about the connection.
type ConnectionState struct {
Version uint16 // TLS version used by the connection (e.g. VersionTLS12)
Expand All @@ -201,8 +206,8 @@ type ConnectionState struct {
ServerName string // server name requested by client, if any (server side only)
PeerCertificates []*x509.Certificate // certificate chain presented by remote peer
VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates
SignedCertificateTimestamps [][]byte // SCTs from the server, if any
OCSPResponse []byte // stapled OCSP response from server, if any
SignedCertificateTimestamps [][]byte // SCTs from the peer, if any
OCSPResponse []byte // stapled OCSP response from peer, if any

// ekm is a closure exposed via ExportKeyingMaterial.
ekm func(label string, context []byte, length int) ([]byte, error)
Expand All @@ -212,7 +217,7 @@ type ConnectionState struct {
// because resumption does not include enough context (see
// https://mitls.org/pages/attacks/3SHAKE#channelbindings). This will
// change in future versions of Go once the TLS master-secret fix has
// been standardized and implemented.
// been standardized and implemented. It is not defined in TLS 1.3.
TLSUnique []byte
}

Expand Down Expand Up @@ -550,7 +555,7 @@ type Config struct {

// MaxVersion contains the maximum SSL/TLS version that is acceptable.
// If zero, then the maximum version supported by this package is used,
// which is currently TLS 1.2.
// which is currently TLS 1.3.
MaxVersion uint16

// CurvePreferences contains the elliptic curves that will be used in
Expand Down Expand Up @@ -772,15 +777,19 @@ func (c *Config) supportedVersions(isClient bool) []uint16 {
if isClient && v < VersionTLS10 {
continue
}
// TLS 1.3 is only supported if explicitly requested while in development.
if v == VersionTLS13 && (c == nil || c.MaxVersion != VersionTLS13) {
continue
}
versions = append(versions, v)
}
return versions
}

func (c *Config) maxSupportedVersion(isClient bool) uint16 {
supportedVersions := c.supportedVersions(isClient)
if len(supportedVersions) == 0 {
return 0
}
return supportedVersions[0]
}

// supportedVersionsFromMax returns a list of supported versions derived from a
// legacy maximum version value. Note that only versions supported by this
// library are returned. Any newer peer will use supportedVersions anyway.
Expand Down
2 changes: 1 addition & 1 deletion src/crypto/tls/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -1378,7 +1378,7 @@ func (c *Conn) ConnectionState() ConnectionState {
state.VerifiedChains = c.verifiedChains
state.SignedCertificateTimestamps = c.scts
state.OCSPResponse = c.ocspResponse
if !c.didResume {
if !c.didResume && c.vers != VersionTLS13 {
if c.clientFinishedIsFirst {
state.TLSUnique = c.clientFinished[:]
} else {
Expand Down
19 changes: 12 additions & 7 deletions src/crypto/tls/conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,7 @@ func runDynamicRecordSizingTest(t *testing.T, config *Config) {
return
}

// The last record will be a close_notify alert, which
// we don't wish to record.
if recordType(recordHeader[0]) == recordTypeApplicationData {
recordSizes = append(recordSizes, recordHeaderLen+length)
}
recordSizes = append(recordSizes, recordHeaderLen+length)
}

recordSizesChan <- recordSizes
Expand Down Expand Up @@ -215,8 +211,9 @@ func runDynamicRecordSizingTest(t *testing.T, config *Config) {
t.Fatalf("Client encountered an error")
}

// Drop the size of last record, which is likely to be truncated.
recordSizes = recordSizes[:len(recordSizes)-1]
// Drop the size of the second to last record, which is likely to be
// truncated, and the last record, which is a close_notify alert.
recordSizes = recordSizes[:len(recordSizes)-2]

// recordSizes should contain a series of records smaller than
// tcpMSSEstimate followed by some larger than maxPlaintext.
Expand All @@ -241,22 +238,30 @@ func runDynamicRecordSizingTest(t *testing.T, config *Config) {

func TestDynamicRecordSizingWithStreamCipher(t *testing.T) {
config := testConfig.Clone()
config.MaxVersion = VersionTLS12
config.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA}
runDynamicRecordSizingTest(t, config)
}

func TestDynamicRecordSizingWithCBC(t *testing.T) {
config := testConfig.Clone()
config.MaxVersion = VersionTLS12
config.CipherSuites = []uint16{TLS_RSA_WITH_AES_256_CBC_SHA}
runDynamicRecordSizingTest(t, config)
}

func TestDynamicRecordSizingWithAEAD(t *testing.T) {
config := testConfig.Clone()
config.MaxVersion = VersionTLS12
config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
runDynamicRecordSizingTest(t, config)
}

func TestDynamicRecordSizingWithTLSv13(t *testing.T) {
config := testConfig.Clone()
runDynamicRecordSizingTest(t, config)
}

// hairpinConn is a net.Conn that makes a “hairpin” call when closed, back into
// the tls.Conn which is calling it.
type hairpinConn struct {
Expand Down
3 changes: 0 additions & 3 deletions src/crypto/tls/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,6 @@ func ExampleConfig_keyLogWriter() {
// The resulting file can be used with Wireshark to decrypt the TLS
// connection by setting (Pre)-Master-Secret log filename in SSL Protocol
// preferences.

// Output:
// CLIENT_RANDOM 0000000000000000000000000000000000000000000000000000000000000000 baca0df460a688e44ce018b025183cc2353ae01f89755ef766eedd3ecc302888ee3b3a22962e45f48c20df15a98c0e80
}

func ExampleLoadX509KeyPair() {
Expand Down
52 changes: 26 additions & 26 deletions src/crypto/tls/handshake_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,6 @@ func (test *clientTest) loadData() (flows [][]byte, err error) {
func (test *clientTest) run(t *testing.T, write bool) {
checkOpenSSLVersion(t)

// TODO(filippo): regenerate client tests all at once after CL 146217,
// RSA-PSS and client-side TLS 1.3 are landed.
if !write && !strings.Contains(test.name, "TLSv13") {
t.Skip("recorded client tests are out of date")
}

var clientConn, serverConn net.Conn
var recordingConn *recordingConn
var childProcess *exec.Cmd
Expand Down Expand Up @@ -456,7 +450,7 @@ func (test *clientTest) run(t *testing.T, write bool) {

// If the server sent us an alert after our last flight, give it a
// chance to arrive.
if write {
if write && test.renegotiationExpectedToFail == 0 {
client.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
if _, err := client.Read(make([]byte, 1)); err != nil {
if netErr, ok := err.(net.Error); !ok || !netErr.Timeout() {
Expand Down Expand Up @@ -550,12 +544,6 @@ func runClientTestTLS12(t *testing.T, template *clientTest) {
}

func runClientTestTLS13(t *testing.T, template *clientTest) {
// TODO(filippo): set MaxVersion to VersionTLS13 instead in testConfig
// while regenerating client tests.
if template.config == nil {
template.config = testConfig.Clone()
}
template.config.MaxVersion = VersionTLS13
runClientTestForVersion(t, template, "TLSv13", "-tls1_3")
}

Expand Down Expand Up @@ -1058,14 +1046,16 @@ func TestLRUClientSessionCache(t *testing.T) {
}
}

func TestKeyLog(t *testing.T) {
func TestKeyLogTLS12(t *testing.T) {
var serverBuf, clientBuf bytes.Buffer

clientConfig := testConfig.Clone()
clientConfig.KeyLogWriter = &clientBuf
clientConfig.MaxVersion = VersionTLS12

serverConfig := testConfig.Clone()
serverConfig.KeyLogWriter = &serverBuf
serverConfig.MaxVersion = VersionTLS12

c, s := localPipe(t)
done := make(chan bool)
Expand Down Expand Up @@ -1114,11 +1104,9 @@ func TestKeyLogTLS13(t *testing.T) {

clientConfig := testConfig.Clone()
clientConfig.KeyLogWriter = &clientBuf
clientConfig.MaxVersion = VersionTLS13

serverConfig := testConfig.Clone()
serverConfig.KeyLogWriter = &serverBuf
serverConfig.MaxVersion = VersionTLS13

c, s := localPipe(t)
done := make(chan bool)
Expand Down Expand Up @@ -1640,14 +1628,21 @@ func (wcc *writeCountingConn) Write(data []byte) (int, error) {
}

func TestBuffering(t *testing.T) {
t.Run("TLSv12", func(t *testing.T) { testBuffering(t, VersionTLS12) })
t.Run("TLSv13", func(t *testing.T) { testBuffering(t, VersionTLS13) })
}

func testBuffering(t *testing.T, version uint16) {
c, s := localPipe(t)
done := make(chan bool)

clientWCC := &writeCountingConn{Conn: c}
serverWCC := &writeCountingConn{Conn: s}

go func() {
Server(serverWCC, testConfig).Handshake()
config := testConfig.Clone()
config.MaxVersion = version
Server(serverWCC, config).Handshake()
serverWCC.Close()
done <- true
}()
Expand All @@ -1659,12 +1654,21 @@ func TestBuffering(t *testing.T) {
clientWCC.Close()
<-done

if n := clientWCC.numWrites; n != 2 {
t.Errorf("expected client handshake to complete with only two writes, but saw %d", n)
var expectedClient, expectedServer int
if version == VersionTLS13 {
expectedClient = 2
expectedServer = 1
} else {
expectedClient = 2
expectedServer = 2
}

if n := clientWCC.numWrites; n != expectedClient {
t.Errorf("expected client handshake to complete with %d writes, but saw %d", expectedClient, n)
}

if n := serverWCC.numWrites; n != 2 {
t.Errorf("expected server handshake to complete with only two writes, but saw %d", n)
if n := serverWCC.numWrites; n != expectedServer {
t.Errorf("expected server handshake to complete with %d writes, but saw %d", expectedServer, n)
}
}

Expand Down Expand Up @@ -1696,17 +1700,13 @@ func TestAlertFlushing(t *testing.T) {
t.Fatal("client unexpectedly returned no error")
}

const expectedError = "remote error: tls: handshake failure"
const expectedError = "remote error: tls: internal error"
if e := err.Error(); !strings.Contains(e, expectedError) {
t.Fatalf("expected to find %q in error but error was %q", expectedError, e)
}
clientWCC.Close()
<-done

if n := clientWCC.numWrites; n != 1 {
t.Errorf("expected client handshake to complete with one write, but saw %d", n)
}

if n := serverWCC.numWrites; n != 1 {
t.Errorf("expected server handshake to complete with one write, but saw %d", n)
}
Expand Down
18 changes: 14 additions & 4 deletions src/crypto/tls/handshake_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,18 @@ Curves:
}

hs.hello.random = make([]byte, 32)
_, err := io.ReadFull(c.config.rand(), hs.hello.random)
serverRandom := hs.hello.random
// Downgrade protection canaries. See RFC 8446, Section 4.1.3.
maxVers := c.config.maxSupportedVersion(false)
if maxVers >= VersionTLS12 && c.vers < maxVers {
if c.vers == VersionTLS12 {
copy(serverRandom[24:], downgradeCanaryTLS12)
} else {
copy(serverRandom[24:], downgradeCanaryTLS11)
}
serverRandom = serverRandom[:24]
}
_, err := io.ReadFull(c.config.rand(), serverRandom)
if err != nil {
c.sendAlert(alertInternalError)
return err
Expand Down Expand Up @@ -299,11 +310,10 @@ func (hs *serverHandshakeState) pickCipherSuite() error {
return errors.New("tls: no cipher suite supported by both client and server")
}

// See RFC 7507.
for _, id := range hs.clientHello.cipherSuites {
if id == TLS_FALLBACK_SCSV {
// The client is doing a fallback connection.
if hs.clientHello.vers < c.config.supportedVersions(false)[0] {
// The client is doing a fallback connection. See RFC 7507.
if hs.clientHello.vers < c.config.maxSupportedVersion(false) {
c.sendAlert(alertInappropriateFallback)
return errors.New("tls: client using inappropriate protocol fallback")
}
Expand Down
Loading

0 comments on commit bfd6d30

Please sign in to comment.