package tls
import (
)
func ( uint8, crypto.PublicKey, crypto.Hash, , []byte) error {
switch {
case signatureECDSA:
, := .(*ecdsa.PublicKey)
if ! {
return fmt.Errorf("expected an ECDSA public key, got %T", )
}
if !ecdsa.VerifyASN1(, , ) {
return errors.New("ECDSA verification failure")
}
case signatureEd25519:
, := .(ed25519.PublicKey)
if ! {
return fmt.Errorf("expected an Ed25519 public key, got %T", )
}
if !ed25519.Verify(, , ) {
return errors.New("Ed25519 verification failure")
}
case signaturePKCS1v15:
, := .(*rsa.PublicKey)
if ! {
return fmt.Errorf("expected an RSA public key, got %T", )
}
if := rsa.VerifyPKCS1v15(, , , ); != nil {
return
}
case signatureRSAPSS:
, := .(*rsa.PublicKey)
if ! {
return fmt.Errorf("expected an RSA public key, got %T", )
}
:= &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}
if := rsa.VerifyPSS(, , , , ); != nil {
return
}
default:
return errors.New("internal error: unknown signature type")
}
return nil
}
const (
serverSignatureContext = "TLS 1.3, server CertificateVerify\x00"
clientSignatureContext = "TLS 1.3, client CertificateVerify\x00"
)
var signaturePadding = []byte{
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
}
func ( crypto.Hash, string, hash.Hash) []byte {
if == directSigning {
:= &bytes.Buffer{}
.Write(signaturePadding)
io.WriteString(, )
.Write(.Sum(nil))
return .Bytes()
}
:= .New()
.Write(signaturePadding)
io.WriteString(, )
.Write(.Sum(nil))
return .Sum(nil)
}
func ( SignatureScheme) ( uint8, crypto.Hash, error) {
switch {
case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512:
= signaturePKCS1v15
case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512:
= signatureRSAPSS
case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512:
= signatureECDSA
case Ed25519:
= signatureEd25519
default:
return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", )
}
switch {
case PKCS1WithSHA1, ECDSAWithSHA1:
= crypto.SHA1
case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256:
= crypto.SHA256
case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384:
= crypto.SHA384
case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512:
= crypto.SHA512
case Ed25519:
= directSigning
default:
return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", )
}
return , , nil
}
func ( crypto.PublicKey) ( uint8, crypto.Hash, error) {
switch .(type) {
case *rsa.PublicKey:
return signaturePKCS1v15, crypto.MD5SHA1, nil
case *ecdsa.PublicKey:
return signatureECDSA, crypto.SHA1, nil
case ed25519.PublicKey:
return 0, 0, fmt.Errorf("tls: Ed25519 public keys are not supported before TLS 1.2")
default:
return 0, 0, fmt.Errorf("tls: unsupported public key: %T", )
}
}
var rsaSignatureSchemes = []struct {
scheme SignatureScheme
minModulusBytes int
maxVersion uint16
}{
{PSSWithSHA256, crypto.SHA256.Size()*2 + 2, VersionTLS13},
{PSSWithSHA384, crypto.SHA384.Size()*2 + 2, VersionTLS13},
{PSSWithSHA512, crypto.SHA512.Size()*2 + 2, VersionTLS13},
{PKCS1WithSHA256, 19 + crypto.SHA256.Size() + 11, VersionTLS12},
{PKCS1WithSHA384, 19 + crypto.SHA384.Size() + 11, VersionTLS12},
{PKCS1WithSHA512, 19 + crypto.SHA512.Size() + 11, VersionTLS12},
{PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11, VersionTLS12},
}
func ( uint16, *Certificate) []SignatureScheme {
, := .PrivateKey.(crypto.Signer)
if ! {
return nil
}
var []SignatureScheme
switch pub := .Public().(type) {
case *ecdsa.PublicKey:
if != VersionTLS13 {
= []SignatureScheme{
ECDSAWithP256AndSHA256,
ECDSAWithP384AndSHA384,
ECDSAWithP521AndSHA512,
ECDSAWithSHA1,
}
break
}
switch .Curve {
case elliptic.P256():
= []SignatureScheme{ECDSAWithP256AndSHA256}
case elliptic.P384():
= []SignatureScheme{ECDSAWithP384AndSHA384}
case elliptic.P521():
= []SignatureScheme{ECDSAWithP521AndSHA512}
default:
return nil
}
case *rsa.PublicKey:
:= .Size()
= make([]SignatureScheme, 0, len(rsaSignatureSchemes))
for , := range rsaSignatureSchemes {
if >= .minModulusBytes && <= .maxVersion {
= append(, .scheme)
}
}
case ed25519.PublicKey:
= []SignatureScheme{Ed25519}
default:
return nil
}
if .SupportedSignatureAlgorithms != nil {
var []SignatureScheme
for , := range {
if isSupportedSignatureAlgorithm(, .SupportedSignatureAlgorithms) {
= append(, )
}
}
return
}
return
}
func ( uint16, *Certificate, []SignatureScheme) (SignatureScheme, error) {
:= signatureSchemesForCertificate(, )
if len() == 0 {
return 0, unsupportedCertificateError()
}
if len() == 0 && == VersionTLS12 {
= []SignatureScheme{PKCS1WithSHA1, ECDSAWithSHA1}
}
for , := range {
if isSupportedSignatureAlgorithm(, ) {
return , nil
}
}
return 0, errors.New("tls: peer doesn't support any of the certificate's signature algorithms")
}
func ( *Certificate) error {
switch .PrivateKey.(type) {
case rsa.PrivateKey, ecdsa.PrivateKey:
return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T",
.PrivateKey, .PrivateKey)
case *ed25519.PrivateKey:
return fmt.Errorf("tls: unsupported certificate: private key is *ed25519.PrivateKey, expected ed25519.PrivateKey")
}
, := .PrivateKey.(crypto.Signer)
if ! {
return fmt.Errorf("tls: certificate private key (%T) does not implement crypto.Signer",
.PrivateKey)
}
switch pub := .Public().(type) {
case *ecdsa.PublicKey:
switch .Curve {
case elliptic.P256():
case elliptic.P384():
case elliptic.P521():
default:
return fmt.Errorf("tls: unsupported certificate curve (%s)", .Curve.Params().Name)
}
case *rsa.PublicKey:
return fmt.Errorf("tls: certificate RSA key size too small for supported signature algorithms")
case ed25519.PublicKey:
default:
return fmt.Errorf("tls: unsupported certificate key (%T)", )
}
if .SupportedSignatureAlgorithms != nil {
return fmt.Errorf("tls: peer doesn't support the certificate custom signature algorithms")
}
return fmt.Errorf("tls: internal error: unsupported key (%T)", .PrivateKey)
}