Server side of client authentication
This commit is contained in:
parent
68c9776eb9
commit
0d06e5c19c
76
13.go
76
13.go
@ -211,12 +211,26 @@ CurvePreferenceLoop:
|
||||
serverFinishedKey := hkdfExpandLabel(hash, sTrafficSecret, nil, "finished", hashSize)
|
||||
hs.clientFinishedKey = hkdfExpandLabel(hash, cTrafficSecret, nil, "finished", hashSize)
|
||||
|
||||
// EncryptedExtensions
|
||||
hs.keySchedule.write(hs.hello13Enc.marshal())
|
||||
if _, err := c.writeRecord(recordTypeHandshake, hs.hello13Enc.marshal()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: we should have 2 separated methods - one for full-handshake and the other for PSK-handshake
|
||||
if !c.didResume {
|
||||
// Server MUST NOT send CertificateRequest if authenticating with PSK
|
||||
if (c.config.ClientAuth >= RequestClientCert) {
|
||||
|
||||
certReq := new(certificateRequestMsg13)
|
||||
// extension 'signature_algorithms' MUST be specified
|
||||
certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms13
|
||||
hs.keySchedule.write(certReq.marshal())
|
||||
if _, err := hs.c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := hs.sendCertificate13(); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -286,6 +300,43 @@ func (hs *serverHandshakeState) readClientFinished13(hasConfirmLock bool) error
|
||||
return err
|
||||
}
|
||||
|
||||
// client authentication
|
||||
if certMsg, ok := msg.(*certificateMsg13); ok {
|
||||
|
||||
hs.keySchedule.write(certMsg.marshal())
|
||||
pubKey, err := hs.processCertsFromClient13(certMsg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
if err = hs.verifyPeerCertificate(certVerify, pubKey); err != nil {
|
||||
return err
|
||||
}
|
||||
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)
|
||||
if !ok {
|
||||
c.sendAlert(alertUnexpectedMessage)
|
||||
@ -767,6 +818,15 @@ func (hs *clientHandshakeState) processCertsFromServer13(certMsg *certificateMsg
|
||||
return hs.processCertsFromServer(certs)
|
||||
}
|
||||
|
||||
// TODO: Merge with function above
|
||||
func (hs *serverHandshakeState) processCertsFromClient13(certMsg *certificateMsg13) (crypto.PublicKey, error) {
|
||||
certs := make([][]byte, len(certMsg.certificates))
|
||||
for i, cert := range certMsg.certificates {
|
||||
certs[i] = cert.data
|
||||
}
|
||||
return hs.processCertsFromClient(certs)
|
||||
}
|
||||
|
||||
func (hs *clientHandshakeState) processEncryptedExtensions(ee *encryptedExtensionsMsg) error {
|
||||
c := hs.c
|
||||
if ee.alpnProtocol != "" {
|
||||
@ -792,6 +852,22 @@ func (hs *clientHandshakeState) verifyPeerCertificate(certVerify *certificateVer
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: Merge with function above
|
||||
func (hs *serverHandshakeState) verifyPeerCertificate(certVerify *certificateVerifyMsg, pub crypto.PublicKey) error {
|
||||
_, sigType, hashFunc, err := pickSignatureAlgorithm(pub, []SignatureScheme{certVerify.signatureAlgorithm}, supportedSignatureAlgorithms13, hs.c.vers)
|
||||
if err != nil {
|
||||
hs.c.sendAlert(alertHandshakeFailure)
|
||||
return err
|
||||
}
|
||||
digest := prepareDigitallySigned(hashFunc, "TLS 1.3, client CertificateVerify", hs.keySchedule.transcriptHash.Sum(nil))
|
||||
err = verifyHandshakeSignature(sigType, pub, hashFunc, digest, certVerify.signature)
|
||||
if err != nil {
|
||||
hs.c.sendAlert(alertDecryptError)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hs *clientHandshakeState) getCertificate13(certReq *certificateRequestMsg13) (*Certificate, error) {
|
||||
certReq12 := &certificateRequestMsg{
|
||||
hasSignatureAndHash: true,
|
||||
|
Loading…
Reference in New Issue
Block a user