diff options
Diffstat (limited to 'lib/tls13/certificate.c')
-rw-r--r-- | lib/tls13/certificate.c | 26 |
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); |