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 committed by Kris Kwiatkowski
parent ce53b126bc
commit 6fcf1bc4c0
2 changed files with 36 additions and 38 deletions

14
13.go
View File

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

View File

@ -578,15 +578,6 @@ func (hs *serverHandshakeState) doFullHandshake() error {
} }
hs.finishedHash.Write(certMsg.marshal()) 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) pub, err = hs.processCertsFromClient(certMsg.certificates)
if err != nil { if err != nil {
return err return err
@ -787,6 +778,15 @@ func (hs *serverHandshakeState) sendFinished(out []byte) error {
func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) { func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) {
c := hs.c 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 hs.certsFromClient = certificates
certs := make([]*x509.Certificate, len(certificates)) certs := make([]*x509.Certificate, len(certificates))
var err error var err error