don't expect CertificateVerify when the client doesn't send any cert

This commit is contained in:
Marten Seemann 2018-10-12 14:27:02 +01:00 зафіксовано Kris Kwiatkowski
джерело ce53b126bc
коміт 6fcf1bc4c0
2 змінених файлів з 36 додано та 38 видалено

56
13.go

@ -349,11 +349,11 @@ func (hs *serverHandshakeState) readClientFinished13(hasConfirmLock bool) error
}
// client authentication
if certMsg, ok := msg.(*certificateMsg13); ok {
// (4.4.2) Client MUST send certificate msg if requested by server
if c.config.ClientAuth < RequestClientCert {
c.sendAlert(alertUnexpectedMessage)
// (4.4.2) Client MUST send certificate msg if requested by server
if c.config.ClientAuth >= RequestClientCert && !c.didResume {
certMsg, ok := msg.(*certificateMsg13)
if !ok {
c.sendAlert(alertCertificateRequired)
return unexpectedMessageError(certMsg, msg)
}
@ -364,39 +364,37 @@ func (hs *serverHandshakeState) readClientFinished13(hasConfirmLock bool) error
return err
}
// 4.4.3: CertificateVerify MUST appear immediately after Certificate msg
msg, err = c.readHandshake()
if err != nil {
return err
}
if len(certs) > 0 {
// 4.4.3: CertificateVerify MUST appear immediately after Certificate msg
msg, err = c.readHandshake()
if err != nil {
return err
}
certVerify, ok := msg.(*certificateVerifyMsg)
if !ok {
c.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(certVerify, msg)
}
certVerify, ok := msg.(*certificateVerifyMsg)
if !ok {
c.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(certVerify, msg)
}
err, alertCode := verifyPeerHandshakeSignature(
certVerify,
pubKey,
supportedSignatureAlgorithms13,
hs.keySchedule.transcriptHash.Sum(nil),
"TLS 1.3, client CertificateVerify")
if err != nil {
c.sendAlert(alertCode)
return err
err, alertCode := verifyPeerHandshakeSignature(
certVerify,
pubKey,
supportedSignatureAlgorithms13,
hs.keySchedule.transcriptHash.Sum(nil),
"TLS 1.3, client CertificateVerify")
if err != nil {
c.sendAlert(alertCode)
return err
}
hs.keySchedule.write(certVerify.marshal())
}
hs.keySchedule.write(certVerify.marshal())
// Read next chunk
msg, err = c.readHandshake()
if err != nil {
return err
}
} else if (c.config.ClientAuth >= RequestClientCert) && !c.didResume {
c.sendAlert(alertCertificateRequired)
return unexpectedMessageError(certMsg, msg)
}
clientFinished, ok := msg.(*finishedMsg)

@ -578,15 +578,6 @@ func (hs *serverHandshakeState) doFullHandshake() error {
}
hs.finishedHash.Write(certMsg.marshal())
if len(certMsg.certificates) == 0 {
// The client didn't actually send a certificate
switch c.config.ClientAuth {
case RequireAnyClientCert, RequireAndVerifyClientCert:
c.sendAlert(alertBadCertificate)
return errors.New("tls: client didn't provide a certificate")
}
}
pub, err = hs.processCertsFromClient(certMsg.certificates)
if err != nil {
return err
@ -787,6 +778,15 @@ func (hs *serverHandshakeState) sendFinished(out []byte) error {
func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) {
c := hs.c
if len(certificates) == 0 {
// The client didn't actually send a certificate
switch c.config.ClientAuth {
case RequireAnyClientCert, RequireAndVerifyClientCert:
c.sendAlert(alertBadCertificate)
return nil, errors.New("tls: client didn't provide a certificate")
}
}
hs.certsFromClient = certificates
certs := make([]*x509.Certificate, len(certificates))
var err error