mirror of
https://github.com/strongswan/strongswan.git
synced 2025-08-20 00:01:59 -04:00
Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
0fc4770cff | ||
|
0269d780de | ||
|
4a809acc9f |
@ -20,7 +20,7 @@
|
||||
# initialize & set some vars
|
||||
# ============================
|
||||
|
||||
AC_INIT([strongSwan],[5.9.14dr1])
|
||||
AC_INIT([strongSwan],[5.9.14dr2])
|
||||
AM_INIT_AUTOMAKE(m4_esyscmd([
|
||||
echo tar-ustar
|
||||
echo subdir-objects
|
||||
|
@ -96,6 +96,11 @@ struct private_ike_cfg_t {
|
||||
*/
|
||||
bool certreq;
|
||||
|
||||
/**
|
||||
* should we send an OCSP status request?
|
||||
*/
|
||||
bool ocsp_certreq;
|
||||
|
||||
/**
|
||||
* enforce UDP encapsulation
|
||||
*/
|
||||
@ -134,6 +139,12 @@ METHOD(ike_cfg_t, send_certreq, bool,
|
||||
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)
|
||||
{
|
||||
@ -388,6 +399,7 @@ METHOD(ike_cfg_t, equals, bool,
|
||||
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 &&
|
||||
@ -587,6 +599,7 @@ ike_cfg_t *ike_cfg_create(ike_cfg_create_t *data)
|
||||
.public = {
|
||||
.get_version = _get_version,
|
||||
.send_certreq = _send_certreq,
|
||||
.send_ocsp_certreq = _send_ocsp_certreq,
|
||||
.force_encap = _force_encap_,
|
||||
.fragmentation = _fragmentation,
|
||||
.childless = _childless,
|
||||
@ -611,6 +624,7 @@ ike_cfg_t *ike_cfg_create(ike_cfg_create_t *data)
|
||||
.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,
|
||||
|
@ -210,6 +210,13 @@ struct ike_cfg_t {
|
||||
*/
|
||||
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?
|
||||
*
|
||||
@ -288,6 +295,8 @@ struct ike_cfg_create_t {
|
||||
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 */
|
||||
|
@ -32,6 +32,13 @@ ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
|
||||
"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",
|
||||
@ -81,6 +88,11 @@ struct private_peer_cfg_t {
|
||||
*/
|
||||
cert_policy_t cert_policy;
|
||||
|
||||
/**
|
||||
* should we send OCSP status request/response
|
||||
*/
|
||||
ocsp_policy_t ocsp_policy;
|
||||
|
||||
/**
|
||||
* uniqueness of an IKE_SA
|
||||
*/
|
||||
@ -495,6 +507,12 @@ METHOD(peer_cfg_t, get_cert_policy, cert_policy_t,
|
||||
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)
|
||||
{
|
||||
@ -741,6 +759,7 @@ METHOD(peer_cfg_t, equals, bool,
|
||||
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 &&
|
||||
@ -828,6 +847,7 @@ peer_cfg_t *peer_cfg_create(char *name, ike_cfg_t *ike_cfg,
|
||||
.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,
|
||||
@ -861,6 +881,7 @@ peer_cfg_t *peer_cfg_create(char *name, ike_cfg_t *ike_cfg,
|
||||
.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,
|
||||
|
@ -25,6 +25,7 @@
|
||||
#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;
|
||||
@ -61,6 +62,25 @@ enum cert_policy_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.
|
||||
*/
|
||||
@ -213,6 +233,13 @@ struct peer_cfg_t {
|
||||
*/
|
||||
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?
|
||||
*
|
||||
@ -397,6 +424,8 @@ struct peer_cfg_t {
|
||||
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 */
|
||||
|
@ -230,6 +230,9 @@ METHOD(cert_payload_t, get_cert, certificate_t*,
|
||||
case ENC_CRL:
|
||||
type = CERT_X509_CRL;
|
||||
break;
|
||||
case ENC_OCSP_CONTENT:
|
||||
type = CERT_X509_OCSP_RESPONSE;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@ -339,6 +342,9 @@ cert_payload_t *cert_payload_create_from_cert(payload_type_t type,
|
||||
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));
|
||||
|
@ -244,6 +244,8 @@ METHOD(certreq_payload_t, get_cert_type, certificate_type_t,
|
||||
{
|
||||
case ENC_X509_SIGNATURE:
|
||||
return CERT_X509;
|
||||
case ENC_OCSP_CONTENT:
|
||||
return CERT_X509_OCSP_REQUEST;
|
||||
default:
|
||||
return CERT_ANY;
|
||||
}
|
||||
@ -302,6 +304,9 @@ certreq_payload_t *certreq_payload_create_type(certificate_type_t type)
|
||||
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);
|
||||
|
@ -314,6 +314,7 @@ typedef struct {
|
||||
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;
|
||||
@ -425,6 +426,7 @@ static void log_peer_data(peer_data_t *data)
|
||||
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);
|
||||
@ -1678,6 +1680,28 @@ CALLBACK(parse_send_cert, bool,
|
||||
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
|
||||
*/
|
||||
@ -1879,6 +1903,7 @@ CALLBACK(peer_kv, bool,
|
||||
{ "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 },
|
||||
@ -2498,6 +2523,7 @@ CALLBACK(config_sn, bool,
|
||||
.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,
|
||||
@ -2646,6 +2672,8 @@ CALLBACK(config_sn, bool,
|
||||
.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,
|
||||
@ -2655,6 +2683,7 @@ CALLBACK(config_sn, bool,
|
||||
|
||||
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,
|
||||
|
@ -250,6 +250,11 @@ enum ike_condition_t {
|
||||
* All authentication rounds have been completed successfully
|
||||
*/
|
||||
COND_AUTHENTICATED = (1<<14),
|
||||
|
||||
/**
|
||||
* An OCSP status request was received
|
||||
*/
|
||||
COND_OCSP_REQUEST = (1<<15),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -215,6 +215,66 @@ static void add_attribute_certs(private_ike_cert_post_t *this,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@ -250,6 +310,23 @@ static void build_certs(private_ike_cert_post_t *this, message_t *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,
|
||||
|
@ -15,6 +15,8 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "ike_cert_pre.h"
|
||||
|
||||
#include <daemon.h>
|
||||
@ -59,9 +61,51 @@ static void process_certreq(private_ike_cert_pre_t *this,
|
||||
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)
|
||||
@ -255,6 +299,30 @@ static void process_crl(cert_payload_t *payload, auth_cfg_t *auth)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@ -318,6 +386,10 @@ static void process_certs(private_ike_cert_pre_t *this, message_t *message)
|
||||
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;
|
||||
@ -329,7 +401,6 @@ static void process_certs(private_ike_cert_pre_t *this, message_t *message)
|
||||
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);
|
||||
@ -403,6 +474,36 @@ static void add_certreqs(certreq_payload_t **req, auth_cfg_t *auth)
|
||||
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
|
||||
*/
|
||||
@ -416,46 +517,59 @@ static void build_certreqs(private_ike_cert_pre_t *this, message_t *message)
|
||||
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))
|
||||
/* check if we require a specific CA for that peer */
|
||||
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
if (peer_cfg)
|
||||
{
|
||||
add_certreqs(&req, auth);
|
||||
enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, FALSE);
|
||||
while (enumerator->enumerate(enumerator, &auth))
|
||||
{
|
||||
add_certreqs(&req, auth);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
if (!req)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,6 +90,16 @@ struct cert_validator_t {
|
||||
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_ @}*/
|
||||
|
@ -1352,6 +1352,33 @@ METHOD(credential_manager_t, get_private, private_key_t*,
|
||||
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)
|
||||
{
|
||||
@ -1427,6 +1454,7 @@ credential_manager_t *credential_manager_create()
|
||||
.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,
|
||||
|
@ -149,6 +149,7 @@ struct credential_manager_t {
|
||||
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.
|
||||
*
|
||||
@ -176,6 +177,16 @@ struct credential_manager_t {
|
||||
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.
|
||||
*
|
||||
|
@ -141,6 +141,25 @@ static certificate_t *fetch_ocsp(char *url, certificate_t *subject,
|
||||
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
|
||||
*/
|
||||
@ -182,18 +201,11 @@ static bool verify_ocsp(ocsp_response_t *response, certificate_t *ca,
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
@ -212,18 +224,11 @@ static bool verify_ocsp(ocsp_response_t *response, certificate_t *ca,
|
||||
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);
|
||||
@ -323,7 +328,8 @@ static certificate_t *get_better_ocsp(certificate_t *cand, certificate_t *best,
|
||||
* 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;
|
||||
@ -409,7 +415,15 @@ static cert_validation_t check_ocsp(x509_t *subject, x509_t *issuer,
|
||||
{ /* 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;
|
||||
}
|
||||
|
||||
@ -866,7 +880,8 @@ METHOD(cert_validator_t, validate_online, bool,
|
||||
|
||||
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");
|
||||
@ -927,6 +942,47 @@ METHOD(cert_validator_t, validate_online, bool,
|
||||
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)
|
||||
{
|
||||
@ -974,6 +1030,7 @@ revocation_validator_t *revocation_validator_create()
|
||||
INIT(this,
|
||||
.public = {
|
||||
.validator.validate_online = _validate_online,
|
||||
.validator.ocsp = _ocsp,
|
||||
.reload = _reload,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
|
@ -205,6 +205,19 @@ connections.<conn>.send_cert = ifasked
|
||||
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.
|
||||
|
||||
|
@ -675,7 +675,7 @@ cp ${TEST_CERT} ${CA_DIR}/certs/${SERIAL}.pem
|
||||
|
||||
# Put a copy into the following ikev2 scenarios
|
||||
for t in ocsp-timeouts-good ocsp-disabled ocsp-no-signer-cert ocsp-root-cert \
|
||||
ocsp-untrusted-cert
|
||||
ocsp-untrusted-cert ocsp-rfc4806-signer ocsp-rfc4806-both
|
||||
do
|
||||
TEST="${TEST_DIR}/ikev2/${t}"
|
||||
mkdir -p ${TEST}/hosts/carol/${SWANCTL_DIR}/rsa
|
||||
@ -707,12 +707,15 @@ pki --self --type rsa --in ${TEST_KEY} --flag ocspSigning \
|
||||
--dn "C=CH, O=${PROJECT}, OU=${OU}, CN=${CN}" \
|
||||
--outform pem > ${TEST_CERT}
|
||||
|
||||
# Copy self-signed OCSP Signing certificate to ikev2/ocsp-local-cert scenario
|
||||
TEST="${TEST_DIR}/ikev2/ocsp-local-cert"
|
||||
mkdir -p ${TEST}/hosts/carol/${SWANCTL_DIR}/x509ocsp
|
||||
mkdir -p ${TEST}/hosts/moon/${SWANCTL_DIR}/x509ocsp
|
||||
cp ${TEST_CERT} ${TEST}/hosts/carol/${SWANCTL_DIR}/x509ocsp
|
||||
cp ${TEST_CERT} ${TEST}/hosts/moon/${SWANCTL_DIR}/x509ocsp
|
||||
# Put a copy into the following ikev2 scenarios
|
||||
for t in ocsp-local-cert ocsp-rfc4806-local
|
||||
do
|
||||
TEST="${TEST_DIR}/ikev2/${t}"
|
||||
mkdir -p ${TEST}/hosts/carol/${SWANCTL_DIR}/x509ocsp
|
||||
mkdir -p ${TEST}/hosts/moon/${SWANCTL_DIR}/x509ocsp
|
||||
cp ${TEST_CERT} ${TEST}/hosts/carol/${SWANCTL_DIR}/x509ocsp
|
||||
cp ${TEST_CERT} ${TEST}/hosts/moon/${SWANCTL_DIR}/x509ocsp
|
||||
done
|
||||
|
||||
# Generate mars virtual server certificate
|
||||
TEST="${TEST_DIR}/ha/both-active"
|
||||
|
@ -24,14 +24,14 @@ fi
|
||||
: ${TESTDIR=/srv/strongswan-testing}
|
||||
|
||||
# Kernel configuration
|
||||
: ${KERNELVERSION=6.3.9}
|
||||
: ${KERNELVERSION=6.7.9}
|
||||
: ${KERNEL=linux-$KERNELVERSION}
|
||||
: ${KERNELTARBALL=$KERNEL.tar.xz}
|
||||
: ${KERNELCONFIG=$DIR/../config/kernel/config-6.3}
|
||||
: ${KERNELPATCH=ha-6.3-abicompat.patch.bz2}
|
||||
: ${KERNELCONFIG=$DIR/../config/kernel/config-6.7}
|
||||
: ${KERNELPATCH=ha-6.5-abicompat-raw-sockets.patch.bz2}
|
||||
|
||||
# strongSwan version used in tests
|
||||
: ${SWANVERSION=5.9.14dr1}
|
||||
: ${SWANVERSION=5.9.14dr2}
|
||||
|
||||
# Build directory where the guest kernel and images will be built
|
||||
: ${BUILDDIR=$TESTDIR/build}
|
||||
|
15
testing/tests/ikev2/ocsp-rfc4806-both/description.txt
Normal file
15
testing/tests/ikev2/ocsp-rfc4806-both/description.txt
Normal file
@ -0,0 +1,15 @@
|
||||
By setting <b>revocation = strict</b> in swanctl.conf, a <b>strict</b> CRL policy
|
||||
is enforced on both roadwarrior <b>carol</b> and gateway <b>moon</b>.
|
||||
<p/>
|
||||
Based on RFC 4806, both <b>carol</b> and <b>moon</b> send an OCSP request via an
|
||||
IKEv2 CERTREQ payload to their peer which in turn requests online status information
|
||||
on its own certificate from the OCSP server <b>winnetou</b> on behalf of the other
|
||||
peer. The OCSP server <b>winnetou</b> possesses an OCSP signer certificate containing
|
||||
an <b>OCSPSigning</b> Extended Key Usage (EKU) flag issued by the strongSwan CA.
|
||||
<p/>
|
||||
<b>carol</b>'s certificate includes an <b>OCSP URI</b> in an authority information
|
||||
access extension pointing to <b>winnetou</b>. Therefore no special authorities
|
||||
section information is needed in carol's swanctl.conf.
|
||||
<p/>
|
||||
<b>carol</b> can successfully initiate an IPsec connection to <b>moon</b> since
|
||||
the status of both certificates is <b>good</b>.
|
17
testing/tests/ikev2/ocsp-rfc4806-both/evaltest.dat
Normal file
17
testing/tests/ikev2/ocsp-rfc4806-both/evaltest.dat
Normal file
@ -0,0 +1,17 @@
|
||||
moon::swanctl --list-authorities 2> /dev/null::ocsp_uris: http://ocsp.strongswan.org:8880::YES
|
||||
moon:: cat /var/log/daemon.log::received empty OCSP cert request::YES
|
||||
moon:: cat /var/log/daemon.log::received OCSP response issued by::YES
|
||||
moon:: cat /var/log/daemon.log::requesting ocsp status::YES
|
||||
moon:: cat /var/log/daemon.log::ocsp response correctly signed by::YES
|
||||
moon:: cat /var/log/daemon.log::ocsp response is valid::2
|
||||
moon:: cat /var/log/daemon.log::certificate status is good::YES
|
||||
moon:: cat /var/log/daemon.log::sending OCSP status for certificate::YES
|
||||
carol::swanctl --list-authorities 2> /dev/null::ocsp_uris: http://ocsp.strongswan.org:8880::NO
|
||||
carol::cat /var/log/daemon.log::received empty OCSP cert request::YES
|
||||
carol::cat /var/log/daemon.log::requesting ocsp status::YES
|
||||
carol::cat /var/log/daemon.log::sending OCSP status for certificate::YES
|
||||
carol::cat /var/log/daemon.log::received OCSP response issued by::YES
|
||||
carol::cat /var/log/daemon.log::ocsp response is valid::2
|
||||
carol::cat /var/log/daemon.log::certificate status is good::YES
|
||||
moon::swanctl --list-sas --raw 2> /dev/null::rw.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-port=4500 local-id=moon.strongswan.org remote-host=192.168.0.100 remote-port=4500 remote-id=carol@strongswan.org.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*net.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[10.1.0.0/16] remote-ts=\[192.168.0.100/32]::YES
|
||||
carol::swanctl --list-sas --raw 2> /dev/null::home.*version=2 state=ESTABLISHED local-host=192.168.0.100 local-port=4500 local-id=carol@strongswan.org remote-host=192.168.0.1 remote-port=4500 remote-id=moon.strongswan.org initiator=yes.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*home.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[192.168.0.100/32] remote-ts=\[10.1.0.0/16]::YES
|
@ -0,0 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 md5 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
connections {
|
||||
|
||||
home {
|
||||
local_addrs = 192.168.0.100
|
||||
remote_addrs = 192.168.0.1
|
||||
|
||||
local {
|
||||
auth = pubkey
|
||||
certs = carolCert.pem
|
||||
id = carol@strongswan.org
|
||||
}
|
||||
remote {
|
||||
auth = pubkey
|
||||
id = moon.strongswan.org
|
||||
revocation = strict
|
||||
}
|
||||
children {
|
||||
home {
|
||||
remote_ts = 10.1.0.0/16
|
||||
|
||||
esp_proposals = aes128gcm128-x25519
|
||||
}
|
||||
}
|
||||
version = 2
|
||||
proposals = aes128-sha256-x25519
|
||||
ocsp = both
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
34
testing/tests/ikev2/ocsp-rfc4806-both/hosts/moon/etc/swanctl/swanctl.conf
Executable file
34
testing/tests/ikev2/ocsp-rfc4806-both/hosts/moon/etc/swanctl/swanctl.conf
Executable file
@ -0,0 +1,34 @@
|
||||
connections {
|
||||
|
||||
rw {
|
||||
local_addrs = 192.168.0.1
|
||||
|
||||
local {
|
||||
auth = pubkey
|
||||
certs = moonCert.pem
|
||||
id = moon.strongswan.org
|
||||
}
|
||||
remote {
|
||||
auth = pubkey
|
||||
revocation = strict
|
||||
}
|
||||
children {
|
||||
net {
|
||||
local_ts = 10.1.0.0/16
|
||||
|
||||
esp_proposals = aes128gcm128-x25519
|
||||
}
|
||||
}
|
||||
version = 2
|
||||
proposals = aes128-sha256-x25519
|
||||
ocsp = both
|
||||
}
|
||||
}
|
||||
|
||||
authorities {
|
||||
|
||||
strongswan {
|
||||
cacert = strongswanCert.pem
|
||||
ocsp_uris = http://ocsp.strongswan.org:8880
|
||||
}
|
||||
}
|
3
testing/tests/ikev2/ocsp-rfc4806-both/posttest.dat
Normal file
3
testing/tests/ikev2/ocsp-rfc4806-both/posttest.dat
Normal file
@ -0,0 +1,3 @@
|
||||
carol::swanctl --terminate --ike home
|
||||
carol::systemctl stop strongswan
|
||||
moon::systemctl stop strongswan
|
5
testing/tests/ikev2/ocsp-rfc4806-both/pretest.dat
Normal file
5
testing/tests/ikev2/ocsp-rfc4806-both/pretest.dat
Normal file
@ -0,0 +1,5 @@
|
||||
moon::systemctl start strongswan
|
||||
carol::systemctl start strongswan
|
||||
moon::expect-connection rw
|
||||
carol::expect-connection home
|
||||
carol::swanctl --initiate --child home
|
25
testing/tests/ikev2/ocsp-rfc4806-both/test.conf
Normal file
25
testing/tests/ikev2/ocsp-rfc4806-both/test.conf
Normal file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This configuration file provides information on the
|
||||
# guest instances used for this test
|
||||
|
||||
# All guest instances that are required for this test
|
||||
#
|
||||
VIRTHOSTS="moon carol winnetou"
|
||||
|
||||
# Corresponding block diagram
|
||||
#
|
||||
DIAGRAM="m-c-w.png"
|
||||
|
||||
# Guest instances on which tcpdump is to be started
|
||||
#
|
||||
TCPDUMPHOSTS=""
|
||||
|
||||
# Guest instances on which IPsec is started
|
||||
# Used for IPsec logging purposes
|
||||
#
|
||||
IPSECHOSTS="moon carol"
|
||||
|
||||
# charon controlled by swanctl
|
||||
#
|
||||
SWANCTL=1
|
15
testing/tests/ikev2/ocsp-rfc4806-local/description.txt
Normal file
15
testing/tests/ikev2/ocsp-rfc4806-local/description.txt
Normal file
@ -0,0 +1,15 @@
|
||||
By setting <b>revocation = strict</b> in swanctl.conf, a <b>strict</b> CRL policy
|
||||
is enforced on both roadwarrior <b>carol</b> and gateway <b>moon</b>.
|
||||
<p/>
|
||||
Based on RFC 4806, <b>carol</b> sends an OCSP request via an IKEv2 CERTREQ payload to
|
||||
gateway <b>moon</b> which in turn requests online status information on its own
|
||||
certificate from the OCSP server <b>winnetou</b> on behalf of <b>carol</b>.
|
||||
The OCSP server <b>winnetou</b> possesses a <b>self-signed</b> OCSP signer certificate
|
||||
that must be imported locally by the peers into the <b>/etc/swanctl/x509ocsp/</b>
|
||||
directory.
|
||||
<p/>
|
||||
An <b>authorities</b> section in <b>moon</b>'s swanctl.conf defines an <b>OCSP URI</b>
|
||||
pointing to the OCSP server <b>winnetou</b>.
|
||||
<p/>
|
||||
<b>carol</b> can successfully initiate an IPsec connection to <b>moon</b> since
|
||||
the status of both certificates is <b>good</b>.
|
14
testing/tests/ikev2/ocsp-rfc4806-local/evaltest.dat
Normal file
14
testing/tests/ikev2/ocsp-rfc4806-local/evaltest.dat
Normal file
@ -0,0 +1,14 @@
|
||||
moon::swanctl --list-authorities 2> /dev/null::ocsp_uris: http://ocsp.strongswan.org:8880::YES
|
||||
moon:: cat /var/log/daemon.log::received OCSP cert request claiming trust for
|
||||
moon:: cat /var/log/daemon.log::requesting ocsp status from::2
|
||||
moon:: cat /var/log/daemon.log::ocsp response correctly signed by.*OCSP Self-Signed Authority::2
|
||||
moon:: cat /var/log/daemon.log::ocsp response is valid::2
|
||||
moon:: cat /var/log/daemon.log::certificate status is good::YES
|
||||
moon:: cat /var/log/daemon.log::sending OCSP status for certificate::YES
|
||||
carol::swanctl --list-authorities 2> /dev/null::ocsp_uris: http://ocsp.strongswan.org:8880::NO
|
||||
carol::cat /var/log/daemon.log::sending OCSP cert request with self-signed OCSP-signer
|
||||
carol::cat /var/log/daemon.log::received OCSP response issued by::YES
|
||||
carol::cat /var/log/daemon.log::ocsp response is valid::YES
|
||||
carol::cat /var/log/daemon.log::certificate status is good::YES
|
||||
moon::swanctl --list-sas --raw 2> /dev/null::rw.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-port=4500 local-id=moon.strongswan.org remote-host=192.168.0.100 remote-port=4500 remote-id=carol@strongswan.org.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*net.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[10.1.0.0/16] remote-ts=\[192.168.0.100/32]::YES
|
||||
carol::swanctl --list-sas --raw 2> /dev/null::home.*version=2 state=ESTABLISHED local-host=192.168.0.100 local-port=4500 local-id=carol@strongswan.org remote-host=192.168.0.1 remote-port=4500 remote-id=moon.strongswan.org initiator=yes.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*home.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[192.168.0.100/32] remote-ts=\[10.1.0.0/16]::YES
|
@ -0,0 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 md5 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
connections {
|
||||
|
||||
home {
|
||||
local_addrs = 192.168.0.100
|
||||
remote_addrs = 192.168.0.1
|
||||
|
||||
local {
|
||||
auth = pubkey
|
||||
certs = carolCert.pem
|
||||
id = carol@strongswan.org
|
||||
}
|
||||
remote {
|
||||
auth = pubkey
|
||||
id = moon.strongswan.org
|
||||
revocation = strict
|
||||
}
|
||||
children {
|
||||
home {
|
||||
remote_ts = 10.1.0.0/16
|
||||
|
||||
esp_proposals = aes128gcm128-x25519
|
||||
}
|
||||
}
|
||||
version = 2
|
||||
proposals = aes128-sha256-x25519
|
||||
ocsp = request
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
34
testing/tests/ikev2/ocsp-rfc4806-local/hosts/moon/etc/swanctl/swanctl.conf
Executable file
34
testing/tests/ikev2/ocsp-rfc4806-local/hosts/moon/etc/swanctl/swanctl.conf
Executable file
@ -0,0 +1,34 @@
|
||||
connections {
|
||||
|
||||
rw {
|
||||
local_addrs = 192.168.0.1
|
||||
|
||||
local {
|
||||
auth = pubkey
|
||||
certs = moonCert.pem
|
||||
id = moon.strongswan.org
|
||||
}
|
||||
remote {
|
||||
auth = pubkey
|
||||
revocation = strict
|
||||
}
|
||||
children {
|
||||
net {
|
||||
local_ts = 10.1.0.0/16
|
||||
|
||||
esp_proposals = aes128gcm128-x25519
|
||||
}
|
||||
}
|
||||
version = 2
|
||||
proposals = aes128-sha256-x25519
|
||||
ocsp = reply
|
||||
}
|
||||
}
|
||||
|
||||
authorities {
|
||||
|
||||
strongswan {
|
||||
cacert = strongswanCert.pem
|
||||
ocsp_uris = http://ocsp.strongswan.org:8880
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd /etc/ca
|
||||
|
||||
echo "Content-type: application/ocsp-response"
|
||||
echo ""
|
||||
|
||||
cat | pki --ocsp --respond --cacert strongswanCert.pem --index index.txt \
|
||||
--cert ocspCert-self.pem --key ocspKey-self.pem --lifetime 5 --debug 0
|
4
testing/tests/ikev2/ocsp-rfc4806-local/posttest.dat
Normal file
4
testing/tests/ikev2/ocsp-rfc4806-local/posttest.dat
Normal file
@ -0,0 +1,4 @@
|
||||
carol::systemctl stop strongswan
|
||||
moon::systemctl stop strongswan
|
||||
carol::rm /etc/swanctl/x509ocsp/*
|
||||
moon::rm /etc/swanctl/x509ocsp/*
|
5
testing/tests/ikev2/ocsp-rfc4806-local/pretest.dat
Normal file
5
testing/tests/ikev2/ocsp-rfc4806-local/pretest.dat
Normal file
@ -0,0 +1,5 @@
|
||||
moon::systemctl start strongswan
|
||||
carol::systemctl start strongswan
|
||||
moon::expect-connection rw
|
||||
carol::expect-connection home
|
||||
carol::swanctl --initiate --child home
|
25
testing/tests/ikev2/ocsp-rfc4806-local/test.conf
Normal file
25
testing/tests/ikev2/ocsp-rfc4806-local/test.conf
Normal file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This configuration file provides information on the
|
||||
# guest instances used for this test
|
||||
|
||||
# All guest instances that are required for this test
|
||||
#
|
||||
VIRTHOSTS="moon carol winnetou"
|
||||
|
||||
# Corresponding block diagram
|
||||
#
|
||||
DIAGRAM="m-c-w.png"
|
||||
|
||||
# Guest instances on which tcpdump is to be started
|
||||
#
|
||||
TCPDUMPHOSTS=""
|
||||
|
||||
# Guest instances on which IPsec is started
|
||||
# Used for IPsec logging purposes
|
||||
#
|
||||
IPSECHOSTS="moon carol"
|
||||
|
||||
# charon controlled by swanctl
|
||||
#
|
||||
SWANCTL=1
|
16
testing/tests/ikev2/ocsp-rfc4806-signer/description.txt
Normal file
16
testing/tests/ikev2/ocsp-rfc4806-signer/description.txt
Normal file
@ -0,0 +1,16 @@
|
||||
By setting <b>revocation = strict</b> in swanctl.conf, a <b>strict</b> CRL policy
|
||||
is enforced on both roadwarrior <b>carol</b> and gateway <b>moon</b>.
|
||||
<p/>
|
||||
Based on RFC 4806, <b>carol</b> sends an OCSP request via an IKEv2 CERTREQ payload to
|
||||
gateway <b>moon</b> which in turn requests online status information on its own
|
||||
certificate from the OCSP server <b>winnetou</b> on behalf of <b>carol</b>.
|
||||
The OCSP server <b>winnetou</b> possesses an OCSP signer certificate containing an
|
||||
<b>OCSPSigning</b> Extended Key Usage (EKU) flag issued by the strongSwan CA.
|
||||
<p/>
|
||||
Even though <b>carol</b>'s certificate includes an <b>OCSP URI</b> in an authority
|
||||
information access extension pointing to <b>winnetou</b>, gateway <b>moon</b> still
|
||||
needs a special authorities section in swanctl.conf in order to be able to request
|
||||
an OCSP response for its own certificate since that is lacking an <b>OCSP URI</b>.
|
||||
<p/>
|
||||
<b>carol</b> can successfully initiate an IPsec connection to <b>moon</b> since
|
||||
the status of both certificates is <b>good</b>.
|
13
testing/tests/ikev2/ocsp-rfc4806-signer/evaltest.dat
Normal file
13
testing/tests/ikev2/ocsp-rfc4806-signer/evaltest.dat
Normal file
@ -0,0 +1,13 @@
|
||||
moon::swanctl --list-authorities 2> /dev/null::ocsp_uris: http://ocsp.strongswan.org:8880::YES
|
||||
moon:: cat /var/log/daemon.log::received empty OCSP cert request::YES
|
||||
moon:: cat /var/log/daemon.log::requesting ocsp status::2
|
||||
moon:: cat /var/log/daemon.log::ocsp response correctly signed by::2
|
||||
moon:: cat /var/log/daemon.log::ocsp response is valid::2
|
||||
moon:: cat /var/log/daemon.log::certificate status is good::YES
|
||||
moon:: cat /var/log/daemon.log::sending OCSP status for certificate::YES
|
||||
carol::swanctl --list-authorities 2> /dev/null::ocsp_uris: http://ocsp.strongswan.org:8880::NO
|
||||
carol::cat /var/log/daemon.log::received OCSP response issued by::YES
|
||||
carol::cat /var/log/daemon.log::ocsp response is valid::YES
|
||||
carol::cat /var/log/daemon.log::certificate status is good::YES
|
||||
moon::swanctl --list-sas --raw 2> /dev/null::rw.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-port=4500 local-id=moon.strongswan.org remote-host=192.168.0.100 remote-port=4500 remote-id=carol@strongswan.org.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*net.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[10.1.0.0/16] remote-ts=\[192.168.0.100/32]::YES
|
||||
carol::swanctl --list-sas --raw 2> /dev/null::home.*version=2 state=ESTABLISHED local-host=192.168.0.100 local-port=4500 local-id=carol@strongswan.org remote-host=192.168.0.1 remote-port=4500 remote-id=moon.strongswan.org initiator=yes.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*home.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[192.168.0.100/32] remote-ts=\[10.1.0.0/16]::YES
|
@ -0,0 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 md5 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
connections {
|
||||
|
||||
home {
|
||||
local_addrs = 192.168.0.100
|
||||
remote_addrs = 192.168.0.1
|
||||
|
||||
local {
|
||||
auth = pubkey
|
||||
certs = carolCert.pem
|
||||
id = carol@strongswan.org
|
||||
}
|
||||
remote {
|
||||
auth = pubkey
|
||||
id = moon.strongswan.org
|
||||
revocation = strict
|
||||
}
|
||||
children {
|
||||
home {
|
||||
remote_ts = 10.1.0.0/16
|
||||
|
||||
esp_proposals = aes128gcm128-x25519
|
||||
}
|
||||
}
|
||||
version = 2
|
||||
proposals = aes128-sha256-x25519
|
||||
ocsp = request
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default
|
||||
}
|
34
testing/tests/ikev2/ocsp-rfc4806-signer/hosts/moon/etc/swanctl/swanctl.conf
Executable file
34
testing/tests/ikev2/ocsp-rfc4806-signer/hosts/moon/etc/swanctl/swanctl.conf
Executable file
@ -0,0 +1,34 @@
|
||||
connections {
|
||||
|
||||
rw {
|
||||
local_addrs = 192.168.0.1
|
||||
|
||||
local {
|
||||
auth = pubkey
|
||||
certs = moonCert.pem
|
||||
id = moon.strongswan.org
|
||||
}
|
||||
remote {
|
||||
auth = pubkey
|
||||
revocation = strict
|
||||
}
|
||||
children {
|
||||
net {
|
||||
local_ts = 10.1.0.0/16
|
||||
|
||||
esp_proposals = aes128gcm128-x25519
|
||||
}
|
||||
}
|
||||
version = 2
|
||||
proposals = aes128-sha256-x25519
|
||||
ocsp = reply
|
||||
}
|
||||
}
|
||||
|
||||
authorities {
|
||||
|
||||
strongswan {
|
||||
cacert = strongswanCert.pem
|
||||
ocsp_uris = http://ocsp.strongswan.org:8880
|
||||
}
|
||||
}
|
3
testing/tests/ikev2/ocsp-rfc4806-signer/posttest.dat
Normal file
3
testing/tests/ikev2/ocsp-rfc4806-signer/posttest.dat
Normal file
@ -0,0 +1,3 @@
|
||||
carol::swanctl --terminate --ike home
|
||||
carol::systemctl stop strongswan
|
||||
moon::systemctl stop strongswan
|
5
testing/tests/ikev2/ocsp-rfc4806-signer/pretest.dat
Normal file
5
testing/tests/ikev2/ocsp-rfc4806-signer/pretest.dat
Normal file
@ -0,0 +1,5 @@
|
||||
moon::systemctl start strongswan
|
||||
carol::systemctl start strongswan
|
||||
moon::expect-connection rw
|
||||
carol::expect-connection home
|
||||
carol::swanctl --initiate --child home
|
25
testing/tests/ikev2/ocsp-rfc4806-signer/test.conf
Normal file
25
testing/tests/ikev2/ocsp-rfc4806-signer/test.conf
Normal file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This configuration file provides information on the
|
||||
# guest instances used for this test
|
||||
|
||||
# All guest instances that are required for this test
|
||||
#
|
||||
VIRTHOSTS="moon carol winnetou"
|
||||
|
||||
# Corresponding block diagram
|
||||
#
|
||||
DIAGRAM="m-c-w.png"
|
||||
|
||||
# Guest instances on which tcpdump is to be started
|
||||
#
|
||||
TCPDUMPHOSTS=""
|
||||
|
||||
# Guest instances on which IPsec is started
|
||||
# Used for IPsec logging purposes
|
||||
#
|
||||
IPSECHOSTS="moon carol"
|
||||
|
||||
# charon controlled by swanctl
|
||||
#
|
||||
SWANCTL=1
|
Loading…
x
Reference in New Issue
Block a user