From: Nikos Mavrogiannopoulos Date: Tue, 6 Nov 2012 22:07:12 +0000 (+0100) Subject: Added gnutls_ocsp_status_request_is_checked(). X-Git-Tag: gnutls_3_1_4~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=30e0eed098299705dae650b120d54562dffa4280;p=thirdparty%2Fgnutls.git Added gnutls_ocsp_status_request_is_checked(). --- diff --git a/NEWS b/NEWS index 55d74ce710..5fe0411b42 100644 --- a/NEWS +++ b/NEWS @@ -38,6 +38,7 @@ a site's DANE data. ** API and ABI modifications: gnutls_session_get_id2: Added gnutls_certificate_verify_peers3: Added +gnutls_ocsp_status_request_is_checked: Added gnutls_certificate_verification_status_print: Added gnutls_srtp_set_profile: Added gnutls_srtp_set_profile_direct: Added diff --git a/doc/cha-intro-tls.texi b/doc/cha-intro-tls.texi index 624efb9e22..a83c0f721f 100644 --- a/doc/cha-intro-tls.texi +++ b/doc/cha-intro-tls.texi @@ -580,7 +580,7 @@ may periodically run @code{ocsptool} (see @ref{ocsptool Invocation}) to obtain its certificate revocation status and serve it to the clients. That way a client avoids an additional connection to the OCSP server. -@showfuncC{gnutls_certificate_set_ocsp_status_request_function,gnutls_certificate_set_ocsp_status_request_file,gnutls_ocsp_status_request_enable_client} +@showfuncD{gnutls_certificate_set_ocsp_status_request_function,gnutls_certificate_set_ocsp_status_request_file,gnutls_ocsp_status_request_enable_client,gnutls_ocsp_status_request_is_checked} A server is required to provide the OCSP server's response using the @funcref{gnutls_certificate_set_ocsp_status_request_file}. The response may be obtained periodically using the following command. diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 1081135817..bc03a8c4c4 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -919,6 +919,9 @@ typedef struct unsigned int hb_actual_retrans_timeout_ms; /* current timeout, in milliseconds*/ unsigned int hb_retrans_timeout_ms; /* the default timeout, in milliseconds*/ unsigned int hb_total_timeout_ms; /* the total timeout, in milliseconds*/ + + unsigned int ocsp_check_ok; /* will be zero if the OCSP response TLS extension + * check failed (OCSP was old/unrelated or so). */ heartbeat_state_t hb_state; /* for ping */ diff --git a/lib/gnutls_ui.c b/lib/gnutls_ui.c index 110ebae818..9fb6c50bbb 100644 --- a/lib/gnutls_ui.c +++ b/lib/gnutls_ui.c @@ -825,3 +825,23 @@ gnutls_url_is_supported (const char* url) #endif return 0; } + +/** + * gnutls_ocsp_status_request_is_checked: + * @session: is a gnutls session + * @flags: should be zero + * + * Check whether an OCSP status response was included in the handshake + * and whether it was checked and valid (not too old or superseded). + * This is a helper function when needing to decide whether to perform an + * OCSP validity check on the peer's certificate. Must be called after + * gnutls_certificate_verify_peers3() is called. + * + * Returns: non zero it was valid, or a zero if it wasn't sent, + * or sent and was invalid. + **/ +int +gnutls_ocsp_status_request_is_checked (gnutls_session_t session, unsigned int flags) +{ + return session->internals.ocsp_check_ok; +} diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index bd50d23f10..8188b79852 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -102,6 +102,7 @@ check_ocsp_response (gnutls_session_t session, gnutls_x509_crt_t cert, int ret; unsigned int status, cert_status; time_t rtime, vtime, ntime, now; + int check_failed; now = gnutls_time(0); @@ -157,6 +158,7 @@ check_ocsp_response (gnutls_session_t session, gnutls_x509_crt_t cert, if (now - vtime > MAX_OCSP_VALIDITY_SECS) { _gnutls_audit_log(session, "The OCSP response is old\n"); + check_failed = 1; } } else @@ -165,9 +167,13 @@ check_ocsp_response (gnutls_session_t session, gnutls_x509_crt_t cert, if (ntime < now) { _gnutls_audit_log(session, "There is a newer OCSP response but was not provided by the server\n"); + check_failed = 1; } } + if (check_failed == 0) + session->internals.ocsp_check_ok = 1; + ret = 0; cleanup: gnutls_ocsp_resp_deinit (resp); @@ -205,6 +211,9 @@ _gnutls_x509_cert_verify_peers (gnutls_session_t session, unsigned int ocsp_status = 0; unsigned int verify_flags; + /* No OCSP check so far */ + session->internals.ocsp_check_ok = 0; + CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST); info = _gnutls_get_auth_info (session); diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index c12576d4ae..b91f684df8 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1274,6 +1274,7 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session); int gnutls_ocsp_status_request_get (gnutls_session_t session, gnutls_datum_t *response); + int gnutls_ocsp_status_request_is_checked (gnutls_session_t session, unsigned int flags); /* global state functions */ diff --git a/lib/libgnutls.map b/lib/libgnutls.map index afc2dd4c62..201bdda3e4 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -868,6 +868,7 @@ GNUTLS_3_1_0 { gnutls_srtp_get_keys; gnutls_srtp_get_mki; gnutls_srtp_set_mki; + gnutls_ocsp_status_request_is_checked; } GNUTLS_3_0_0; GNUTLS_PRIVATE {