*/
bool certreq;
+ /**
+ * should we send an OCSP status request?
+ */
+ bool ocsp_certreq;
+
/**
* enforce UDP encapsulation
*/
return this->certreq;
}
+METHOD(ike_cfg_t, send_ocsp_certreq, bool,
+ private_ike_cfg_t *this)
+{
+ return this->ocsp_certreq;
+}
+
METHOD(ike_cfg_t, force_encap_, bool,
private_ike_cfg_t *this)
{
return
this->version == other->version &&
this->certreq == other->certreq &&
+ this->ocsp_certreq == other->ocsp_certreq &&
this->force_encap == other->force_encap &&
this->fragmentation == other->fragmentation &&
this->childless == other->childless &&
.public = {
.get_version = _get_version,
.send_certreq = _send_certreq,
+ .send_ocsp_certreq = _send_ocsp_certreq,
.force_encap = _force_encap_,
.fragmentation = _fragmentation,
.childless = _childless,
.refcount = 1,
.version = data->version,
.certreq = !data->no_certreq,
+ .ocsp_certreq = !data->no_ocsp_certreq,
.force_encap = data->force_encap,
.fragmentation = data->fragmentation,
.childless = data->childless,
*/
bool (*send_certreq) (ike_cfg_t *this);
+ /**
+ * Should we send an OCSP status request in IKE_SA_INIT?
+ *
+ * @return OCSP status request sending policy
+ */
+ bool (*send_ocsp_certreq) (ike_cfg_t *this);
+
/**
* Enforce UDP encapsulation by faking NATD notifies?
*
uint16_t remote_port;
/** TRUE to not send any certificate requests */
bool no_certreq;
+ /** TRUE to not send OCSP status requests */
+ bool no_ocsp_certreq;
/** Enforce UDP encapsulation by faking NATD notify */
bool force_encap;
/** Use IKE fragmentation */
"CERT_NEVER_SEND",
);
+ENUM(ocsp_policy_names, OCSP_SEND_BOTH, OCSP_SEND_NEVER,
+ "OCSP_SEND_BOTH",
+ "OCSP_SEND_REPLY",
+ "OCSP_SEND_REQUEST",
+ "OCSP_SEND_NEVER",
+);
+
ENUM(unique_policy_names, UNIQUE_NEVER, UNIQUE_KEEP,
"UNIQUE_NEVER",
"UNIQUE_NO",
*/
cert_policy_t cert_policy;
+ /**
+ * should we send OCSP status request/response
+ */
+ ocsp_policy_t ocsp_policy;
+
/**
* uniqueness of an IKE_SA
*/
return this->cert_policy;
}
+METHOD(peer_cfg_t, get_ocsp_policy, ocsp_policy_t,
+ private_peer_cfg_t *this)
+{
+ return this->ocsp_policy;
+}
+
METHOD(peer_cfg_t, get_unique_policy, unique_policy_t,
private_peer_cfg_t *this)
{
return (
get_ike_version(this) == get_ike_version(other) &&
this->cert_policy == other->cert_policy &&
+ this->ocsp_policy == other->ocsp_policy &&
this->unique == other->unique &&
this->keyingtries == other->keyingtries &&
this->use_mobike == other->use_mobike &&
.create_child_cfg_enumerator = _create_child_cfg_enumerator,
.select_child_cfg = _select_child_cfg,
.get_cert_policy = _get_cert_policy,
+ .get_ocsp_policy = _get_ocsp_policy,
.get_unique_policy = _get_unique_policy,
.get_keyingtries = _get_keyingtries,
.get_rekey_time = _get_rekey_time,
.child_cfgs = linked_list_create(),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
.cert_policy = data->cert_policy,
+ .ocsp_policy = data->ocsp_policy,
.unique = data->unique,
.keyingtries = data->keyingtries,
.rekey_time = data->rekey_time,
#define PEER_CFG_H_
typedef enum cert_policy_t cert_policy_t;
+typedef enum ocsp_policy_t ocsp_policy_t;
typedef enum unique_policy_t unique_policy_t;
typedef struct peer_cfg_t peer_cfg_t;
typedef struct peer_cfg_create_t peer_cfg_create_t;
*/
extern enum_name_t *cert_policy_names;
+/**
+ * OCSP status request/response sending policy.
+ */
+enum ocsp_policy_t {
+ /** request OCSP status and reply to OCSP status requests */
+ OCSP_SEND_BOTH = 0,
+ /** send OCSP status upon OCSP status request */
+ OCSP_SEND_REPLY = 1,
+ /** send OCSP status request */
+ OCSP_SEND_REQUEST = 2,
+ /** never send OCSP status request or response */
+ OCSP_SEND_NEVER = 3,
+};
+
+/**
+ * enum strings for ocsp_policy_t
+ */
+extern enum_name_t *ocsp_policy_names;
+
/**
* Uniqueness of an IKE_SA, used to drop multiple connections with one peer.
*/
*/
cert_policy_t (*get_cert_policy) (peer_cfg_t *this);
+ /**
+ * Should an OCSP status request/response be sent for this connection?
+ *
+ * @return OCSP sending policy
+ */
+ ocsp_policy_t (*get_ocsp_policy) (peer_cfg_t *this);
+
/**
* How to handle uniqueness of IKE_SAs?
*
struct peer_cfg_create_t {
/** Whether to send a certificate payload */
cert_policy_t cert_policy;
+ /** Whether to send OCSP status request/response */
+ ocsp_policy_t ocsp_policy;
/** Uniqueness of an IKE_SA */
unique_policy_t unique;
/** How many keying tries should be done before giving up */
case ENC_CRL:
type = CERT_X509_CRL;
break;
+ case ENC_OCSP_CONTENT:
+ type = CERT_X509_OCSP_RESPONSE;
+ break;
default:
return NULL;
}
case CERT_X509_AC:
this->encoding = ENC_X509_ATTRIBUTE;
break;
+ case CERT_X509_OCSP_RESPONSE:
+ this->encoding = ENC_OCSP_CONTENT;
+ break;
default:
DBG1(DBG_ENC, "embedding %N certificate in payload failed",
certificate_type_names, cert->get_type(cert));
{
case ENC_X509_SIGNATURE:
return CERT_X509;
+ case ENC_OCSP_CONTENT:
+ return CERT_X509_OCSP_REQUEST;
default:
return CERT_ANY;
}
case CERT_X509:
this->encoding = ENC_X509_SIGNATURE;
break;
+ case CERT_X509_OCSP_REQUEST:
+ this->encoding = ENC_OCSP_CONTENT;
+ break;
default:
DBG1(DBG_ENC, "certificate type %N not supported in requests",
certificate_type_names, type);
identification_t *ppk_id;
bool ppk_required;
cert_policy_t send_cert;
+ ocsp_policy_t ocsp;
uint64_t dpd_delay;
uint64_t dpd_timeout;
fragmentation_t fragmentation;
DBG2(DBG_CFG, " remote_port = %u", data->remote_port);
DBG2(DBG_CFG, " send_certreq = %u", data->send_certreq);
DBG2(DBG_CFG, " send_cert = %N", cert_policy_names, data->send_cert);
+ DBG2(DBG_CFG, " ocsp = %N", ocsp_policy_names, data->ocsp);
DBG2(DBG_CFG, " ppk_id = %Y", data->ppk_id);
DBG2(DBG_CFG, " ppk_required = %u", data->ppk_required);
DBG2(DBG_CFG, " mobike = %u", data->mobike);
return FALSE;
}
+/**
+ * Parse an ocsp_policy_t
+ */
+CALLBACK(parse_ocsp, bool,
+ ocsp_policy_t *out, chunk_t v)
+{
+ enum_map_t map[] = {
+ { "both", OCSP_SEND_BOTH },
+ { "reply", OCSP_SEND_REPLY },
+ { "request", OCSP_SEND_REQUEST },
+ { "never", OCSP_SEND_NEVER },
+ };
+ int d;
+
+ if (parse_map(map, countof(map), &d, v))
+ {
+ *out = d;
+ return TRUE;
+ }
+ return FALSE;
+}
+
/**
* Parse a unique_policy_t
*/
{ "childless", parse_childless, &peer->childless },
{ "send_certreq", parse_bool, &peer->send_certreq },
{ "send_cert", parse_send_cert, &peer->send_cert },
+ { "ocsp", parse_ocsp, &peer->ocsp },
{ "keyingtries", parse_uint32, &peer->keyingtries },
{ "unique", parse_unique, &peer->unique },
{ "local_port", parse_uint32, &peer->local_port },
.send_certreq = TRUE,
.pull = TRUE,
.send_cert = CERT_SEND_IF_ASKED,
+ .ocsp = OCSP_SEND_REPLY,
.version = IKE_ANY,
.remote_port = IKEV2_UDP_PORT,
.fragmentation = FRAGMENTATION_YES,
.remote = peer.remote_addrs,
.remote_port = peer.remote_port,
.no_certreq = !peer.send_certreq,
+ .no_ocsp_certreq = peer.ocsp != OCSP_SEND_BOTH &&
+ peer.ocsp != OCSP_SEND_REQUEST,
.force_encap = peer.encap,
.fragmentation = peer.fragmentation,
.childless = peer.childless,
cfg = (peer_cfg_create_t){
.cert_policy = peer.send_cert,
+ .ocsp_policy = peer.ocsp,
.unique = peer.unique,
.keyingtries = peer.keyingtries,
.rekey_time = peer.rekey_time,
* All authentication rounds have been completed successfully
*/
COND_AUTHENTICATED = (1<<14),
+
+ /**
+ * An OCSP status request was received
+ */
+ COND_OCSP_REQUEST = (1<<15),
};
/**
}
}
+/**
+ * Build CERT payload with OCSP status for the given cert
+ */
+static cert_payload_t *build_cert_ocsp_payload(certificate_t *cert,
+ certificate_t *issuer)
+{
+ certificate_t *response;
+ cert_payload_t *payload;
+
+ response = lib->credmgr->get_ocsp(lib->credmgr, cert, issuer);
+ if (!response)
+ {
+ DBG2(DBG_IKE, "no OCSP status for certificate \"%Y\"",
+ cert->get_subject(cert));
+ return NULL;
+ }
+ payload = cert_payload_create_from_cert(PLV2_CERTIFICATE, response);
+ response->destroy(response);
+ return payload;
+}
+
+/**
+ * Add subject certificate and intermediate CA certificates OCSP status to message
+ */
+static void add_cert_ocsp(private_ike_cert_post_t *this, auth_cfg_t *auth,
+ message_t *message)
+{
+ auth_rule_t type;
+ cert_payload_t *payload;
+ certificate_t *cert, *issuer;
+ enumerator_t *enumerator;
+
+ cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+ if (!cert)
+ {
+ return;
+ }
+
+ enumerator = auth->create_enumerator(auth);
+ while (enumerator->enumerate(enumerator, &type, &issuer))
+ {
+ if (type == AUTH_RULE_CA_CERT || type == AUTH_RULE_IM_CERT)
+ {
+ payload = build_cert_ocsp_payload(cert, issuer);
+ if (payload)
+ {
+ DBG1(DBG_IKE, "sending OCSP status for certificate \"%Y\"",
+ cert->get_subject(cert));
+ message->add_payload(message, (payload_t*)payload);
+ }
+ if (type == AUTH_RULE_CA_CERT)
+ {
+ break;
+ }
+ cert = issuer;
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
/**
* add certificates to message
*/
}
break;
}
+
+ switch (peer_cfg->get_ocsp_policy(peer_cfg))
+ {
+ case OCSP_SEND_NEVER:
+ case OCSP_SEND_REQUEST:
+ break;
+ case OCSP_SEND_REPLY:
+ case OCSP_SEND_BOTH:
+ if (this->ike_sa->has_condition(this->ike_sa, COND_OCSP_REQUEST) &&
+ !this->ike_sa->has_condition(this->ike_sa,
+ COND_ONLINE_VALIDATION_SUSPENDED))
+ {
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+ add_cert_ocsp(this, auth, message);
+ }
+ break;
+ }
}
METHOD(task_t, build_i, status_t,
* for more details.
*/
+#include <time.h>
+
#include "ike_cert_pre.h"
#include <daemon.h>
certreq_payload_t *certreq, auth_cfg_t *auth)
{
enumerator_t *enumerator;
- u_int unknown = 0;
+ u_int unknown = 0, known = 0;
chunk_t keyid;
+ if (certreq->get_cert_type(certreq) == CERT_X509_OCSP_REQUEST)
+ {
+ this->ike_sa->set_condition(this->ike_sa, COND_OCSP_REQUEST, TRUE);
+
+ enumerator = certreq->create_keyid_enumerator(certreq);
+ while (enumerator->enumerate(enumerator, &keyid))
+ {
+ identification_t *id;
+ certificate_t *cert;
+
+ id = identification_create_from_encoding(ID_KEY_ID, keyid);
+ cert = lib->credmgr->get_cert(lib->credmgr,
+ CERT_X509, KEY_ANY, id, TRUE);
+ if (cert)
+ {
+ DBG1(DBG_IKE, "received OCSP cert request claiming trust "
+ "for \"%Y\"", cert->get_subject(cert));
+ cert->destroy(cert);
+ known++;
+ }
+ else
+ {
+ DBG2(DBG_IKE, "received OCSP cert request claiming trust for "
+ "unknown certificate with keyid %Y", id);
+ unknown++;
+ }
+ id->destroy(id);
+
+ }
+ if (unknown)
+ {
+ DBG1(DBG_IKE, "received OCSP cert request with %u unknown trusted "
+ "certificates", unknown);
+ }
+ else if (!known)
+ {
+ DBG1(DBG_IKE, "received empty OCSP cert request");
+ }
+ enumerator->destroy(enumerator);
+ return;
+ }
+
this->ike_sa->set_condition(this->ike_sa, COND_CERTREQ_SEEN, TRUE);
if (certreq->get_cert_type(certreq) != CERT_X509)
}
}
+/**
+ * Process an OCSP certificate payload
+ */
+static void process_ocsp(cert_payload_t *payload, auth_cfg_t *auth,
+ ike_cfg_t *ike_cfg)
+{
+ certificate_t *cert;
+
+ if (!ike_cfg->send_ocsp_certreq(ike_cfg))
+ {
+ DBG1(DBG_IKE, "received OCSP response, but we didn't request any, "
+ "ignore");
+ return;
+ }
+
+ cert = payload->get_cert(payload);
+ if (cert)
+ {
+ DBG1(DBG_IKE, "received OCSP response issued by \"%Y\"",
+ cert->get_issuer(cert));
+ auth->add(auth, AUTH_HELPER_REVOCATION_CERT, cert);
+ }
+}
+
/**
* Process an attribute certificate payload
*/
case ENC_CRL:
process_crl(cert_payload, auth);
break;
+ case ENC_OCSP_CONTENT:
+ process_ocsp(cert_payload, auth,
+ this->ike_sa->get_ike_cfg(this->ike_sa));
+ break;
case ENC_X509_ATTRIBUTE:
process_ac(cert_payload, auth);
break;
case ENC_SPKI:
case ENC_RAW_RSA_KEY:
case ENC_X509_HASH_AND_URL_BUNDLE:
- case ENC_OCSP_CONTENT:
default:
DBG1(DBG_ENC, "certificate encoding %N not supported",
cert_encoding_names, encoding);
enumerator->destroy(enumerator);
}
+/**
+ * add the keyid of a self-signed OCSP signer to the certificate request payload
+ */
+static void add_certreq_ocsp(certreq_payload_t *req, certificate_t *cert)
+{
+ public_key_t *public;
+ chunk_t keyid;
+ x509_t *x509 = (x509_t*)cert;
+
+ if (cert->get_type(cert) != CERT_X509 ||
+ !(x509->get_flags(x509) & X509_OCSP_SIGNER &&
+ x509->get_flags(x509) & X509_SELF_SIGNED))
+ {
+ /* no self-signed OCSP-signer cert, skip */
+ return;
+ }
+ public = cert->get_public_key(cert);
+ if (!public)
+ {
+ return;
+ }
+ if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &keyid))
+ {
+ req->add_keyid(req, keyid);
+ DBG1(DBG_IKE, "sending OCSP cert request with self-signed "
+ "OCSP-signer \"%Y\"", cert->get_subject(cert));
+ }
+ public->destroy(public);
+}
+
/**
* build certificate requests
*/
certreq_payload_t *req = NULL;
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
- if (!ike_cfg->send_certreq(ike_cfg))
+ if (ike_cfg->send_certreq(ike_cfg))
{
- return;
- }
+ /* check if we require a specific CA for that peer */
+ peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
+ if (peer_cfg)
+ {
+ enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, FALSE);
+ while (enumerator->enumerate(enumerator, &auth))
+ {
+ add_certreqs(&req, auth);
+ }
+ enumerator->destroy(enumerator);
+ }
- /* check if we require a specific CA for that peer */
- peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
- if (peer_cfg)
- {
- enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, FALSE);
- while (enumerator->enumerate(enumerator, &auth))
+ if (!req)
{
- add_certreqs(&req, auth);
+ /* otherwise add all trusted CA certificates */
+ enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
+ CERT_ANY, KEY_ANY, NULL, TRUE);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ add_certreq(&req, cert);
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ if (req)
+ {
+ message->add_payload(message, (payload_t*)req);
+
+ if (lib->settings->get_bool(lib->settings,
+ "%s.hash_and_url", FALSE, lib->ns))
+ {
+ message->add_notify(message, FALSE, HTTP_CERT_LOOKUP_SUPPORTED,
+ chunk_empty);
+ this->do_http_lookup = TRUE;
+ }
}
- enumerator->destroy(enumerator);
}
- if (!req)
+ if (ike_cfg->send_ocsp_certreq(ike_cfg))
{
- /* otherwise add all trusted CA certificates */
+ req = certreq_payload_create_type(CERT_X509_OCSP_REQUEST);
+
enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
CERT_ANY, KEY_ANY, NULL, TRUE);
while (enumerator->enumerate(enumerator, &cert))
{
- add_certreq(&req, cert);
+ add_certreq_ocsp(req, cert);
}
enumerator->destroy(enumerator);
- }
- if (req)
- {
message->add_payload(message, (payload_t*)req);
-
- if (lib->settings->get_bool(lib->settings,
- "%s.hash_and_url", FALSE, lib->ns))
- {
- message->add_notify(message, FALSE, HTTP_CERT_LOOKUP_SUPPORTED,
- chunk_empty);
- this->do_http_lookup = TRUE;
- }
}
}
bool (*validate_online)(cert_validator_t *this, certificate_t *subject,
certificate_t *issuer, u_int pathlen, bool anchor,
auth_cfg_t *auth);
+
+ /**
+ * Do OCSP checking for the given certificate.
+ *
+ * @param subject subject certificate to check
+ * @param issuer issuer of subject
+ * @return a valid OCSP response, NULL otherwise
+ */
+ certificate_t* (*ocsp)(cert_validator_t *this, certificate_t *subject,
+ certificate_t *issuer);
};
#endif /** CERT_VALIDATOR_H_ @}*/
return private;
}
+METHOD(credential_manager_t, get_ocsp, certificate_t*,
+ private_credential_manager_t *this, certificate_t *subject,
+ certificate_t *issuer)
+{
+ cert_validator_t *validator;
+ enumerator_t *enumerator;
+ certificate_t *response = NULL;
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->validators->create_enumerator(this->validators);
+ while (enumerator->enumerate(enumerator, &validator))
+ {
+ if (validator->ocsp)
+ {
+ response = validator->ocsp(validator, subject, issuer);
+ if (response)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+
+ return response;
+}
+
METHOD(credential_manager_t, flush_cache, void,
private_credential_manager_t *this, certificate_type_t type)
{
.get_cert = _get_cert,
.get_shared = _get_shared,
.get_private = _get_private,
+ .get_ocsp = _get_ocsp,
.create_trusted_enumerator = _create_trusted_enumerator,
.create_public_enumerator = _create_public_enumerator,
.flush_cache = _flush_cache,
certificate_t *(*get_cert)(credential_manager_t *this,
certificate_type_t cert, key_type_t key,
identification_t *id, bool trusted);
+
/**
* Get the best matching shared key for two IDs.
*
private_key_t* (*get_private)(credential_manager_t *this, key_type_t type,
identification_t *id, auth_cfg_t *auth);
+ /**
+ * Get an OCSP response for the given certificate.
+ *
+ * @param subject subject certificate to check
+ * @param issuer issuer of subject
+ * @return a valid OCSP response, NULL otherwise
+ */
+ certificate_t* (*get_ocsp)(credential_manager_t *this, certificate_t *subject,
+ certificate_t *issuer);
+
/**
* Create an enumerator over trusted certificates.
*
return response;
}
+/**
+ * Verify OCSP response signature
+ */
+static bool verify_ocsp_sig(certificate_t *subject, certificate_t *issuer,
+ bool cached)
+{
+ if (lib->credmgr->issued_by(lib->credmgr, subject, issuer, NULL))
+ {
+ if (!cached)
+ {
+ DBG1(DBG_CFG, " ocsp response correctly signed by \"%Y\"",
+ issuer->get_subject(issuer));
+ }
+ return TRUE;
+ }
+ DBG1(DBG_CFG, "OCSP response verification failed, invalid signature");
+ return FALSE;
+}
+
/**
* check the signature of an OCSP response
*/
}
}
found = TRUE;
- if (lib->credmgr->issued_by(lib->credmgr, subject, issuer, NULL))
+ verified = verify_ocsp_sig(subject, issuer, cached);
+ if (verified)
{
- if (!cached)
- {
- DBG1(DBG_CFG, " ocsp response correctly signed by \"%Y\"",
- issuer->get_subject(issuer));
- }
- verified = TRUE;
break;
}
- DBG1(DBG_CFG, "ocsp response verification failed, "
- "invalid signature");
}
enumerator->destroy(enumerator);
issuer->get_validity(issuer, NULL, NULL, NULL))
{
found = TRUE;
- if (lib->credmgr->issued_by(lib->credmgr, subject, issuer, NULL))
+ verified = verify_ocsp_sig(subject, issuer, cached);
+ if (verified)
{
- if (!cached)
- {
- DBG1(DBG_CFG, " ocsp response correctly signed by \"%Y\"",
- issuer->get_subject(issuer));
- }
- verified = TRUE;
break;
}
- DBG1(DBG_CFG, "ocsp response verification failed, "
- "invalid signature");
}
}
enumerator->destroy(enumerator);
* validate a x509 certificate using OCSP
*/
static cert_validation_t check_ocsp(x509_t *subject, x509_t *issuer,
- auth_cfg_t *auth, u_int timeout)
+ auth_cfg_t *auth, u_int timeout,
+ certificate_t **response)
{
enumerator_t *enumerator;
cert_validation_t valid = VALIDATION_SKIPPED;
{ /* successful OCSP check fulfills also CRL constraint */
auth->add(auth, AUTH_RULE_CRL_VALIDATION, VALIDATION_GOOD);
}
- DESTROY_IF(best);
+
+ if (response)
+ {
+ *response = best;
+ }
+ else
+ {
+ DESTROY_IF(best);
+ }
return valid;
}
if (enable_ocsp)
{
- switch (check_ocsp((x509_t*)subject, (x509_t*)issuer, auth, timeout))
+ switch (check_ocsp((x509_t*)subject, (x509_t*)issuer, auth, timeout,
+ NULL))
{
case VALIDATION_GOOD:
DBG1(DBG_CFG, "certificate status is good");
return TRUE;
}
+METHOD (cert_validator_t, ocsp, certificate_t *,
+ private_revocation_validator_t *this, certificate_t *subject,
+ certificate_t *issuer)
+{
+ certificate_t *response = NULL;
+ auth_cfg_t *auth;
+ bool enable_ocsp;
+ u_int timeout;
+
+ this->lock->lock(this->lock);
+ enable_ocsp = this->enable_ocsp;
+ timeout = this->timeout;
+ this->lock->unlock(this->lock);
+
+ if (enable_ocsp &&
+ subject->get_type(subject) == CERT_X509 &&
+ issuer->get_type(issuer) == CERT_X509)
+ {
+ DBG1(DBG_CFG, "checking OCSP status of \"%Y\"",
+ subject->get_subject(subject));
+
+ auth = auth_cfg_create();
+ switch (check_ocsp((x509_t*)subject, (x509_t*)issuer, auth, timeout,
+ &response))
+ {
+ case VALIDATION_GOOD:
+ case VALIDATION_ON_HOLD:
+ case VALIDATION_REVOKED:
+ break;
+ case VALIDATION_STALE:
+ case VALIDATION_SKIPPED:
+ case VALIDATION_FAILED:
+ DESTROY_IF(response);
+ response = NULL;
+ break;
+ }
+ auth->destroy(auth);
+ }
+ return response;
+}
+
METHOD(revocation_validator_t, reload, void,
private_revocation_validator_t *this)
{
INIT(this,
.public = {
.validator.validate_online = _validate_online,
+ .validator.ocsp = _ocsp,
.reload = _reload,
.destroy = _destroy,
},
certificate payloads altogether, _always_ causes certificate payloads to be
sent unconditionally whenever certificate authentication is used.
+connections.<conn>.ocsp = reply
+ Request and send OCSP status in certificate request or certificate payloads
+ (_never_, _reply, _request_ or _both_).
+
+ Send OCSP status requests in certificate request payloads and/or send OCSP
+ status response in certificate payloads when using certificate
+ authentication. With the default of _reply_ the daemon sends OCSP status
+ responses in certificate payloads if an OCSP status request has been
+ received in a certificate request, _never_ disables sending of OCSP status
+ requests and responses altogether, _request_ causes OCSP status requests in
+ certificate request payloads to be sent whenever certificate authentication
+ is used, _both_ combines _reply_ and _request_.
+
connections.<conn>.ppk_id =
String identifying the Postquantum Preshared Key (PPK) to be used.