Test that we reject Certificate or CertificateRequest in resumption

I was going to add a corresponding test for PAKEs and noticed we
neglected this for PSKs. This also fixes a bug in runner where client
auth + resumption handshakes as a server didn't work right. (I guess
none of our tests exercise this case.)

Change-Id: I9e82dcbca54aedba4059e45c3e40a39b390de34e
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/75667
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
This commit is contained in:
David Benjamin
2025-01-27 08:39:58 -08:00
committed by Boringssl LUCI CQ
parent f0a4948de1
commit afa405fd7c
3 changed files with 70 additions and 25 deletions
+9
View File
@@ -1769,6 +1769,15 @@ type ProtocolBugs struct {
// extension in a TLS 1.3 CertificateRequest.
SendCustomCertificateRequest uint16
// AlwaysSendCertificateRequest, if true, causes the server to send
// CertificateRequest in TLS 1.3, even in handshakes where it is not
// allowed, such as resumption.
AlwaysSendCertificateRequest bool
// AlwaysSendCertificate, if true, causes the server to send Certificate in
// TLS 1.3, even in handshakes where it is not allowed, such as resumption.
AlwaysSendCertificate bool
// SendSNIWarningAlert, if true, causes the server to send an
// unrecognized_name alert before the ServerHello.
SendSNIWarningAlert bool
+26 -25
View File
@@ -1068,32 +1068,33 @@ func (hs *serverHandshakeState) doTLS13Handshake() error {
c.writeRecord(recordTypeHandshake, encryptedExtensions.marshal())
}
if hs.sessionState == nil {
if config.ClientAuth >= RequestClientCert {
// Request a client certificate
certReq := &certificateRequestMsg{
vers: c.wireVersion,
hasSignatureAlgorithm: !config.Bugs.OmitCertificateRequestAlgorithms,
hasRequestContext: true,
requestContext: config.Bugs.SendRequestContext,
customExtension: config.Bugs.SendCustomCertificateRequest,
}
if !config.Bugs.NoSignatureAlgorithms {
certReq.signatureAlgorithms = config.verifySignatureAlgorithms()
}
// An empty list of certificateAuthorities signals to
// the client that it may send any certificate in response
// to our request. When we know the CAs we trust, then
// we can send them down, so that the client can choose
// an appropriate certificate to give to us.
if config.ClientCAs != nil {
certReq.certificateAuthorities = config.ClientCAs.Subjects()
}
hs.writeServerHash(certReq.marshal())
c.writeRecord(recordTypeHandshake, certReq.marshal())
requestClientCert := config.ClientAuth >= RequestClientCert && (hs.sessionState == nil || config.Bugs.AlwaysSendCertificateRequest)
if requestClientCert {
// Request a client certificate
certReq := &certificateRequestMsg{
vers: c.wireVersion,
hasSignatureAlgorithm: !config.Bugs.OmitCertificateRequestAlgorithms,
hasRequestContext: true,
requestContext: config.Bugs.SendRequestContext,
customExtension: config.Bugs.SendCustomCertificateRequest,
}
if !config.Bugs.NoSignatureAlgorithms {
certReq.signatureAlgorithms = config.verifySignatureAlgorithms()
}
// An empty list of certificateAuthorities signals to
// the client that it may send any certificate in response
// to our request. When we know the CAs we trust, then
// we can send them down, so that the client can choose
// an appropriate certificate to give to us.
if config.ClientCAs != nil {
certReq.certificateAuthorities = config.ClientCAs.Subjects()
}
hs.writeServerHash(certReq.marshal())
c.writeRecord(recordTypeHandshake, certReq.marshal())
}
if hs.sessionState == nil || config.Bugs.AlwaysSendCertificate {
certMsg := &certificateMsg{
hasRequestContext: true,
}
@@ -1308,7 +1309,7 @@ func (hs *serverHandshakeState) doTLS13Handshake() error {
// If we requested a client certificate, then the client must send a
// certificate message, even if it's empty.
if config.ClientAuth >= RequestClientCert {
if requestClientCert {
certMsg, err := readHandshakeType[certificateMsg](c)
if err != nil {
return err
+35
View File
@@ -17015,6 +17015,41 @@ func addTLS13HandshakeTests() {
expectedLocalError: "remote error: unexpected message",
})
// PSK/resumption handshakes should not accept CertificateRequest or
// Certificate messages.
testCases = append(testCases, testCase{
testType: clientTest,
name: "CertificateInResumption-TLS13",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
AlwaysSendCertificate: true,
},
},
resumeSession: true,
shouldFail: true,
expectedError: ":UNEXPECTED_MESSAGE:",
expectedLocalError: "remote error: unexpected message",
})
testCases = append(testCases, testCase{
testType: clientTest,
name: "CertificateRequestInResumption-TLS13",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
ClientAuth: RequireAnyClientCert,
Bugs: ProtocolBugs{
AlwaysSendCertificateRequest: true,
},
},
shimCertificate: &rsaCertificate,
resumeSession: true,
shouldFail: true,
expectedError: ":UNEXPECTED_MESSAGE:",
expectedLocalError: "remote error: unexpected message",
})
// If the client or server has 0-RTT enabled but disabled TLS 1.3, it should
// report a reason of protocol_version.
testCases = append(testCases, testCase{