]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/crypto/tls/handshake_server.go
[dev.boringcrypto] all: merge master into dev.boringcrypto
[gostls13.git] / src / crypto / tls / handshake_server.go
index 5b1aa64166b30b783b084050e2ff3bb8709612e9..c5caab122457c12122dd177b763e3c26b7819e30 100644 (file)
@@ -10,7 +10,6 @@ import (
        "crypto/rsa"
        "crypto/subtle"
        "crypto/x509"
-       "encoding/asn1"
        "errors"
        "fmt"
        "io"
@@ -520,59 +519,15 @@ func (hs *serverHandshakeState) doFullHandshake() error {
                }
 
                // Determine the signature type.
-               var signatureAlgorithm SignatureScheme
-               var sigType uint8
-               if certVerify.hasSignatureAndHash {
-                       signatureAlgorithm = certVerify.signatureAlgorithm
-                       if !isSupportedSignatureAlgorithm(signatureAlgorithm, supportedSignatureAlgorithms()) {
-                               return errors.New("tls: unsupported hash function for client certificate")
-                       }
-                       sigType = signatureFromSignatureScheme(signatureAlgorithm)
-               } else {
-                       // Before TLS 1.2 the signature algorithm was implicit
-                       // from the key type, and only one hash per signature
-                       // algorithm was possible. Leave signatureAlgorithm
-                       // unset.
-                       switch pub.(type) {
-                       case *ecdsa.PublicKey:
-                               sigType = signatureECDSA
-                       case *rsa.PublicKey:
-                               sigType = signatureRSA
-                       }
+               _, sigType, hashFunc, err := pickSignatureAlgorithm(pub, []SignatureScheme{certVerify.signatureAlgorithm}, supportedSignatureAlgorithms(), c.vers)
+               if err != nil {
+                       c.sendAlert(alertIllegalParameter)
+                       return err
                }
 
-               switch key := pub.(type) {
-               case *ecdsa.PublicKey:
-                       if sigType != signatureECDSA {
-                               err = errors.New("tls: bad signature type for client's ECDSA certificate")
-                               break
-                       }
-                       ecdsaSig := new(ecdsaSignature)
-                       if _, err = asn1.Unmarshal(certVerify.signature, ecdsaSig); err != nil {
-                               break
-                       }
-                       if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
-                               err = errors.New("tls: ECDSA signature contained zero or negative values")
-                               break
-                       }
-                       var digest []byte
-                       if digest, _, err = hs.finishedHash.hashForClientCertificate(sigType, signatureAlgorithm, hs.masterSecret); err != nil {
-                               break
-                       }
-                       if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
-                               err = errors.New("tls: ECDSA verification failure")
-                       }
-               case *rsa.PublicKey:
-                       if sigType != signatureRSA {
-                               err = errors.New("tls: bad signature type for client's RSA certificate")
-                               break
-                       }
-                       var digest []byte
-                       var hashFunc crypto.Hash
-                       if digest, hashFunc, err = hs.finishedHash.hashForClientCertificate(sigType, signatureAlgorithm, hs.masterSecret); err != nil {
-                               break
-                       }
-                       err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature)
+               var digest []byte
+               if digest, err = hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret); err == nil {
+                       err = verifyHandshakeSignature(sigType, pub, hashFunc, digest, certVerify.signature)
                }
                if err != nil {
                        c.sendAlert(alertBadCertificate)