diff --git a/src/crypto/tls/auth.go b/src/crypto/tls/auth.go index 51113d88969..86811ab5b18 100644 --- a/src/crypto/tls/auth.go +++ b/src/crypto/tls/auth.go @@ -259,72 +259,26 @@ func signatureSchemesForCertificate(version uint16, cert *Certificate) []Signatu return sigAlgs } -// signatureSchemeForDelegatedCredential returns the list of supported -// SignatureSchemes for a given delegated credential, based on the public -// key, and optionally filtered by its explicit -// SupportedSignatureAlgorithmsDC. -// -// This function must be kept in sync with supportedSignatureAlgorithmsDC. -func signatureSchemeForDelegatedCredential(version uint16, dc *DelegatedCredential) []SignatureScheme { - pub := dc.cred.publicKey - - var sigAlgs []SignatureScheme - switch pub.(type) { - case *ecdsa.PublicKey: - pk, ok := pub.(*ecdsa.PublicKey) - if !ok { - return nil - } - switch pk.Curve { - case elliptic.P256(): - sigAlgs = []SignatureScheme{ECDSAWithP256AndSHA256} - case elliptic.P384(): - sigAlgs = []SignatureScheme{ECDSAWithP384AndSHA384} - case elliptic.P521(): - sigAlgs = []SignatureScheme{ECDSAWithP521AndSHA512} - default: - return nil - } - case ed25519.PublicKey: - sigAlgs = []SignatureScheme{Ed25519} - case circlSign.PublicKey: - pk, ok := pub.(circlSign.PublicKey) - if !ok { - return nil - } - scheme := pk.Scheme() - tlsScheme, ok := scheme.(circlPki.TLSScheme) - if !ok { - return nil - } - sigAlgs = []SignatureScheme{SignatureScheme(tlsScheme.TLSIdentifier())} - default: - return nil - } - - return sigAlgs -} - // selectSignatureSchemeDC picks a SignatureScheme from the peer's preference list // that works with the selected delegated credential. It's only called for protocol // versions that support delegated credential, so TLS 1.3. -func selectSignatureSchemeDC(vers uint16, dc *DelegatedCredential, peerAlgs []SignatureScheme) (SignatureScheme, error) { +func selectSignatureSchemeDC(vers uint16, dc *DelegatedCredential, peerAlgs []SignatureScheme, peerAlgsDC []SignatureScheme) (SignatureScheme, error) { if vers != VersionTLS13 { return 0, errors.New("unsupported TLS version for dc") } - supportedAlgs := signatureSchemeForDelegatedCredential(vers, dc) - if len(supportedAlgs) == 0 { - return 0, errors.New("unsupported scheme for dc") + if !isSupportedSignatureAlgorithm(dc.algorithm, peerAlgs) { + return undefinedSignatureScheme, errors.New("tls: peer doesn't support the delegated credential's signature") } + // Pick signature scheme in the peer's preference order, as our // preference order is not configurable. - for _, preferredAlg := range peerAlgs { - if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) { + for _, preferredAlg := range peerAlgsDC { + if preferredAlg == dc.cred.expCertVerfAlgo { return preferredAlg, nil } } - return 0, errors.New("tls: peer doesn't support any of the delegated credential's signature algorithms") + return 0, errors.New("tls: peer doesn't support the delegated credential's signature algorithm") } // selectSignatureScheme picks a SignatureScheme from the peer's preference list diff --git a/src/crypto/tls/delegated_credentials.go b/src/crypto/tls/delegated_credentials.go index 1fae172d2eb..2bf5bfd2a2d 100644 --- a/src/crypto/tls/delegated_credentials.go +++ b/src/crypto/tls/delegated_credentials.go @@ -21,6 +21,7 @@ import ( "crypto/ed25519" "crypto/elliptic" "crypto/rand" + "crypto/rsa" "crypto/x509" "encoding/binary" "errors" @@ -40,6 +41,10 @@ const ( dcMaxSignatureLen = (1 << 16) - 1 // Bytes ) +const ( + undefinedSignatureScheme SignatureScheme = 0x0000 +) + var extensionDelegatedCredential = []int{1, 3, 6, 1, 4, 1, 44363, 44} // isValidForDelegation returns true if a certificate can be used for Delegated @@ -61,7 +66,6 @@ func isValidForDelegation(cert *x509.Certificate) bool { return true } } - return false } @@ -133,6 +137,7 @@ func (cred *credential) marshalPublicKeyInfo() ([]byte, error) { } return rawPub, nil + default: return nil, fmt.Errorf("tls: unsupported signature scheme: 0x%04x", cred.expCertVerfAlgo) } @@ -228,6 +233,12 @@ func getHash(scheme SignatureScheme) crypto.Hash { return crypto.SHA512 case Ed25519: return directSigning + case PKCS1WithSHA256, PSSWithSHA256: + return crypto.SHA256 + case PSSWithSHA384: + return crypto.SHA384 + case PSSWithSHA512: + return crypto.SHA512 default: return 0 //Unknown hash function } @@ -291,28 +302,29 @@ func prepareDelegationSignatureInput(hash crypto.Hash, cred *credential, dCert [ // Extract the algorithm used to sign the Delegated Credential from the // end-entity (leaf) certificate. func getSignatureAlgorithm(cert *Certificate) (SignatureScheme, error) { - var sigAlgo SignatureScheme switch sk := cert.PrivateKey.(type) { case *ecdsa.PrivateKey: pk := sk.Public().(*ecdsa.PublicKey) curveName := pk.Curve.Params().Name - certAlg := cert.Leaf.SignatureAlgorithm - if certAlg == x509.ECDSAWithSHA256 && curveName == "P-256" { - sigAlgo = ECDSAWithP256AndSHA256 - } else if certAlg == x509.ECDSAWithSHA384 && curveName == "P-384" { - sigAlgo = ECDSAWithP384AndSHA384 - } else if certAlg == x509.ECDSAWithSHA512 && curveName == "P-521" { - sigAlgo = ECDSAWithP521AndSHA512 + certAlg := cert.Leaf.PublicKeyAlgorithm + if certAlg == x509.ECDSA && curveName == "P-256" { + return ECDSAWithP256AndSHA256, nil + } else if certAlg == x509.ECDSA && curveName == "P-384" { + return ECDSAWithP384AndSHA384, nil + } else if certAlg == x509.ECDSA && curveName == "P-521" { + return ECDSAWithP521AndSHA512, nil } else { - return SignatureScheme(0x00), fmt.Errorf("using curve %s for %s is not supported", curveName, cert.Leaf.SignatureAlgorithm) + return undefinedSignatureScheme, fmt.Errorf("using curve %s for %s is not supported", curveName, cert.Leaf.SignatureAlgorithm) } case ed25519.PrivateKey: - sigAlgo = Ed25519 + return Ed25519, nil + case *rsa.PrivateKey: + // If the certificate has the RSAEncryption OID there are a number of valid signature schemes that may sign the DC. + // In the absence of better information, we make a reasonable choice. + return PSSWithSHA256, nil default: - return SignatureScheme(0x00), fmt.Errorf("tls: unsupported algorithm for Delegated Credential") + return undefinedSignatureScheme, fmt.Errorf("tls: unsupported algorithm for signing Delegated Credential") } - - return sigAlgo, nil } // NewDelegatedCredential creates a new Delegated Credential using 'cert' for @@ -365,7 +377,7 @@ func NewDelegatedCredential(cert *Certificate, pubAlgo SignatureScheme, validTim return nil, nil, err } default: - return nil, nil, fmt.Errorf("tls: unsupported algorithm for Delegated Credential: %T", pubAlgo) + return nil, nil, fmt.Errorf("tls: unsupported algorithm for Delegated Credential: %s", pubAlgo) } // Prepare the credential for signing @@ -390,6 +402,13 @@ func NewDelegatedCredential(cert *Certificate, pubAlgo SignatureScheme, validTim if err != nil { return nil, nil, err } + case *rsa.PrivateKey: + opts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, + Hash: hash} + sig, err = rsa.SignPSS(rand.Reader, sk, hash, values, opts) + if err != nil { + return nil, nil, err + } default: return nil, nil, fmt.Errorf("tls: unsupported key type for Delegated Credential") } @@ -448,17 +467,29 @@ func (dc *DelegatedCredential) Validate(cert *x509.Certificate, isClient bool, n } return ed25519.Verify(pk, in, dc.signature) + case PSSWithSHA256, + PSSWithSHA384, + PSSWithSHA512: + pk, ok := cert.PublicKey.(*rsa.PublicKey) + if !ok { + return false + } + hash := getHash(dc.algorithm) + return rsa.VerifyPSS(pk, hash, in, dc.signature, nil) == nil default: return false } } -// marshal encodes a DelegatedCredential structure. It also sets dc.Raw to that +// Marshal encodes a DelegatedCredential structure. It also sets dc.Raw to that // encoding. -func (dc *DelegatedCredential) marshal() ([]byte, error) { +func (dc *DelegatedCredential) Marshal() ([]byte, error) { if len(dc.signature) > dcMaxSignatureLen { return nil, errors.New("tls: delegated credential is not valid") } + if len(dc.signature) == 0 { + return nil, errors.New("tls: delegated credential has no signature") + } raw, err := dc.cred.marshal() if err != nil { @@ -475,8 +506,8 @@ func (dc *DelegatedCredential) marshal() ([]byte, error) { return dc.raw, nil } -// unmarshalDelegatedCredential decodes a DelegatedCredential structure. -func unmarshalDelegatedCredential(raw []byte) (*DelegatedCredential, error) { +// UnmarshalDelegatedCredential decodes a DelegatedCredential structure. +func UnmarshalDelegatedCredential(raw []byte) (*DelegatedCredential, error) { rawCredentialLen, err := getCredentialLen(raw) if err != nil { return nil, err diff --git a/src/crypto/tls/delegated_credentials_test.go b/src/crypto/tls/delegated_credentials_test.go index 3e898562122..0f399768154 100644 --- a/src/crypto/tls/delegated_credentials_test.go +++ b/src/crypto/tls/delegated_credentials_test.go @@ -385,12 +385,12 @@ func TestDelegatedCredentialMarshal(t *testing.T) { t.Fatal(err) } - ser, err := delegatedCred.marshal() + ser, err := delegatedCred.Marshal() if err != nil { t.Error(err) } - delegatedCred2, err := unmarshalDelegatedCredential(ser) + delegatedCred2, err := UnmarshalDelegatedCredential(ser) if err != nil { t.Error(err) } @@ -466,6 +466,12 @@ func testServerGetCertificate(ch *ClientHelloInfo) (*Certificate, error) { } +// Used when the server doesn't support DCs. +// This function always returns a non-DC cert. +func testServerGetCertificateNoDC(ch *ClientHelloInfo) (*Certificate, error) { + return dcTestCerts["no dc"], nil +} + // Checks that the client suppports a version >= 1.3 and accepts Delegated // Credentials. If so, it returns the delegation certificate; otherwise it // returns a non-Delegated certificate. @@ -507,8 +513,8 @@ func testConnWithDC(t *testing.T, clientMsg, serverMsg string, clientConfig, ser } serverCh <- server }() - client, err := Dial("tcp", ln.Addr().String(), clientConfig) + if err != nil { return false, err } @@ -552,20 +558,22 @@ func testConnWithDC(t *testing.T, clientMsg, serverMsg string, clientConfig, ser func TestDCHandshakeServerAuth(t *testing.T) { serverMsg := "hello, client" clientMsg := "hello, server" - + initDCTest() clientConfig := dcTestConfig.Clone() serverConfig := dcTestConfig.Clone() - clientConfig.InsecureSkipVerify = true for i, test := range dcServerTests { clientConfig.SupportDelegatedCredential = test.clientDCSupport - - initDCTest() for dcCount = 0; dcCount < len(dcTestDCSignatureScheme); dcCount++ { - serverConfig.GetCertificate = testServerGetCertificate + if test.serverMaxVers < VersionTLS13 { + t.Logf("Server doesn't support DCs, not offering. test %d", i) + serverConfig.GetCertificate = testServerGetCertificateNoDC + } else { + serverConfig.GetCertificate = testServerGetCertificate + } + clientConfig.MaxVersion = test.clientMaxVers serverConfig.MaxVersion = test.serverMaxVers - usedDC, err := testConnWithDC(t, clientMsg, serverMsg, clientConfig, serverConfig, "client") if err != nil && test.expectSuccess { @@ -586,6 +594,7 @@ func TestDCHandshakeClientAuth(t *testing.T) { clientMsg := "hello, server" serverMsg := "hello, client" + initDCTest() serverConfig := dcTestConfig.Clone() serverConfig.ClientAuth = RequestClientCert serverConfig.GetCertificate = testServerGetCertificate @@ -595,7 +604,6 @@ func TestDCHandshakeClientAuth(t *testing.T) { for j, test := range dcClientTests { serverConfig.SupportDelegatedCredential = test.serverDCSupport - initDCTest() for dcCount = 0; dcCount < len(dcTestDCSignatureScheme); dcCount++ { serverConfig.MaxVersion = test.serverMaxVers clientConfig.MaxVersion = test.clientMaxVers @@ -620,6 +628,7 @@ func TestDCHandshakeClientAndServerAuth(t *testing.T) { clientMsg := "hello, server" serverMsg := "hello, client" + initDCTest() serverConfig := dcTestConfig.Clone() serverConfig.ClientAuth = RequestClientCert serverConfig.GetCertificate = testServerGetCertificate @@ -632,8 +641,6 @@ func TestDCHandshakeClientAndServerAuth(t *testing.T) { serverConfig.MaxVersion = VersionTLS13 clientConfig.MaxVersion = VersionTLS13 - initDCTest() - usedDC, err := testConnWithDC(t, clientMsg, serverMsg, clientConfig, serverConfig, "both") if err != nil { diff --git a/src/crypto/tls/generate_delegated_credential.go b/src/crypto/tls/generate_delegated_credential.go new file mode 100644 index 00000000000..f2d41b02f9a --- /dev/null +++ b/src/crypto/tls/generate_delegated_credential.go @@ -0,0 +1,125 @@ +// Copyright 2022 Cloudflare, Inc. All rights reserved. Use of this source code +// is governed by a BSD-style license that can be found in the LICENSE file. + +//go:build ignore + +// Generate a delegated credential with the given signature scheme, signed with +// the given x.509 key pair. Outputs to 'dc.cred' and 'dckey.pem' and will +// overwrite existing files. + +// Example usage: +// generate_delegated_credential -cert-path cert.pem -key-path key.pem -signature-scheme Ed25519 -duration 24h + +package main + +import ( + circlSign "circl/sign" + "crypto" + "crypto/ecdsa" + "crypto/ed25519" + "crypto/rsa" + "crypto/tls" + "crypto/x509" + "encoding/pem" + "errors" + "flag" + "fmt" + "log" + "os" + "path/filepath" + "time" +) + +var ( + validFor = flag.Duration("duration", 5*24*time.Hour, "Duration that credential is valid for") + signatureScheme = flag.String("signature-scheme", "", "The signature scheme used by the DC") + certPath = flag.String("cert-path", "./cert.pem", "Path to signing cert") + keyPath = flag.String("key-path", "./key.pem", "Path to signing key") + isClient = flag.Bool("client-dc", false, "Create a client Delegated Credential") + outPath = flag.String("out-path", "./", "Path to output directory") +) + +var SigStringMap = map[string]tls.SignatureScheme{ + // ECDSA algorithms. Only constrained to a specific curve in TLS 1.3. + "ECDSAWithP256AndSHA256": tls.ECDSAWithP256AndSHA256, + "ECDSAWithP384AndSHA384": tls.ECDSAWithP384AndSHA384, + "ECDSAWithP521AndSHA512": tls.ECDSAWithP521AndSHA512, + + // EdDSA algorithms. + "Ed25519": tls.Ed25519, +} + +func main() { + flag.Parse() + sa := SigStringMap[*signatureScheme] + + cert, err := tls.LoadX509KeyPair(*certPath, *keyPath) + if err != nil { + log.Fatalf("Failed to load certificate and key: %v", err) + } + cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0]) + if err != nil { + log.Fatalf("Failed to parse leaf certificate: %v", err) + } + + validTime := time.Since(cert.Leaf.NotBefore) + *validFor + dc, priv, err := tls.NewDelegatedCredential(&cert, sa, validTime, *isClient) + if err != nil { + log.Fatalf("Failed to create a DC: %v\n", err) + } + dcBytes, err := dc.Marshal() + if err != nil { + log.Fatalf("Failed to marshal DC: %v\n", err) + } + + DCOut, err := os.Create(filepath.Join(*outPath, "dc.cred")) + if err != nil { + log.Fatalf("Failed to open dc.cred for writing: %v", err) + } + + DCOut.Write(dcBytes) + if err := DCOut.Close(); err != nil { + log.Fatalf("Error closing dc.cred: %v", err) + } + log.Print("wrote dc.cred\n") + + derBytes, err := x509.MarshalPKCS8PrivateKey(priv) + if err != nil { + log.Fatalf("Failed to marshal DC private key: %v\n", err) + } + + DCKeyOut, err := os.Create(filepath.Join(*outPath, "dckey.pem")) + if err != nil { + log.Fatalf("Failed to open dckey.pem for writing: %v", err) + } + + if err := pem.Encode(DCKeyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: derBytes}); err != nil { + log.Fatalf("Failed to write data to dckey.pem: %v\n", err) + } + if err := DCKeyOut.Close(); err != nil { + log.Fatalf("Error closing dckey.pem: %v\n", err) + } + log.Print("wrote dckey.pem\n") + + fmt.Println("Success") +} + +// Copied from tls.go, because it's private. +func parsePrivateKey(der []byte) (crypto.PrivateKey, error) { + if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { + return key, nil + } + if key, err := x509.ParsePKCS8PrivateKey(der); err == nil { + switch key := key.(type) { + case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey, circlSign.PrivateKey: + return key, nil + default: + return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping") + } + } + if key, err := x509.ParseECPrivateKey(der); err == nil { + return key, nil + } + + return nil, errors.New("tls: failed to parse private key") +} diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go index 62a12a2f36b..0ee7c28252b 100644 --- a/src/crypto/tls/handshake_client_tls13.go +++ b/src/crypto/tls/handshake_client_tls13.go @@ -60,7 +60,7 @@ func (hs *clientHandshakeStateTLS13) processDelegatedCredentialFromServer(rawDC return errors.New("tls: got Delegated Credential extension without indication") } - dc, err = unmarshalDelegatedCredential(rawDC) + dc, err = UnmarshalDelegatedCredential(rawDC) if err != nil { c.sendAlert(alertDecodeError) return fmt.Errorf("tls: Delegated Credential: %s", err) @@ -70,6 +70,10 @@ func (hs *clientHandshakeStateTLS13) processDelegatedCredentialFromServer(rawDC c.sendAlert(alertIllegalParameter) return errors.New("tls: Delegated Credential used with invalid signature algorithm") } + if !isSupportedSignatureAlgorithm(dc.algorithm, c.config.supportedSignatureAlgorithms()) { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: Delegated Credential signed with unsupported signature algorithm") + } } if dc != nil { @@ -826,26 +830,21 @@ func certificateRequestInfo(certReq *certificateRequestMsgTLS13, vers uint16, ct // cannot be used for the current connection. func getClientDelegatedCredential(cri *CertificateRequestInfo, cert *Certificate) (*DelegatedCredentialPair, error) { if len(cert.DelegatedCredentials) == 0 { - return nil, errors.New("No Delegated Credential found.") - } - - if len(cert.DelegatedCredentials) == 1 { - // There's only one choice, so no point doing any work. - return &cert.DelegatedCredentials[0], nil + return nil, errors.New("no Delegated Credential found") } for _, dcPair := range cert.DelegatedCredentials { // If the client sent the signature_algorithms in the DC extension, ensure it supports // schemes we can use with this delegated credential. if len(cri.SignatureSchemesDC) > 0 { - if _, err := selectSignatureSchemeDC(VersionTLS13, dcPair.DC, cri.SignatureSchemesDC); err == nil { + if _, err := selectSignatureSchemeDC(VersionTLS13, dcPair.DC, cri.SignatureSchemes, cri.SignatureSchemesDC); err == nil { return &dcPair, nil } } } // No delegated credential can be returned. - return nil, errors.New("No valid Delegated Credential found.") + return nil, errors.New("no valid Delegated Credential found") } func (hs *clientHandshakeStateTLS13) sendClientCertificate() error { @@ -864,11 +863,12 @@ func (hs *clientHandshakeStateTLS13) sendClientCertificate() error { var dcPair *DelegatedCredentialPair if hs.certReq.supportDelegatedCredential && len(hs.certReq.supportedSignatureAlgorithmsDC) > 0 { + // getClientDelegatedCredential selects a delegated credential that the server has advertised support for, if possible. if delegatedCredentialPair, err := getClientDelegatedCredential(cri, cert); err == nil { if delegatedCredentialPair.DC != nil && delegatedCredentialPair.PrivateKey != nil { var err error // Even if the Delegated Credential has already been marshalled, be sure it is the correct one. - if delegatedCredentialPair.DC.raw, err = delegatedCredentialPair.DC.marshal(); err == nil { + if delegatedCredentialPair.DC.raw, err = delegatedCredentialPair.DC.Marshal(); err == nil { dcPair = delegatedCredentialPair cert.DelegatedCredential = dcPair.DC.raw } @@ -910,12 +910,10 @@ func (hs *clientHandshakeStateTLS13) sendClientCertificate() error { if certMsg.delegatedCredential { suppSigAlgo = hs.certReq.supportedSignatureAlgorithmsDC - sigAlgorithm, err = selectSignatureSchemeDC(c.vers, dcPair.DC, suppSigAlgo) - if err != nil { - // getDelegatedCredential returned a delegated credential incompatible with the - // CertificateRequestInfo supported signature algorithms. + if dcPair == nil || dcPair.DC == nil { cert.DelegatedCredential = nil } else { + sigAlgorithm = dcPair.DC.cred.expCertVerfAlgo cert.PrivateKey = dcPair.PrivateKey } } diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go index fa553d8fad2..b01c234d851 100644 --- a/src/crypto/tls/handshake_server_tls13.go +++ b/src/crypto/tls/handshake_server_tls13.go @@ -66,7 +66,7 @@ func (hs *serverHandshakeStateTLS13) processDelegatedCredentialFromClient(rawDC return errors.New("tls: got Delegated Credential extension without indication") } - dc, err = unmarshalDelegatedCredential(rawDC) + dc, err = UnmarshalDelegatedCredential(rawDC) if err != nil { c.sendAlert(alertDecodeError) return fmt.Errorf("tls: Delegated Credential: %s", err) @@ -450,26 +450,21 @@ func cloneHash(in hash.Hash, h crypto.Hash) hash.Hash { // cannot be used for the current connection. func getDelegatedCredential(clientHello *ClientHelloInfo, cert *Certificate) (*DelegatedCredentialPair, error) { if len(cert.DelegatedCredentials) == 0 { - return nil, errors.New("No Delegated Credential found.") - } - - if len(cert.DelegatedCredentials) == 1 { - // There's only one choice, so no point doing any work. - return &cert.DelegatedCredentials[0], nil + return nil, errors.New("no Delegated Credential found") } for _, dcPair := range cert.DelegatedCredentials { // The client must have sent the signature_algorithms in the DC extension: ensure it supports // schemes we can use with this delegated credential. if len(clientHello.SignatureSchemesDC) > 0 { - if _, err := selectSignatureSchemeDC(VersionTLS13, dcPair.DC, clientHello.SignatureSchemesDC); err == nil { + if _, err := selectSignatureSchemeDC(VersionTLS13, dcPair.DC, clientHello.SignatureSchemes, clientHello.SignatureSchemesDC); err == nil { return &dcPair, nil } } } // No delegated credential can be returned. - return nil, errors.New("No valid Delegated Credential found.") + return nil, errors.New("no valid Delegated Credential found") } func (hs *serverHandshakeStateTLS13) pickCertificate() error { @@ -506,27 +501,20 @@ func (hs *serverHandshakeStateTLS13) pickCertificate() error { hs.cert = certificate if hs.clientHello.delegatedCredentialSupported && len(hs.clientHello.supportedSignatureAlgorithmsDC) > 0 { + // getDelegatedCredential selects a delegated credential that the client has advertised support for, if possible. delegatedCredentialPair, err := getDelegatedCredential(clientHelloInfo(hs.ctx, c, hs.clientHello), hs.cert) if err != nil { // a Delegated Credential was not found. Fallback to the certificate. return nil } - if delegatedCredentialPair.DC != nil && delegatedCredentialPair.PrivateKey != nil { // Even if the Delegated Credential has already been marshalled, be sure it is the correct one. - delegatedCredentialPair.DC.raw, err = delegatedCredentialPair.DC.marshal() + delegatedCredentialPair.DC.raw, err = delegatedCredentialPair.DC.Marshal() if err != nil { // invalid Delegated Credential. Fallback to the certificate. return nil } - - hs.sigAlg, err = selectSignatureSchemeDC(c.vers, delegatedCredentialPair.DC, hs.clientHello.supportedSignatureAlgorithmsDC) - if err != nil { - // the Delegated Credential is unsupported or - // incompatible with the client's signature algorithms. - // Fallback to the certificate. - return nil - } + hs.sigAlg = delegatedCredentialPair.DC.cred.expCertVerfAlgo hs.cert.PrivateKey = delegatedCredentialPair.PrivateKey hs.cert.DelegatedCredential = delegatedCredentialPair.DC.raw @@ -850,7 +838,6 @@ func (hs *serverHandshakeStateTLS13) sendServerCertificate() error { certVerifyMsg := new(certificateVerifyMsg) certVerifyMsg.hasSignatureAlgorithm = true certVerifyMsg.signatureAlgorithm = hs.sigAlg - sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerifyMsg.signatureAlgorithm) if err != nil { return c.sendAlert(alertInternalError)