summaryrefslogtreecommitdiff
path: root/lib/tls13/certificate.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tls13/certificate.c')
-rw-r--r--lib/tls13/certificate.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/lib/tls13/certificate.c b/lib/tls13/certificate.c
index 29c7de4590..e53f116213 100644
--- a/lib/tls13/certificate.c
+++ b/lib/tls13/certificate.c
@@ -35,11 +35,25 @@ int _gnutls13_recv_certificate(gnutls_session_t session)
{
int ret;
gnutls_buffer_st buf;
+ unsigned optional = 0;
- ret = _gnutls_recv_handshake(session, GNUTLS_HANDSHAKE_CERTIFICATE_PKT, 0, &buf);
+ if (session->security_parameters.entity == GNUTLS_SERVER) {
+ /* if we didn't request a certificate, there will not be any */
+ if (session->internals.send_cert_req == 0)
+ return 0;
+
+ if (session->internals.send_cert_req != GNUTLS_CERT_REQUIRE)
+ optional = 1;
+ }
+
+ ret = _gnutls_recv_handshake(session, GNUTLS_HANDSHAKE_CERTIFICATE_PKT, optional, &buf);
if (ret < 0)
return gnutls_assert_val(ret);
+ if (buf.length == 0 && optional) {
+ return 0;
+ }
+
if (buf.data[0] != 0) {
/* The context field must be empty during handshake */
gnutls_assert();
@@ -59,6 +73,8 @@ int _gnutls13_recv_certificate(gnutls_session_t session)
goto cleanup;
}
+ session->internals.hsk_flags |= HSK_CRT_VRFY_EXPECTED;
+
ret = 0;
cleanup:
@@ -85,6 +101,14 @@ int _gnutls13_send_certificate(gnutls_session_t session, unsigned again)
if (ret < 0)
return gnutls_assert_val(ret);
+ if (session->security_parameters.entity == GNUTLS_CLIENT) {
+ /* if we didn't get a cert request there will not be any */
+ if (apr_cert_list_length == 0 ||
+ !(session->internals.hsk_flags & HSK_CRT_ASKED)) {
+ return 0;
+ }
+ }
+
ret = _gnutls_buffer_append_prefix(&buf, 8, 0);
if (ret < 0)
return gnutls_assert_val(ret);