mirror of
https://github.com/refraction-networking/utls.git
synced 2025-04-04 20:47:36 +03:00
crypto/tls: implement Certificate.SupportedSignatureAlgorithms
This will let applications stop crypto/tls from using a certificate key with an algorithm that is not supported by its crypto.Signer, like hardware backed keys that can't do RSA-PSS. Fixes #28660 Change-Id: I294cc06bddf813fff35c5107540c4a1788e1dace Reviewed-on: https://go-review.googlesource.com/c/go/+/205062 Run-TryBot: Filippo Valsorda <filippo@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
This commit is contained in:
parent
0e7f9b3702
commit
555e9b864b
4 changed files with 91 additions and 9 deletions
37
auth.go
37
auth.go
|
@ -154,7 +154,8 @@ func legacyTypeAndHashFromPublicKey(pub crypto.PublicKey) (sigType uint8, hash c
|
|||
}
|
||||
|
||||
// signatureSchemesForCertificate returns the list of supported SignatureSchemes
|
||||
// for a given certificate, based on the public key and the protocol version.
|
||||
// for a given certificate, based on the public key and the protocol version,
|
||||
// and optionally filtered by its explicit SupportedSignatureAlgorithms.
|
||||
//
|
||||
// This function must be kept in sync with supportedSignatureAlgorithms.
|
||||
func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme {
|
||||
|
@ -163,31 +164,33 @@ func signatureSchemesForCertificate(version uint16, cert *Certificate) []Signatu
|
|||
return nil
|
||||
}
|
||||
|
||||
var sigAlgs []SignatureScheme
|
||||
switch pub := priv.Public().(type) {
|
||||
case *ecdsa.PublicKey:
|
||||
if version != VersionTLS13 {
|
||||
// In TLS 1.2 and earlier, ECDSA algorithms are not
|
||||
// constrained to a single curve.
|
||||
return []SignatureScheme{
|
||||
sigAlgs = []SignatureScheme{
|
||||
ECDSAWithP256AndSHA256,
|
||||
ECDSAWithP384AndSHA384,
|
||||
ECDSAWithP521AndSHA512,
|
||||
ECDSAWithSHA1,
|
||||
}
|
||||
break
|
||||
}
|
||||
switch pub.Curve {
|
||||
case elliptic.P256():
|
||||
return []SignatureScheme{ECDSAWithP256AndSHA256}
|
||||
sigAlgs = []SignatureScheme{ECDSAWithP256AndSHA256}
|
||||
case elliptic.P384():
|
||||
return []SignatureScheme{ECDSAWithP384AndSHA384}
|
||||
sigAlgs = []SignatureScheme{ECDSAWithP384AndSHA384}
|
||||
case elliptic.P521():
|
||||
return []SignatureScheme{ECDSAWithP521AndSHA512}
|
||||
sigAlgs = []SignatureScheme{ECDSAWithP521AndSHA512}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
case *rsa.PublicKey:
|
||||
if version != VersionTLS13 {
|
||||
return []SignatureScheme{
|
||||
sigAlgs = []SignatureScheme{
|
||||
// Temporarily disable RSA-PSS in TLS 1.2, see Issue 32425.
|
||||
// PSSWithSHA256,
|
||||
// PSSWithSHA384,
|
||||
|
@ -197,18 +200,30 @@ func signatureSchemesForCertificate(version uint16, cert *Certificate) []Signatu
|
|||
PKCS1WithSHA512,
|
||||
PKCS1WithSHA1,
|
||||
}
|
||||
break
|
||||
}
|
||||
// TLS 1.3 dropped support for PKCS#1 v1.5 in favor of RSA-PSS.
|
||||
return []SignatureScheme{
|
||||
sigAlgs = []SignatureScheme{
|
||||
PSSWithSHA256,
|
||||
PSSWithSHA384,
|
||||
PSSWithSHA512,
|
||||
}
|
||||
case ed25519.PublicKey:
|
||||
return []SignatureScheme{Ed25519}
|
||||
sigAlgs = []SignatureScheme{Ed25519}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
if cert.SupportedSignatureAlgorithms != nil {
|
||||
var filteredSigAlgs []SignatureScheme
|
||||
for _, sigAlg := range sigAlgs {
|
||||
if isSupportedSignatureAlgorithm(sigAlg, cert.SupportedSignatureAlgorithms) {
|
||||
filteredSigAlgs = append(filteredSigAlgs, sigAlg)
|
||||
}
|
||||
}
|
||||
return filteredSigAlgs
|
||||
}
|
||||
return sigAlgs
|
||||
}
|
||||
|
||||
// selectSignatureScheme picks a SignatureScheme from the peer's preference list
|
||||
|
@ -216,7 +231,7 @@ func signatureSchemesForCertificate(version uint16, cert *Certificate) []Signatu
|
|||
// versions that support signature algorithms, so TLS 1.2 and 1.3.
|
||||
func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) {
|
||||
supportedAlgs := signatureSchemesForCertificate(vers, c)
|
||||
if supportedAlgs == nil {
|
||||
if len(supportedAlgs) == 0 {
|
||||
return 0, unsupportedCertificateError(c)
|
||||
}
|
||||
if len(peerAlgs) == 0 && vers == VersionTLS12 {
|
||||
|
@ -266,5 +281,9 @@ func unsupportedCertificateError(cert *Certificate) error {
|
|||
return fmt.Errorf("tls: unsupported certificate key (%T)", pub)
|
||||
}
|
||||
|
||||
if cert.SupportedSignatureAlgorithms != nil {
|
||||
return fmt.Errorf("tls: peer doesn't support the certificate custom signature algorithms")
|
||||
}
|
||||
|
||||
return fmt.Errorf("tls: internal error: unsupported key (%T)", cert.PrivateKey)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue