29#include <openssl/err.h>
30#include <openssl/evp.h>
31#include <openssl/ocsp.h>
32#include <openssl/pem.h>
33#include <openssl/x509v3.h>
48#define MD_OCSP_ID_LENGTH SHA_DIGEST_LENGTH
106 default:
return "unknown";
121 unsigned int ulen = 0;
193 memset(resp_der, 0,
sizeof(*resp_der));
194 memset(resp_valid, 0,
sizeof(*resp_valid));
213 const char *
s =
NULL;
215 if (resp_der->
len > 0) {
276 const char *user_agent,
const char *proxy_url,
316 "md[%s]: priming OCSP status",
name);
334 "md[%s]: getting ocsp responder from cert",
name);
338 "md[%s]: certificate with serial %s has no OCSP responder URL",
347 "md[%s]: unable to create OCSP certid for certificate with serial %s",
355 "md[%s]: adding ocsp info (responder=%s)",
389 "md[%s]: OCSP, get_status",
name);
410 "md[%s]: OCSP, no response available",
name);
411 cb(
NULL, 0, userdata);
436 "md[%s]: OCSP, provided %ld bytes of response",
471 memset(&valid, 0,
sizeof(valid));
474 "md[%s]: OCSP, get_status",
name);
501 memset(&der, 0,
sizeof(der));
537 return apr_psprintf(
p,
"certid[der=%s, issuer=%s, key=%s, serial=%s]",
547 default:
return "???";
559#if OPENSSL_VERSION_NUMBER < 0x10100000L \
560 || (defined(LIBRESSL_VERSION_NUMBER) \
561 && LIBRESSL_VERSION_NUMBER < 0x2070000f)
562 certid =
resp->certId;
570 return apr_psprintf(
p,
"ocsp-single-resp[%s, status=%s, reason=%d, valid=%s]",
613 "OCSP response, status=%d, body brigade length=%ld",
641 "req[%d]: OCSP response nonce does match", req->
id);
651 "req[%d]: OCSP response did not return the nonce", req->
id);
814 ostat = update->
ostat;
833 "application/ocsp-request", &ostat->
req_der);
839 "scheduling OCSP request[%d] for %s, %d request in flight",
858 update->
p =
ctx->ptemp;
859 update->
ostat = ostat;
892 ctx.max_parallel = 6;
898 "OCSP status updates due: %d",
ctx.todos->nelts);
1049 for (
i = 0;
i <
ctx.ostats->nelts; ++
i) {
const char apr_size_t len
APR-UTIL Buckets/Bucket Brigades.
APR general purpose library routines.
apr_size_t const unsigned char unsigned int unsigned int d
APR Thread Mutex Routines.
ap_vhost_iterate_conn_cb void * baton
apr_brigade_flush void * ctx
void const char apr_status_t(* cleanup)(void *))
const char apr_uint32_t * id
#define apr_pcalloc(p, size)
#define APR_ARRAY_PUSH(ary, type)
#define APR_ARRAY_IDX(ary, i, type)
#define apr_time_sec(time)
#define apr_time_from_sec(sec)
apr_status_t md_job_notify_cb(struct md_job_t *job, const char *reason, struct md_result_t *result, apr_pool_t *p, void *baton)
#define MD_KEY_SHA256_FINGERPRINT
apr_status_t md_cert_to_sha256_fingerprint(const char **pfinger, const md_cert_t *cert, apr_pool_t *p)
const char * md_cert_get_serial_number(const md_cert_t *cert, apr_pool_t *p)
apr_status_t md_cert_get_ocsp_responder_url(const char **purl, apr_pool_t *p, const md_cert_t *cert)
apr_time_t md_asn1_generalized_time_get(void *ASN1_GENERALIZEDTIME)
void * md_cert_get_X509(const md_cert_t *cert)
void md_event_holler(const char *event, const char *mdomain, struct md_job_t *job, struct md_result_t *result, apr_pool_t *p)
apr_status_t md_http_POSTd_create(md_http_request_t **preq, md_http_t *http, const char *url, struct apr_table_t *headers, const char *content_type, const struct md_data_t *body)
apr_status_t md_http_multi_perform(md_http_t *http, md_http_next_req *nextreq, void *baton)
void md_http_set_on_status_cb(md_http_request_t *req, md_http_status_cb *cb, void *baton)
void md_http_set_on_response_cb(md_http_request_t *req, md_http_response_cb *cb, void *baton)
apr_status_t md_http_create(md_http_t **phttp, apr_pool_t *p, const char *user_agent, const char *proxy_url)
md_json_t * md_json_create(apr_pool_t *pool)
apr_status_t md_json_set_timeperiod(const md_timeperiod_t *tp, md_json_t *json,...)
apr_status_t md_json_sets(const char *value, md_json_t *json,...)
const char * md_json_gets(const md_json_t *json,...)
apr_status_t md_json_addj(const md_json_t *value, md_json_t *json,...)
apr_status_t md_json_set_time(apr_time_t value, md_json_t *json,...)
apr_status_t md_json_setj(const md_json_t *value, md_json_t *json,...)
const char * md_json_dups(apr_pool_t *p, const md_json_t *json,...)
apr_status_t md_json_setl(long value, md_json_t *json,...)
void md_log_perror(const char *file, int line, md_log_level_t level, apr_status_t rv, apr_pool_t *p, const char *fmt,...)
static const char * single_resp_summary(OCSP_SINGLERESP *resp, apr_pool_t *p)
static const char * certid_summary(const OCSP_CERTID *certid, apr_pool_t *p)
static apr_status_t ocsp_req_make(OCSP_REQUEST **pocsp_req, OCSP_CERTID *certid)
static int select_next_run(void *baton, const void *key, apr_ssize_t klen, const void *val)
static apr_status_t ostat_on_resp(const md_http_response_t *resp, void *baton)
static apr_status_t ocsp_status_save(md_ocsp_cert_stat_t stat, const md_data_t *resp_der, const md_timeperiod_t *resp_valid, md_ocsp_status_t *ostat, apr_pool_t *ptemp)
static apr_status_t job_loadj(md_json_t **pjson, const char *name, md_ocsp_reg_t *reg, apr_pool_t *p)
static int ostat_should_renew(md_ocsp_status_t *ostat)
static apr_status_t ostat_on_req_status(const md_http_request_t *req, apr_status_t status, void *baton)
const char * md_ocsp_cert_stat_name(md_ocsp_cert_stat_t stat)
static apr_status_t ostat_from_json(md_ocsp_cert_stat_t *pstat, md_data_t *resp_der, md_timeperiod_t *resp_valid, md_json_t *json, apr_pool_t *p)
static void ostat_req_cleanup(md_ocsp_status_t *ostat)
static void ostat_to_json(md_json_t *json, md_ocsp_cert_stat_t stat, const md_data_t *resp_der, const md_timeperiod_t *resp_valid, apr_pool_t *p)
void md_ocsp_get_status_all(md_json_t **pjson, md_ocsp_reg_t *reg, apr_pool_t *p)
apr_size_t md_ocsp_count(md_ocsp_reg_t *reg)
apr_status_t md_ocsp_init_id(md_data_t *id, apr_pool_t *p, const md_cert_t *cert)
static apr_status_t ostat_set(md_ocsp_status_t *ostat, md_ocsp_cert_stat_t stat, md_data_t *der, md_timeperiod_t *valid, apr_time_t mtime)
static int add_ostat(void *baton, const void *key, apr_ssize_t klen, const void *val)
static void ocsp_get_meta(md_ocsp_cert_stat_t *pstat, md_timeperiod_t *pvalid, md_ocsp_reg_t *reg, md_ocsp_status_t *ostat, apr_pool_t *p)
md_job_t * md_ocsp_job_make(md_ocsp_reg_t *ocsp, const char *mdomain, apr_pool_t *p)
void md_ocsp_renew(md_ocsp_reg_t *reg, apr_pool_t *p, apr_pool_t *ptemp, apr_time_t *pnext_run)
static apr_status_t ocsp_req_assign_der(md_data_t *d, OCSP_REQUEST *ocsp_req)
static md_json_t * mk_jstat(md_ocsp_status_t *ostat, md_ocsp_reg_t *reg, apr_pool_t *p)
static apr_status_t ocsp_reg_cleanup(void *data)
static void md_openssl_free(void *d)
static int ostat_cleanup(void *ctx, const void *key, apr_ssize_t klen, const void *val)
apr_status_t md_ocsp_remove_responses_older_than(md_ocsp_reg_t *reg, apr_pool_t *p, apr_time_t timestamp)
void md_ocsp_get_summary(md_json_t **pjson, md_ocsp_reg_t *reg, apr_pool_t *p)
apr_status_t md_ocsp_prime(md_ocsp_reg_t *reg, const char *ext_id, apr_size_t ext_id_len, md_cert_t *cert, md_cert_t *issuer, const md_t *md)
static int md_ostat_cmp(const void *v1, const void *v2)
static const char * certstatus_string(int status)
static int select_updates(void *baton, const void *key, apr_ssize_t klen, const void *val)
static const char * certid_as_hex(const OCSP_CERTID *certid, apr_pool_t *p)
apr_status_t md_ocsp_get_status(md_ocsp_copy_der *cb, void *userdata, md_ocsp_reg_t *reg, const char *ext_id, apr_size_t ext_id_len, apr_pool_t *p, const md_t *md)
md_ocsp_cert_stat_t md_ocsp_cert_stat_value(const char *name)
apr_status_t md_ocsp_get_meta(md_ocsp_cert_stat_t *pstat, md_timeperiod_t *pvalid, md_ocsp_reg_t *reg, const md_cert_t *cert, apr_pool_t *p, const md_t *md)
static apr_status_t next_todo(md_http_request_t **preq, void *baton, md_http_t *http, int in_flight)
static int add_to_summary(void *baton, const void *key, apr_ssize_t klen, const void *val)
static apr_status_t ocsp_status_refresh(md_ocsp_status_t *ostat, apr_pool_t *ptemp)
apr_status_t md_ocsp_reg_make(md_ocsp_reg_t **preg, apr_pool_t *p, md_store_t *store, const md_timeslice_t *renew_window, const char *user_agent, const char *proxy_url, apr_time_t min_delay)
@ MD_OCSP_CERT_ST_REVOKED
@ MD_OCSP_CERT_ST_UNKNOWN
void md_ocsp_copy_der(const unsigned char *der, apr_size_t der_len, void *userdata)
void md_result_activity_printf(md_result_t *result, const char *fmt,...)
void md_result_printf(md_result_t *result, apr_status_t status, const char *fmt,...)
void md_result_log(md_result_t *result, unsigned int level)
void md_result_set(md_result_t *result, apr_status_t status, const char *detail)
md_result_t * md_result_md_make(apr_pool_t *p, const char *md_name)
md_job_t * md_job_make(apr_pool_t *p, md_store_t *store, md_store_group_t group, const char *name, apr_time_t min_delay)
void md_job_start_run(md_job_t *job, md_result_t *result, md_store_t *store)
apr_status_t md_job_load(md_job_t *job)
void md_job_end_run(md_job_t *job, md_result_t *result)
apr_status_t md_job_save(md_job_t *job, md_result_t *result, apr_pool_t *p)
apr_time_t md_job_delay_on_errors(md_job_t *job, int err_count, const char *last_problem)
void md_job_log_append(md_job_t *job, const char *type, const char *status, const char *detail)
apr_status_t md_store_save_json(md_store_t *store, apr_pool_t *p, md_store_group_t group, const char *name, const char *aspect, struct md_json_t *data, int create)
apr_time_t md_store_get_modified(md_store_t *store, md_store_group_t group, const char *name, const char *aspect, apr_pool_t *p)
apr_status_t md_store_remove_not_modified_since(md_store_t *store, apr_pool_t *p, apr_time_t modified, md_store_group_t group, const char *name, const char *aspect)
apr_status_t md_store_load_json(md_store_t *store, md_store_group_t group, const char *name, const char *aspect, struct md_json_t **pdata, apr_pool_t *p)
apr_interval_time_t md_timeperiod_remaining(const md_timeperiod_t *period, apr_time_t time)
int md_timeperiod_has_started(const md_timeperiod_t *period, apr_time_t time)
char * md_timeperiod_print(apr_pool_t *p, const md_timeperiod_t *period)
md_timeperiod_t md_timeperiod_slice_before_end(const md_timeperiod_t *period, const md_timeslice_t *ts)
apr_size_t md_util_base64url_decode(md_data_t *decoded, const char *encoded, apr_pool_t *pool)
void md_data_clear(md_data_t *d)
void md_data_assign_pcopy(md_data_t *dest, const char *src, apr_size_t src_len, apr_pool_t *p)
const char * md_util_base64url_encode(const md_data_t *data, apr_pool_t *pool)
apr_status_t md_data_assign_copy(md_data_t *dest, const char *src, apr_size_t src_len)
apr_status_t md_data_to_hex(const char **phex, char separator, apr_pool_t *p, const md_data_t *data)
void md_data_null(md_data_t *d)
md_data_free_fn * free_data
apr_hash_t * id_by_external_id
md_job_notify_cb * notify
md_timeslice_t renew_window
apr_thread_mutex_t * mutex
apr_time_t resp_last_check
md_timeperiod_t resp_valid
md_ocsp_cert_stat_t resp_stat
const char * responder_url
apr_array_header_t * todos
apr_array_header_t * ostats