/** * Verify the ocsp status of a certificate */ cert_status_t verify_by_ocsp(const cert_t *cert, time_t *until, time_t *revocationDate, crl_reason_t *revocationReason) { x509_t *x509 = (x509_t*)cert->cert; chunk_t serialNumber = x509->get_serial(x509); cert_status_t status; ocsp_location_t location; time_t nextUpdate = UNDEFINED_TIME; *revocationDate = UNDEFINED_TIME; *revocationReason = CRL_REASON_UNSPECIFIED; /* is an ocsp location defined? */ if (!build_ocsp_location(cert, &location)) { return CERT_UNDEFINED; } lock_ocsp_cache("verify_by_ocsp"); status = get_ocsp_status(&location, serialNumber, &nextUpdate , revocationDate, revocationReason); unlock_ocsp_cache("verify_by_ocsp"); if (status == CERT_UNDEFINED || nextUpdate < time(NULL)) { plog("ocsp status is stale or not in cache"); add_ocsp_fetch_request(&location, serialNumber); /* inititate fetching of ocsp status */ wake_fetch_thread("verify_by_ocsp"); } *until = nextUpdate; return status; }
/* * verify the ocsp status of a certificate */ bool verify_by_ocsp(/*const*/ x509cert_t *cert, bool strict, time_t *until) { u_char status; ocsp_location_t location; time_t nextUpdate = 0; /* is an ocsp location defined? */ if (!build_ocsp_location(cert, &location)) return FALSE; lock_ocsp_cache("verify_by_ocsp"); status = get_ocsp_status(&location, cert->serialNumber, &nextUpdate); unlock_ocsp_cache("verify_by_ocsp"); #ifdef HAVE_THREADS if (status == CERT_UNDEFINED || nextUpdate < time(NULL)) { openswan_log("ocsp status is stale or not in cache"); add_ocsp_fetch_request(&location, cert->serialNumber); /* inititate fetching of ocsp status */ wake_fetch_thread("verify_by_ocsp"); return !strict; } #endif switch (status) { case CERT_GOOD: DBG(DBG_CONTROL, DBG_log("certificate is good") ) /* with strict crl policy the public key must have the * same lifetime as the validity of the ocsp status */ if (strict && nextUpdate < *until) *until = nextUpdate; break; case CERT_REVOKED: plog("certificate is revoked"); remove_x509_public_key(cert); return FALSE; case CERT_UNKNOWN: plog("certificate status unkown"); if (strict) { remove_x509_public_key(cert); return FALSE; } break; } return TRUE; }
/* * check if an ocsp status is about to expire */ void check_ocsp(void) { ocsp_location_t *location; lock_ocsp_cache("check_ocsp"); location = ocsp_cache; while (location != NULL) { char buf[BUF_LEN]; bool first = TRUE; ocsp_certinfo_t *certinfo = location->certinfo; while (certinfo != NULL) { if (!certinfo->once) { time_t time_left = certinfo->nextUpdate - time(NULL); DBG(DBG_CONTROL, if (first) { dntoa(buf, BUF_LEN, location->issuer); DBG_log("issuer: '%s'", buf); if (location->authKeyID.ptr != NULL) { datatot(location->authKeyID.ptr, location->authKeyID.len , ':', buf, BUF_LEN); DBG_log("authkey: %s", buf); } first = FALSE; } datatot(certinfo->serialNumber.ptr, certinfo->serialNumber.len , ':', buf, BUF_LEN); DBG_log("serial: %s, %ld seconds left", buf, time_left) ) #ifdef HAVE_THREADS if (time_left < 2*crl_check_interval) add_ocsp_fetch_request(location, certinfo->serialNumber); #endif } certinfo = certinfo->next; } location = location->next; }