浏览代码

crypto/tls: add RSASSA-PSS support for handshake messages

This adds support for RSASSA-PSS signatures in handshake messages as
required by TLS 1.3. Even if TLS 1.2 is negotiated, it must support PSS
when advertised in the Client Hello (this will be done later as the
testdata will change).

Updates #9671

Change-Id: I8006b92e017453ae408c153233ce5ccef99b5c3f
tls13
Peter Wu 7 年前
父节点
当前提交
9f46cf9e2d
共有 6 个文件被更改,包括 36 次插入16 次删除
  1. +13
    -4
      auth.go
  2. +2
    -2
      cipher_suites.go
  3. +6
    -3
      common.go
  4. +5
    -1
      handshake_client.go
  5. +9
    -5
      key_agreement.go
  6. +1
    -1
      prf.go

+ 13
- 4
auth.go 查看文件

@@ -26,9 +26,9 @@ func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []S
switch pubkey.(type) {
case *rsa.PublicKey:
if tlsVersion < VersionTLS12 {
return 0, signatureRSA, crypto.MD5SHA1, nil
return 0, signaturePKCS1v15, crypto.MD5SHA1, nil
} else {
return PKCS1WithSHA1, signatureRSA, crypto.SHA1, nil
return PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1, nil
}
case *ecdsa.PublicKey:
return ECDSAWithSHA1, signatureECDSA, crypto.SHA1, nil
@@ -47,7 +47,7 @@ func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []S
sigType := signatureFromSignatureScheme(sigAlg)
switch pubkey.(type) {
case *rsa.PublicKey:
if sigType == signatureRSA {
if sigType == signaturePKCS1v15 || sigType == signatureRSAPSS {
return sigAlg, sigType, hashAlg, nil
}
case *ecdsa.PublicKey:
@@ -78,7 +78,7 @@ func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc c
if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
return errors.New("tls: ECDSA verification failure")
}
case signatureRSA:
case signaturePKCS1v15:
pubKey, ok := pubkey.(*rsa.PublicKey)
if !ok {
return errors.New("tls: RSA signing requires a RSA public key")
@@ -86,6 +86,15 @@ func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc c
if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
return err
}
case signatureRSAPSS:
pubKey, ok := pubkey.(*rsa.PublicKey)
if !ok {
return errors.New("tls: RSA signing requires a RSA public key")
}
signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}
if err := rsa.VerifyPSS(pubKey, hashFunc, digest, sig, signOpts); err != nil {
return err
}
default:
return errors.New("tls: unknown signature algorithm")
}


+ 2
- 2
cipher_suites.go 查看文件

@@ -356,14 +356,14 @@ func rsaKA(version uint16) keyAgreement {

func ecdheECDSAKA(version uint16) keyAgreement {
return &ecdheKeyAgreement{
sigType: signatureECDSA,
isRSA: false,
version: version,
}
}

func ecdheRSAKA(version uint16) keyAgreement {
return &ecdheKeyAgreement{
sigType: signatureRSA,
isRSA: true,
version: version,
}
}


+ 6
- 3
common.go 查看文件

@@ -164,8 +164,9 @@ const (

// Signature algorithms for TLS 1.2 (See RFC 5246, section A.4.1)
const (
signatureRSA uint8 = 1
signatureECDSA uint8 = 3
signaturePKCS1v15 uint8 = iota + 1
signatureECDSA
signatureRSAPSS
)

// supportedSignatureAlgorithms contains the signature and hash algorithms that
@@ -1156,7 +1157,9 @@ func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlg
func signatureFromSignatureScheme(signatureAlgorithm SignatureScheme) uint8 {
switch signatureAlgorithm {
case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512:
return signatureRSA
return signaturePKCS1v15
case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512:
return signatureRSAPSS
case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512:
return signatureECDSA
default:


+ 5
- 1
handshake_client.go 查看文件

@@ -499,7 +499,11 @@ func (hs *clientHandshakeState) doFullHandshake() error {
c.sendAlert(alertInternalError)
return err
}
certVerify.signature, err = key.Sign(c.config.rand(), digest, hashFunc)
signOpts := crypto.SignerOpts(hashFunc)
if sigType == signatureRSAPSS {
signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: hashFunc}
}
certVerify.signature, err = key.Sign(c.config.rand(), digest, signOpts)
if err != nil {
c.sendAlert(alertInternalError)
return err


+ 9
- 5
key_agreement.go 查看文件

@@ -138,13 +138,13 @@ func curveForCurveID(id CurveID) (elliptic.Curve, bool) {

}

// ecdheRSAKeyAgreement implements a TLS key agreement where the server
// ecdheKeyAgreement implements a TLS key agreement where the server
// generates an ephemeral EC public/private key pair and signs it. The
// pre-master secret is then calculated using ECDH. The signature may
// either be ECDSA or RSA.
type ecdheKeyAgreement struct {
version uint16
sigType uint8
isRSA bool
privateKey []byte
curveid CurveID

@@ -216,7 +216,7 @@ NextCandidate:
if err != nil {
return nil, err
}
if sigType != ka.sigType {
if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {
return nil, errors.New("tls: certificate cannot be used with the selected cipher suite")
}

@@ -226,7 +226,11 @@ NextCandidate:
}

var sig []byte
sig, err = priv.Sign(config.rand(), digest, hashFunc)
signOpts := crypto.SignerOpts(hashFunc)
if sigType == signatureRSAPSS {
signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: hashFunc}
}
sig, err = priv.Sign(config.rand(), digest, signOpts)
if err != nil {
return nil, errors.New("tls: failed to sign ECDHE parameters: " + err.Error())
}
@@ -337,7 +341,7 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell
if err != nil {
return err
}
if sigType != ka.sigType {
if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {
return errServerKeyExchange
}



+ 1
- 1
prf.go 查看文件

@@ -317,7 +317,7 @@ func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Has
}

if h.version == VersionSSL30 {
if sigType != signatureRSA {
if sigType != signaturePKCS1v15 {
return nil, errors.New("tls: unsupported signature type for client certificate")
}



正在加载...
取消
保存