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: Ia068dac1677bfc44c41e35d1f46e6499911cfae0
  • Loading branch information
FiloSottile committed Nov 14, 2018
2 parents de153ac + 7f5dce0 commit e8b3500
Show file tree
Hide file tree
Showing 15 changed files with 1,577 additions and 120 deletions.
6 changes: 3 additions & 3 deletions src/crypto/tls/boring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ func TestBoringServerProtocolVersion(t *testing.T) {

fipstls.Force()
defer fipstls.Abandon()
test("VersionSSL30", VersionSSL30, "unsupported, maximum protocol version")
test("VersionTLS10", VersionTLS10, "unsupported, maximum protocol version")
test("VersionTLS11", VersionTLS11, "unsupported, maximum protocol version")
test("VersionSSL30", VersionSSL30, "client offered only unsupported versions")
test("VersionTLS10", VersionTLS10, "client offered only unsupported versions")
test("VersionTLS11", VersionTLS11, "client offered only unsupported versions")
test("VersionTLS12", VersionTLS12, "")
}

Expand Down
105 changes: 64 additions & 41 deletions src/crypto/tls/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ const (
recordHeaderLen = 5 // record header length
maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB)
maxUselessRecords = 5 // maximum number of consecutive non-advancing records

minVersion = VersionTLS10
maxVersion = VersionTLS12
)

// TLS record types.
Expand All @@ -57,19 +54,23 @@ const (

// TLS handshake message types.
const (
typeHelloRequest uint8 = 0
typeClientHello uint8 = 1
typeServerHello uint8 = 2
typeNewSessionTicket uint8 = 4
typeCertificate uint8 = 11
typeServerKeyExchange uint8 = 12
typeCertificateRequest uint8 = 13
typeServerHelloDone uint8 = 14
typeCertificateVerify uint8 = 15
typeClientKeyExchange uint8 = 16
typeFinished uint8 = 20
typeCertificateStatus uint8 = 22
typeNextProtocol uint8 = 67 // Not IANA assigned
typeHelloRequest uint8 = 0
typeClientHello uint8 = 1
typeServerHello uint8 = 2
typeNewSessionTicket uint8 = 4
typeEndOfEarlyData uint8 = 5
typeEncryptedExtensions uint8 = 8
typeCertificate uint8 = 11
typeServerKeyExchange uint8 = 12
typeCertificateRequest uint8 = 13
typeServerHelloDone uint8 = 14
typeCertificateVerify uint8 = 15
typeClientKeyExchange uint8 = 16
typeFinished uint8 = 20
typeCertificateStatus uint8 = 22
typeKeyUpdate uint8 = 24
typeNextProtocol uint8 = 67 // Not IANA assigned
typeMessageHash uint8 = 254 // synthetic message
)

// TLS compression types.
Expand All @@ -88,6 +89,7 @@ const (
extensionSCT uint16 = 18
extensionSessionTicket uint16 = 35
extensionPreSharedKey uint16 = 41
extensionEarlyData uint16 = 42
extensionSupportedVersions uint16 = 43
extensionCookie uint16 = 44
extensionPSKModes uint16 = 45
Expand Down Expand Up @@ -713,24 +715,46 @@ func (c *Config) cipherSuites() []uint16 {
return s
}

func (c *Config) minVersion() uint16 {
if needFIPS() {
return fipsMinVersion(c)
}
if c == nil || c.MinVersion == 0 {
return minVersion
}
return c.MinVersion
var supportedVersions = []uint16{
VersionTLS12,
VersionTLS11,
VersionTLS10,
VersionSSL30,
}

func (c *Config) maxVersion() uint16 {
if needFIPS() {
return fipsMaxVersion(c)
func (c *Config) supportedVersions(isClient bool) []uint16 {
versions := make([]uint16, 0, len(supportedVersions))
for _, v := range supportedVersions {
if needFIPS() && (v < fipsMinVersion(c) || v > fipsMaxVersion(c)) {
continue
}
if c != nil && c.MinVersion != 0 && v < c.MinVersion {
continue
}
if c != nil && c.MaxVersion != 0 && v > c.MaxVersion {
continue
}
// TLS 1.0 is the minimum version supported as a client.
if isClient && v < VersionTLS10 {
continue
}
versions = append(versions, v)
}
if c == nil || c.MaxVersion == 0 {
return maxVersion
return versions
}

// 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.
func supportedVersionsFromMax(maxVersion uint16) []uint16 {
versions := make([]uint16, 0, len(supportedVersions))
for _, v := range supportedVersions {
if v > maxVersion {
continue
}
versions = append(versions, v)
}
return c.MaxVersion
return versions
}

var defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521}
Expand All @@ -746,18 +770,17 @@ func (c *Config) curvePreferences() []CurveID {
}

// mutualVersion returns the protocol version to use given the advertised
// version of the peer.
func (c *Config) mutualVersion(vers uint16) (uint16, bool) {
minVersion := c.minVersion()
maxVersion := c.maxVersion()

if vers < minVersion {
return 0, false
}
if vers > maxVersion {
vers = maxVersion
// versions of the peer. Priority is given to the peer preference order.
func (c *Config) mutualVersion(isClient bool, peerVersions []uint16) (uint16, bool) {
supportedVersions := c.supportedVersions(isClient)
for _, peerVersion := range peerVersions {
for _, v := range supportedVersions {
if v == peerVersion {
return v, true
}
}
}
return vers, true
return 0, false
}

// getCertificate returns the best certificate for the given ClientHelloInfo,
Expand Down
26 changes: 22 additions & 4 deletions src/crypto/tls/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -990,12 +990,24 @@ func (c *Conn) readHandshake() (interface{}, error) {
case typeServerHello:
m = new(serverHelloMsg)
case typeNewSessionTicket:
m = new(newSessionTicketMsg)
if c.vers == VersionTLS13 {
m = new(newSessionTicketMsgTLS13)
} else {
m = new(newSessionTicketMsg)
}
case typeCertificate:
m = new(certificateMsg)
if c.vers == VersionTLS13 {
m = new(certificateMsgTLS13)
} else {
m = new(certificateMsg)
}
case typeCertificateRequest:
m = &certificateRequestMsg{
hasSignatureAlgorithm: c.vers >= VersionTLS12,
if c.vers == VersionTLS13 {
m = new(certificateRequestMsgTLS13)
} else {
m = &certificateRequestMsg{
hasSignatureAlgorithm: c.vers >= VersionTLS12,
}
}
case typeCertificateStatus:
m = new(certificateStatusMsg)
Expand All @@ -1013,6 +1025,12 @@ func (c *Conn) readHandshake() (interface{}, error) {
m = new(nextProtoMsg)
case typeFinished:
m = new(finishedMsg)
case typeEncryptedExtensions:
m = new(encryptedExtensionsMsg)
case typeEndOfEarlyData:
m = new(endOfEarlyDataMsg)
case typeKeyUpdate:
m = new(keyUpdateMsg)
default:
return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
}
Expand Down
43 changes: 32 additions & 11 deletions src/crypto/tls/handshake_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,25 @@ func makeClientHello(config *Config) (*clientHelloMsg, error) {
nextProtosLength += 1 + l
}
}

if nextProtosLength > 0xffff {
return nil, errors.New("tls: NextProtos values too large")
}

supportedVersions := config.supportedVersions(true)
if len(supportedVersions) == 0 {
return nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
}

clientHelloVersion := supportedVersions[0]
// The version at the beginning of the ClientHello was capped at TLS 1.2
// for compatibility reasons. The supported_versions extension is used
// to negotiate versions now. See RFC 8446, Section 4.2.1.
if clientHelloVersion > VersionTLS12 {
clientHelloVersion = VersionTLS12
}

hello := &clientHelloMsg{
vers: config.maxVersion(),
vers: clientHelloVersion,
compressionMethods: []uint8{compressionNone},
random: make([]byte, 32),
ocspStapling: true,
Expand All @@ -60,6 +72,7 @@ func makeClientHello(config *Config) (*clientHelloMsg, error) {
nextProtoNeg: len(config.NextProtos) > 0,
secureRenegotiationSupported: true,
alpnProtocols: config.NextProtos,
supportedVersions: supportedVersions,
}
possibleCipherSuites := config.cipherSuites()
hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
Expand Down Expand Up @@ -143,8 +156,14 @@ func (c *Conn) clientHandshake() error {
}
}

versOk := candidateSession.vers >= c.config.minVersion() &&
candidateSession.vers <= c.config.maxVersion()
versOk := false
for _, v := range c.config.supportedVersions(true) {
if v == candidateSession.vers {
versOk = true
break
}
}

if versOk && cipherSuiteOk {
session = candidateSession
}
Expand Down Expand Up @@ -276,11 +295,15 @@ func (hs *clientHandshakeState) handshake() error {
}

func (hs *clientHandshakeState) pickTLSVersion() error {
vers, ok := hs.c.config.mutualVersion(hs.serverHello.vers)
if !ok || vers < VersionTLS10 {
// TLS 1.0 is the minimum version supported as a client.
peerVersion := hs.serverHello.vers
if hs.serverHello.supportedVersion != 0 {
peerVersion = hs.serverHello.supportedVersion
}

vers, ok := hs.c.config.mutualVersion(true, []uint16{peerVersion})
if !ok {
hs.c.sendAlert(alertProtocolVersion)
return fmt.Errorf("tls: server selected unsupported protocol version %x", hs.serverHello.vers)
return fmt.Errorf("tls: server selected unsupported protocol version %x", peerVersion)
}

hs.c.vers = vers
Expand Down Expand Up @@ -398,9 +421,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
}
hs.finishedHash.Write(cs.marshal())

if cs.statusType == statusTypeOCSP {
c.ocspResponse = cs.response
}
c.ocspResponse = cs.response

msg, err = c.readHandshake()
if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions src/crypto/tls/handshake_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,12 @@ 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 {
t.Skip("recorded client tests are out of date")
}

var clientConn, serverConn net.Conn
var recordingConn *recordingConn
var childProcess *exec.Cmd
Expand Down
Loading

0 comments on commit e8b3500

Please sign in to comment.