]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libgo/go/crypto/tls/handshake_client.go
libgo: update to Go1.14beta1
[thirdparty/gcc.git] / libgo / go / crypto / tls / handshake_client.go
index ed000eb6192a06b948d1b35f4bfbdeca05150a2c..4fb528cc9bf9fe046eaae60948e142da939fff77 100644 (file)
@@ -16,7 +16,6 @@ import (
        "fmt"
        "io"
        "net"
-       "strconv"
        "strings"
        "sync/atomic"
        "time"
@@ -50,7 +49,7 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
                return nil, nil, errors.New("tls: NextProtos values too large")
        }
 
-       supportedVersions := config.supportedVersions(true)
+       supportedVersions := config.supportedVersions()
        if len(supportedVersions) == 0 {
                return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
        }
@@ -73,7 +72,6 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
                serverName:                   hostnameInSNI(config.ServerName),
                supportedCurves:              config.curvePreferences(),
                supportedPoints:              []uint8{pointFormatUncompressed},
-               nextProtoNeg:                 len(config.NextProtos) > 0,
                secureRenegotiationSupported: true,
                alpnProtocols:                config.NextProtos,
                supportedVersions:            supportedVersions,
@@ -340,7 +338,7 @@ func (c *Conn) pickTLSVersion(serverHello *serverHelloMsg) error {
                peerVersion = serverHello.supportedVersion
        }
 
-       vers, ok := c.config.mutualVersion(true, []uint16{peerVersion})
+       vers, ok := c.config.mutualVersion([]uint16{peerVersion})
        if !ok {
                c.sendAlert(alertProtocolVersion)
                return fmt.Errorf("tls: server selected unsupported protocol version %x", peerVersion)
@@ -519,7 +517,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
                certRequested = true
                hs.finishedHash.Write(certReq.marshal())
 
-               cri := certificateRequestInfoFromMsg(certReq)
+               cri := certificateRequestInfoFromMsg(c.vers, certReq)
                if chainToSend, err = c.getClientCertificate(cri); err != nil {
                        c.sendAlert(alertInternalError)
                        return err
@@ -563,9 +561,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
        }
 
        if chainToSend != nil && len(chainToSend.Certificate) > 0 {
-               certVerify := &certificateVerifyMsg{
-                       hasSignatureAlgorithm: c.vers >= VersionTLS12,
-               }
+               certVerify := &certificateVerifyMsg{}
 
                key, ok := chainToSend.PrivateKey.(crypto.Signer)
                if !ok {
@@ -573,23 +569,32 @@ func (hs *clientHandshakeState) doFullHandshake() error {
                        return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
                }
 
-               signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(key.Public(), certReq.supportedSignatureAlgorithms, supportedSignatureAlgorithmsTLS12, c.vers)
-               if err != nil {
-                       c.sendAlert(alertInternalError)
-                       return err
-               }
-               // SignatureAndHashAlgorithm was introduced in TLS 1.2.
-               if certVerify.hasSignatureAlgorithm {
+               var sigType uint8
+               var sigHash crypto.Hash
+               if c.vers >= VersionTLS12 {
+                       signatureAlgorithm, err := selectSignatureScheme(c.vers, chainToSend, certReq.supportedSignatureAlgorithms)
+                       if err != nil {
+                               c.sendAlert(alertIllegalParameter)
+                               return err
+                       }
+                       sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)
+                       if err != nil {
+                               return c.sendAlert(alertInternalError)
+                       }
+                       certVerify.hasSignatureAlgorithm = true
                        certVerify.signatureAlgorithm = signatureAlgorithm
+               } else {
+                       sigType, sigHash, err = legacyTypeAndHashFromPublicKey(key.Public())
+                       if err != nil {
+                               c.sendAlert(alertIllegalParameter)
+                               return err
+                       }
                }
-               signed, err := hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret)
-               if err != nil {
-                       c.sendAlert(alertInternalError)
-                       return err
-               }
-               signOpts := crypto.SignerOpts(hashFunc)
+
+               signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret)
+               signOpts := crypto.SignerOpts(sigHash)
                if sigType == signatureRSAPSS {
-                       signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: hashFunc}
+                       signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
                }
                certVerify.signature, err = key.Sign(c.config.rand(), signed, signOpts)
                if err != nil {
@@ -673,26 +678,14 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
                }
        }
 
-       clientDidNPN := hs.hello.nextProtoNeg
        clientDidALPN := len(hs.hello.alpnProtocols) > 0
-       serverHasNPN := hs.serverHello.nextProtoNeg
        serverHasALPN := len(hs.serverHello.alpnProtocol) > 0
 
-       if !clientDidNPN && serverHasNPN {
-               c.sendAlert(alertHandshakeFailure)
-               return false, errors.New("tls: server advertised unrequested NPN extension")
-       }
-
        if !clientDidALPN && serverHasALPN {
                c.sendAlert(alertHandshakeFailure)
                return false, errors.New("tls: server advertised unrequested ALPN extension")
        }
 
-       if serverHasNPN && serverHasALPN {
-               c.sendAlert(alertHandshakeFailure)
-               return false, errors.New("tls: server advertised both NPN and ALPN extensions")
-       }
-
        if serverHasALPN {
                c.clientProtocol = hs.serverHello.alpnProtocol
                c.clientProtocolFallback = false
@@ -784,18 +777,6 @@ func (hs *clientHandshakeState) sendFinished(out []byte) error {
        if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
                return err
        }
-       if hs.serverHello.nextProtoNeg {
-               nextProto := new(nextProtoMsg)
-               proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
-               nextProto.proto = proto
-               c.clientProtocol = proto
-               c.clientProtocolFallback = fallback
-
-               hs.finishedHash.Write(nextProto.marshal())
-               if _, err := c.writeRecord(recordTypeHandshake, nextProto.marshal()); err != nil {
-                       return err
-               }
-       }
 
        finished := new(finishedMsg)
        finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
@@ -868,7 +849,12 @@ var (
 
 // certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS
 // <= 1.2 CertificateRequest, making an effort to fill in missing information.
-func certificateRequestInfoFromMsg(certReq *certificateRequestMsg) *CertificateRequestInfo {
+func certificateRequestInfoFromMsg(vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
+       cri := &CertificateRequestInfo{
+               AcceptableCAs: certReq.certificateAuthorities,
+               Version:       vers,
+       }
+
        var rsaAvail, ecAvail bool
        for _, certType := range certReq.certificateTypes {
                switch certType {
@@ -879,10 +865,6 @@ func certificateRequestInfoFromMsg(certReq *certificateRequestMsg) *CertificateR
                }
        }
 
-       cri := &CertificateRequestInfo{
-               AcceptableCAs: certReq.certificateAuthorities,
-       }
-
        if !certReq.hasSignatureAlgorithm {
                // Prior to TLS 1.2, the signature schemes were not
                // included in the certificate request message. In this
@@ -903,7 +885,11 @@ func certificateRequestInfoFromMsg(certReq *certificateRequestMsg) *CertificateR
        // See RFC 5246, Section 7.4.4 (where it calls this "somewhat complicated").
        cri.SignatureSchemes = make([]SignatureScheme, 0, len(certReq.supportedSignatureAlgorithms))
        for _, sigScheme := range certReq.supportedSignatureAlgorithms {
-               switch signatureFromSignatureScheme(sigScheme) {
+               sigType, _, err := typeAndHashFromSignatureScheme(sigScheme)
+               if err != nil {
+                       continue
+               }
+               switch sigType {
                case signatureECDSA, signatureEd25519:
                        if ecAvail {
                                cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme)
@@ -923,43 +909,11 @@ func (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate,
                return c.config.GetClientCertificate(cri)
        }
 
-       // We need to search our list of client certs for one
-       // where SignatureAlgorithm is acceptable to the server and the
-       // Issuer is in AcceptableCAs.
-       for i, chain := range c.config.Certificates {
-               sigOK := false
-               for _, alg := range signatureSchemesForCertificate(c.vers, &chain) {
-                       if isSupportedSignatureAlgorithm(alg, cri.SignatureSchemes) {
-                               sigOK = true
-                               break
-                       }
-               }
-               if !sigOK {
+       for _, chain := range c.config.Certificates {
+               if err := cri.SupportsCertificate(&chain); err != nil {
                        continue
                }
-
-               if len(cri.AcceptableCAs) == 0 {
-                       return &chain, nil
-               }
-
-               for j, cert := range chain.Certificate {
-                       x509Cert := chain.Leaf
-                       // Parse the certificate if this isn't the leaf node, or if
-                       // chain.Leaf was nil.
-                       if j != 0 || x509Cert == nil {
-                               var err error
-                               if x509Cert, err = x509.ParseCertificate(cert); err != nil {
-                                       c.sendAlert(alertInternalError)
-                                       return nil, errors.New("tls: failed to parse configured certificate chain #" + strconv.Itoa(i) + ": " + err.Error())
-                               }
-                       }
-
-                       for _, ca := range cri.AcceptableCAs {
-                               if bytes.Equal(x509Cert.RawIssuer, ca) {
-                                       return &chain, nil
-                               }
-                       }
-               }
+               return &chain, nil
        }
 
        // No acceptable certificate found. Don't send a certificate.
@@ -991,7 +945,7 @@ func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
        return protos[0], true
 }
 
-// hostnameInSNI converts name into an approriate hostname for SNI.
+// hostnameInSNI converts name into an appropriate hostname for SNI.
 // Literal IP addresses and absolute FQDNs are not permitted as SNI values.
 // See RFC 6066, Section 3.
 func hostnameInSNI(name string) string {