From: Nikos Mavrogiannopoulos Date: Fri, 28 Sep 2012 17:00:19 +0000 (+0200) Subject: Use the server's OCSP provided data when verifying a certificate's validity. X-Git-Tag: gnutls_3_1_3~76 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dd3b2483a26a852dedb6223e4fcb389c0863998f;p=thirdparty%2Fgnutls.git Use the server's OCSP provided data when verifying a certificate's validity. --- diff --git a/src/cli.c b/src/cli.c index aaf66c1c63..95a6da92ab 100644 --- a/src/cli.c +++ b/src/cli.c @@ -403,7 +403,7 @@ cert_verify_callback (gnutls_session_t session) if (!insecure && !ssh) return -1; } - else if (ENABLED_OPT(OCSP)) + else if (ENABLED_OPT(OCSP) || status_request_ocsp) { /* off-line verification succeeded. Try OCSP */ rc = cert_verify_ocsp(session); if (rc == 0) @@ -1104,6 +1104,9 @@ const char* rest = NULL; record_max_size = OPT_VALUE_RECORDSIZE; status_request_ocsp = HAVE_OPT(STATUS_REQUEST_OCSP); + if (ENABLED_OPT(OCSP)) + status_request_ocsp = 1; + fingerprint = HAVE_OPT(FINGERPRINT); if (HAVE_OPT(X509FMTDER)) @@ -1482,6 +1485,26 @@ cert_verify_ocsp (gnutls_session_t session) ret = -1; goto cleanup; } + + if (status_request_ocsp) + { /* try the server's OCSP response */ + ret = gnutls_status_request_get_ocsp(session, &resp); + if (ret < 0 && !ENABLED_OPT(OCSP)) + { + if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) + fprintf(stderr, "gnutls_status_request_get_ocsp: %s\n", gnutls_strerror(ret)); + ret = -1; + goto cleanup; + } + + if (ret >= 0) + { + ret = check_ocsp_response(issuer, &resp); + if (ret >= 0 || !ENABLED_OPT(OCSP)) + goto cleanup; + } + } + ret = send_ocsp_request(NULL, crt, issuer, &resp, 1); if (ret < 0) diff --git a/src/ocsptool-common.c b/src/ocsptool-common.c index 4436fd7657..1c441b3824 100644 --- a/src/ocsptool-common.c +++ b/src/ocsptool-common.c @@ -302,6 +302,9 @@ print_ocsp_verify_res (unsigned int output) } } +/* three days */ +#define OCSP_VALIDITY_SECS (3*60*60*24) + /* Returns: * 0: certificate is revoked * 1: certificate is ok @@ -314,7 +317,9 @@ check_ocsp_response (gnutls_x509_crt_t issuer, gnutls_ocsp_resp_t resp; int ret; unsigned int status, cert_status; - time_t rtime, ttime; + time_t rtime, vtime, ntime, now; + + now = time(0); ret = gnutls_ocsp_resp_init (&resp); if (ret < 0) @@ -344,7 +349,7 @@ check_ocsp_response (gnutls_x509_crt_t issuer, } ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL, - &cert_status, &ttime, NULL, &rtime, NULL); + &cert_status, &vtime, &ntime, &rtime, NULL); if (ret < 0) error (EXIT_FAILURE, 0, "reading response: %s", gnutls_strerror (ret)); @@ -355,7 +360,27 @@ check_ocsp_response (gnutls_x509_crt_t issuer, goto cleanup; } - printf("- OCSP server flags certificate not revoked as of %s", ctime(&ttime)); + if (ntime == -1) + { + if (now - vtime > OCSP_VALIDITY_SECS) + { + printf("*** The OCSP response is old (was issued at: %s) ignoring", ctime(&vtime)); + ret = -1; + goto cleanup; + } + } + else + { + /* there is a newer OCSP answer, don't trust this one */ + if (ntime < now) + { + printf("*** The OCSP response was issued at: %s, but there is a newer issue at %s", ctime(&vtime), ctime(&ntime)); + ret = -1; + goto cleanup; + } + } + + printf("- OCSP server flags certificate not revoked as of %s", ctime(&vtime)); ret = 1; cleanup: gnutls_ocsp_resp_deinit (resp);