From 5623c86b5678ef93e9670a6f7bc412e2c8dda62a Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Fri, 8 Dec 2017 13:45:24 +0100 Subject: ocsp: enhanced the OCSP response loading APIs Introduced gnutls_certificate_set_ocsp_status_request_file2() and gnutls_certificate_set_ocsp_status_request_mem(). These functions behave as the equivalent certificate loading functions and pre-load the OCSP response provided as a file, either in DER or in PEM form. In addition, ensure that if the server is provided a problematic OCSP response, or the OCSP response is not renewed before it is invalid, we will not provide it to the clients. Signed-off-by: Nikos Mavrogiannopoulos --- lib/tls13/certificate.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) (limited to 'lib/tls13/certificate.c') diff --git a/lib/tls13/certificate.c b/lib/tls13/certificate.c index f9cddb8bc5..b8451220e9 100644 --- a/lib/tls13/certificate.c +++ b/lib/tls13/certificate.c @@ -121,26 +121,42 @@ int append_status_request(void *_ctx, gnutls_buffer_st *buf) gnutls_session_t session = ctx->session; int ret; gnutls_datum_t resp; + unsigned free_resp = 0; - assert(session->internals.selected_ocsp_func != NULL || ctx->cred->glob_ocsp_func != NULL); + assert(session->internals.selected_ocsp_func != NULL || ctx->cred->glob_ocsp_func != NULL || + session->internals.selected_ocsp_length != 0); /* The global ocsp callback function can only be used to return * a single certificate request */ - if (!session->internals.selected_ocsp_func && ctx->cert_index != 0) + if (session->internals.selected_ocsp_length == 1 && ctx->cert_index != 0) return 0; if (session->internals.selected_ocsp_length > 0) { if (ctx->cert_index < session->internals.selected_ocsp_length) { - resp.data = session->internals.selected_ocsp[ctx->cert_index].data; - resp.size = session->internals.selected_ocsp[ctx->cert_index].size; + if ((session->internals.selected_ocsp[ctx->cert_index].exptime != 0 && + gnutls_time(0) >= session->internals.selected_ocsp[ctx->cert_index].exptime) || + session->internals.selected_ocsp[ctx->cert_index].response.data == NULL) { + return 0; + } + + resp.data = session->internals.selected_ocsp[ctx->cert_index].response.data; + resp.size = session->internals.selected_ocsp[ctx->cert_index].response.size; ret = 0; } else { return 0; } } else if (session->internals.selected_ocsp_func) { - if (ctx->cert_index == 0) + if (ctx->cert_index == 0) { ret = session->internals.selected_ocsp_func(session, session->internals.selected_ocsp_func_ptr, &resp); - else { + free_resp = 1; + } else { + return 0; + } + } else if (ctx->cred->glob_ocsp_func) { + if (ctx->cert_index == 0) { + ret = ctx->cred->glob_ocsp_func(session, ctx->cred->glob_ocsp_func_ptr, &resp); + free_resp = 1; + } else { return 0; } } else @@ -166,7 +182,8 @@ int append_status_request(void *_ctx, gnutls_buffer_st *buf) ret = 0; cleanup: - gnutls_free(resp.data); + if (free_resp) + gnutls_free(resp.data); return ret; } @@ -243,8 +260,9 @@ int _gnutls13_send_certificate(gnutls_session_t session, unsigned again) } #ifdef ENABLE_OCSP - if ((session->internals.selected_ocsp_func != NULL || - cred->glob_ocsp_func != NULL) && + if ((session->internals.selected_ocsp_length > 0 || + session->internals.selected_ocsp_func || + cred->glob_ocsp_func) && _gnutls_hello_ext_is_present(session, GNUTLS_EXTENSION_STATUS_REQUEST)) { /* append status response if available */ ret = _gnutls_extv_append_init(&buf); -- cgit v1.2.1