From 6ab20d77120f818522863bd43cab20541e0afa57 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Wed, 15 Jan 2020 09:46:38 +0100 Subject: tls13: do not send OCSP responses as client without server requesting In client side ensure we see a request for OCSP from servers before sending one. Relates: #876 Signed-off-by: Nikos Mavrogiannopoulos --- lib/gnutls_int.h | 1 + lib/includes/gnutls/gnutls.h.in | 4 +++- lib/state.c | 2 ++ lib/tls13/certificate.c | 3 ++- lib/tls13/certificate_request.c | 9 +++++++++ 5 files changed, 17 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index f7cf830ca1..b48805190a 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -1383,6 +1383,7 @@ typedef struct { #define HSK_RECORD_SIZE_LIMIT_SENT (1<<25) /* record_size_limit extension was sent */ #define HSK_RECORD_SIZE_LIMIT_RECEIVED (1<<26) /* server: record_size_limit extension was seen but not accepted yet */ #define HSK_OCSP_REQUESTED (1<<27) /* server: client requested OCSP stapling */ +#define HSK_CLIENT_OCSP_REQUESTED (1<<28) /* client: server requested OCSP stapling */ /* The hsk_flags are for use within the ongoing handshake; * they are reset to zero prior to handshake start by gnutls_handshake. */ diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 1d0f924c26..61232de01b 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1570,6 +1570,7 @@ unsigned gnutls_session_etm_status(gnutls_session_t session); * @GNUTLS_SFLAGS_EARLY_START: The TLS1.3 server session returned early. * @GNUTLS_SFLAGS_EARLY_DATA: The TLS1.3 early data has been received by the server. * @GNUTLS_SFLAGS_CLI_REQUESTED_OCSP: Set when the client has requested OCSP staple during handshake. + * @GNUTLS_SFLAGS_SERV_REQUESTED_OCSP: Set when the server has requested OCSP staple during handshake. * * Enumeration of different session parameters. */ @@ -1585,7 +1586,8 @@ typedef enum { GNUTLS_SFLAGS_POST_HANDSHAKE_AUTH = 1<<8, GNUTLS_SFLAGS_EARLY_START = 1<<9, GNUTLS_SFLAGS_EARLY_DATA = 1<<10, - GNUTLS_SFLAGS_CLI_REQUESTED_OCSP = 1<<11 + GNUTLS_SFLAGS_CLI_REQUESTED_OCSP = 1<<11, + GNUTLS_SFLAGS_SERV_REQUESTED_OCSP = 1<<12 } gnutls_session_flags_t; unsigned gnutls_session_get_flags(gnutls_session_t session); diff --git a/lib/state.c b/lib/state.c index 5e3a7f95aa..dff7312a87 100644 --- a/lib/state.c +++ b/lib/state.c @@ -1576,6 +1576,8 @@ unsigned gnutls_session_get_flags(gnutls_session_t session) flags |= GNUTLS_SFLAGS_EARLY_DATA; if (session->internals.hsk_flags & HSK_OCSP_REQUESTED) flags |= GNUTLS_SFLAGS_CLI_REQUESTED_OCSP; + if (session->internals.hsk_flags & HSK_CLIENT_OCSP_REQUESTED) + flags |= GNUTLS_SFLAGS_SERV_REQUESTED_OCSP; return flags; } diff --git a/lib/tls13/certificate.c b/lib/tls13/certificate.c index 82a45af336..7483251a53 100644 --- a/lib/tls13/certificate.c +++ b/lib/tls13/certificate.c @@ -273,7 +273,8 @@ int _gnutls13_send_certificate(gnutls_session_t session, unsigned again) #ifdef ENABLE_OCSP if ((session->internals.selected_ocsp_length > 0 || session->internals.selected_ocsp_func) && - (session->internals.hsk_flags & HSK_OCSP_REQUESTED)) { + (((session->internals.hsk_flags & HSK_OCSP_REQUESTED) && IS_SERVER(session)) || + ((session->internals.hsk_flags & HSK_CLIENT_OCSP_REQUESTED) && !IS_SERVER(session)))) { /* append status response if available */ ret = _gnutls_extv_append_init(&buf); if (ret < 0) { diff --git a/lib/tls13/certificate_request.c b/lib/tls13/certificate_request.c index 58fdbbc187..7c0eb04d9b 100644 --- a/lib/tls13/certificate_request.c +++ b/lib/tls13/certificate_request.c @@ -26,6 +26,7 @@ #include "handshake.h" #include "tls13/certificate_request.h" #include "ext/signature.h" +#include "ext/status_request.h" #include "mbuffers.h" #include "algorithms.h" #include "auth/cert.h" @@ -108,6 +109,14 @@ int parse_cert_extension(void *_ctx, unsigned tls_id, const uint8_t *data, unsig ctx->pk_algos[ctx->pk_algos_length++] = se->pk; } +#ifdef ENABLE_OCSP + } else if (tls_id == ext_mod_status_request.tls_id) { + if (data_size != 0) + return gnutls_assert_val(GNUTLS_E_TLS_PACKET_DECODING_ERROR); + + /* we are now allowed to send OCSP staples */ + session->internals.hsk_flags |= HSK_CLIENT_OCSP_REQUESTED; +#endif } else if (tls_id == EXTID_CERTIFICATE_AUTHORITIES) { if (data_size < 3) { return gnutls_assert_val(GNUTLS_E_TLS_PACKET_DECODING_ERROR); -- cgit v1.2.1 From f39b85db96c099c5f851f000cb74fb5200e05919 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Wed, 15 Jan 2020 11:05:31 +0100 Subject: tls13: request OCSP responses as a server The TLS1.3 protocol requires the server to advertise an empty OCSP status request extension on its certificate verify message for an OCSP response to be sent by the client. We now always send this extension to allow clients attaching those responses. Resolves: #876 Signed-off-by: Nikos Mavrogiannopoulos --- lib/tls13/certificate_request.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'lib') diff --git a/lib/tls13/certificate_request.c b/lib/tls13/certificate_request.c index 7c0eb04d9b..37e7b41049 100644 --- a/lib/tls13/certificate_request.c +++ b/lib/tls13/certificate_request.c @@ -266,6 +266,11 @@ int write_certificate_authorities(void *ctx, gnutls_buffer_st *buf) size); } +static int append_empty_ext(void *ctx, gnutls_buffer_st *buf) +{ + return GNUTLS_E_INT_RET_0; +} + int _gnutls13_send_certificate_request(gnutls_session_t session, unsigned again) { gnutls_certificate_credentials_t cred; @@ -341,6 +346,17 @@ int _gnutls13_send_certificate_request(gnutls_session_t session, unsigned again) goto cleanup; } +#ifdef ENABLE_OCSP + /* We always advertise our support for OCSP stapling */ + ret = _gnutls_extv_append(&buf, ext_mod_status_request.tls_id, session, + append_empty_ext); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + session->internals.hsk_flags |= HSK_CLIENT_OCSP_REQUESTED; +#endif + ret = _gnutls_extv_append_final(&buf, init_pos, 0); if (ret < 0) { gnutls_assert(); -- cgit v1.2.1