|
|
@@ -17,7 +17,6 @@ import ( |
|
|
|
"io" |
|
|
|
"math/big" |
|
|
|
"net" |
|
|
|
"strconv" |
|
|
|
"time" |
|
|
|
|
|
|
|
"./ed25519" |
|
|
@@ -1678,78 +1677,17 @@ func (hs *clientHandshakeState) writeHash(msg []byte, seqno uint16) { |
|
|
|
// certificate, or none if none match. It may return a particular certificate or |
|
|
|
// nil on success, or an error on internal error. |
|
|
|
func selectClientCertificate(c *Conn, certReq *certificateRequestMsg) (*Certificate, error) { |
|
|
|
// RFC 4346 on the certificateAuthorities field: |
|
|
|
// A list of the distinguished names of acceptable certificate |
|
|
|
// authorities. These distinguished names may specify a desired |
|
|
|
// distinguished name for a root CA or for a subordinate CA; thus, this |
|
|
|
// message can be used to describe both known roots and a desired |
|
|
|
// authorization space. If the certificate_authorities list is empty |
|
|
|
// then the client MAY send any certificate of the appropriate |
|
|
|
// ClientCertificateType, unless there is some external arrangement to |
|
|
|
// the contrary. |
|
|
|
|
|
|
|
var rsaAvail, ecdsaAvail bool |
|
|
|
if !certReq.hasRequestContext { |
|
|
|
for _, certType := range certReq.certificateTypes { |
|
|
|
switch certType { |
|
|
|
case CertTypeRSASign: |
|
|
|
rsaAvail = true |
|
|
|
case CertTypeECDSASign: |
|
|
|
ecdsaAvail = true |
|
|
|
} |
|
|
|
} |
|
|
|
if len(c.config.Certificates) == 0 { |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
|
|
|
|
// We need to search our list of client certs for one |
|
|
|
// where SignatureAlgorithm is RSA and the Issuer is in |
|
|
|
// certReq.certificateAuthorities |
|
|
|
findCert: |
|
|
|
for i, chain := range c.config.Certificates { |
|
|
|
if !certReq.hasRequestContext && !rsaAvail && !ecdsaAvail { |
|
|
|
continue |
|
|
|
} |
|
|
|
|
|
|
|
// Ensure the private key supports one of the advertised |
|
|
|
// signature algorithms. |
|
|
|
if certReq.hasSignatureAlgorithm { |
|
|
|
if _, err := selectSignatureAlgorithm(c.vers, chain.PrivateKey, c.config, certReq.signatureAlgorithms); err != nil { |
|
|
|
continue |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for j, cert := range chain.Certificate { |
|
|
|
x509Cert := chain.Leaf |
|
|
|
// parse the certificate if this isn't the leaf |
|
|
|
// node, or if chain.Leaf was nil |
|
|
|
if j != 0 || x509Cert == nil { |
|
|
|
var err error |
|
|
|
if x509Cert, err = x509.ParseCertificate(cert); err != nil { |
|
|
|
c.sendAlert(alertInternalError) |
|
|
|
return nil, errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if !certReq.hasRequestContext { |
|
|
|
switch { |
|
|
|
case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA: |
|
|
|
case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA: |
|
|
|
case ecdsaAvail && isEd25519Certificate(x509Cert): |
|
|
|
default: |
|
|
|
continue findCert |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if expected := c.config.Bugs.ExpectCertificateReqNames; expected != nil { |
|
|
|
if !eqByteSlices(expected, certReq.certificateAuthorities) { |
|
|
|
return nil, fmt.Errorf("tls: CertificateRequest names differed, got %#v but expected %#v", certReq.certificateAuthorities, expected) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return &chain, nil |
|
|
|
} |
|
|
|
// The test is assumed to have configured the certificate it meant to |
|
|
|
// send. |
|
|
|
if len(c.config.Certificates) > 1 { |
|
|
|
return nil, errors.New("tls: multiple certificates configured") |
|
|
|
} |
|
|
|
|
|
|
|
return nil, nil |
|
|
|
return &c.config.Certificates[0], nil |
|
|
|
} |
|
|
|
|
|
|
|
// clientSessionCacheKey returns a key used to cache sessionTickets that could |
|
|
|