Merge branch 'mbb-reauth-online-revocation'
With these changes initiators of make-before-break reauthentications
suspend online revocation checks until after the new IKE_SA and all
CHILD_SAs are established. See f1cbacc5d1 for details why that's
necessary.
This commit is contained in:
@@ -11,6 +11,15 @@ strongswan-5.4.0
|
|||||||
constraints against IKEv2 authentication in rightauth, which allows the use
|
constraints against IKEv2 authentication in rightauth, which allows the use
|
||||||
of different signature schemes for trustchain verification and authentication.
|
of different signature schemes for trustchain verification and authentication.
|
||||||
|
|
||||||
|
- The initiator of an IKEv2 make-before-break reauthentication now suspends
|
||||||
|
online certificate revocation checks (OCSP, CRLs) until the new IKE_SA and all
|
||||||
|
CHILD_SAs are established. This is required if the checks are done over the
|
||||||
|
CHILD_SA established with the new IKE_SA. This is not possible until the
|
||||||
|
initiator installs this SA and that only happens after the authentication is
|
||||||
|
completed successfully. So we suspend the checks during the reauthentication
|
||||||
|
and do them afterwards, if they fail the IKE_SA is closed. This change has no
|
||||||
|
effect on the behavior during the authentication of the initial IKE_SA.
|
||||||
|
|
||||||
- For the vici plugin a Vici:Session Perl CPAN module has been added to allow
|
- For the vici plugin a Vici:Session Perl CPAN module has been added to allow
|
||||||
Perl applications to control and/or monitor the IKE daemon using the VICI
|
Perl applications to control and/or monitor the IKE daemon using the VICI
|
||||||
interface, similar to the existing Python egg or Ruby gem.
|
interface, similar to the existing Python egg or Ruby gem.
|
||||||
|
|||||||
@@ -111,7 +111,8 @@ sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \
|
|||||||
sa/ikev2/tasks/ike_reauth_complete.c sa/ikev2/tasks/ike_reauth_complete.h \
|
sa/ikev2/tasks/ike_reauth_complete.c sa/ikev2/tasks/ike_reauth_complete.h \
|
||||||
sa/ikev2/tasks/ike_redirect.c sa/ikev2/tasks/ike_redirect.h \
|
sa/ikev2/tasks/ike_redirect.c sa/ikev2/tasks/ike_redirect.h \
|
||||||
sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \
|
sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \
|
||||||
sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h
|
sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h \
|
||||||
|
sa/ikev2/tasks/ike_verify_peer_cert.c sa/ikev2/tasks/ike_verify_peer_cert.h
|
||||||
|
|
||||||
libcharon_la_SOURCES += \
|
libcharon_la_SOURCES += \
|
||||||
sa/ikev1/keymat_v1.c sa/ikev1/keymat_v1.h \
|
sa/ikev1/keymat_v1.c sa/ikev1/keymat_v1.h \
|
||||||
|
|||||||
@@ -111,7 +111,8 @@ sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \
|
|||||||
sa/ikev2/tasks/ike_reauth_complete.c sa/ikev2/tasks/ike_reauth_complete.h \
|
sa/ikev2/tasks/ike_reauth_complete.c sa/ikev2/tasks/ike_reauth_complete.h \
|
||||||
sa/ikev2/tasks/ike_redirect.c sa/ikev2/tasks/ike_redirect.h \
|
sa/ikev2/tasks/ike_redirect.c sa/ikev2/tasks/ike_redirect.h \
|
||||||
sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \
|
sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \
|
||||||
sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h
|
sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h \
|
||||||
|
sa/ikev2/tasks/ike_verify_peer_cert.c sa/ikev2/tasks/ike_verify_peer_cert.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if USE_IKEV1
|
if USE_IKEV1
|
||||||
|
|||||||
+117
-3
@@ -58,6 +58,7 @@
|
|||||||
#include <sa/ikev2/tasks/ike_auth_lifetime.h>
|
#include <sa/ikev2/tasks/ike_auth_lifetime.h>
|
||||||
#include <sa/ikev2/tasks/ike_reauth_complete.h>
|
#include <sa/ikev2/tasks/ike_reauth_complete.h>
|
||||||
#include <sa/ikev2/tasks/ike_redirect.h>
|
#include <sa/ikev2/tasks/ike_redirect.h>
|
||||||
|
#include <credentials/sets/auth_cfg_wrapper.h>
|
||||||
|
|
||||||
#ifdef ME
|
#ifdef ME
|
||||||
#include <sa/ikev2/tasks/ike_me.h>
|
#include <sa/ikev2/tasks/ike_me.h>
|
||||||
@@ -482,6 +483,113 @@ static void flush_auth_cfgs(private_ike_sa_t *this)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(ike_sa_t, verify_peer_certificate, bool,
|
||||||
|
private_ike_sa_t *this)
|
||||||
|
{
|
||||||
|
enumerator_t *e1, *e2, *certs;
|
||||||
|
auth_cfg_t *cfg, *cfg_done;
|
||||||
|
certificate_t *peer, *cert;
|
||||||
|
public_key_t *key;
|
||||||
|
auth_cfg_t *auth;
|
||||||
|
auth_cfg_wrapper_t *wrapper;
|
||||||
|
time_t not_before, not_after;
|
||||||
|
bool valid = TRUE, found;
|
||||||
|
|
||||||
|
if (this->state != IKE_ESTABLISHED)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "unable to verify peer certificate in state %N",
|
||||||
|
ike_sa_state_names, this->state);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->flush_auth_cfg &&
|
||||||
|
lib->settings->get_bool(lib->settings,
|
||||||
|
"%s.flush_auth_cfg", FALSE, lib->ns))
|
||||||
|
{ /* we can do this check only once if auth configs are flushed */
|
||||||
|
DBG1(DBG_IKE, "unable to verify peer certificate as authentication "
|
||||||
|
"information has been flushed");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
this->public.set_condition(&this->public, COND_ONLINE_VALIDATION_SUSPENDED,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
e1 = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, FALSE);
|
||||||
|
e2 = array_create_enumerator(this->other_auths);
|
||||||
|
while (e1->enumerate(e1, &cfg))
|
||||||
|
{
|
||||||
|
if (!e2->enumerate(e2, &cfg_done))
|
||||||
|
{ /* this should not happen as the authentication should never have
|
||||||
|
* succeeded */
|
||||||
|
valid = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((uintptr_t)cfg_done->get(cfg_done,
|
||||||
|
AUTH_RULE_AUTH_CLASS) != AUTH_CLASS_PUBKEY)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
peer = cfg_done->get(cfg_done, AUTH_RULE_SUBJECT_CERT);
|
||||||
|
if (!peer)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "no subject certificate found, skipping certificate "
|
||||||
|
"verification");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!peer->get_validity(peer, NULL, ¬_before, ¬_after))
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "peer certificate invalid (valid from %T to %T)",
|
||||||
|
¬_before, FALSE, ¬_after, FALSE);
|
||||||
|
valid = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
key = peer->get_public_key(peer);
|
||||||
|
if (!key)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "unable to retrieve public key, skipping certificate "
|
||||||
|
"verification");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DBG1(DBG_IKE, "verifying peer certificate");
|
||||||
|
/* serve received certificates */
|
||||||
|
wrapper = auth_cfg_wrapper_create(cfg_done);
|
||||||
|
lib->credmgr->add_local_set(lib->credmgr, &wrapper->set, FALSE);
|
||||||
|
certs = lib->credmgr->create_trusted_enumerator(lib->credmgr,
|
||||||
|
key->get_type(key), peer->get_subject(peer), TRUE);
|
||||||
|
key->destroy(key);
|
||||||
|
|
||||||
|
found = FALSE;
|
||||||
|
while (certs->enumerate(certs, &cert, &auth))
|
||||||
|
{
|
||||||
|
if (peer->equals(peer, cert))
|
||||||
|
{
|
||||||
|
cfg_done->add(cfg_done, AUTH_RULE_CERT_VALIDATION_SUSPENDED,
|
||||||
|
FALSE);
|
||||||
|
cfg_done->merge(cfg_done, auth, FALSE);
|
||||||
|
valid = cfg_done->complies(cfg_done, cfg, TRUE);
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
certs->destroy(certs);
|
||||||
|
lib->credmgr->remove_local_set(lib->credmgr, &wrapper->set);
|
||||||
|
wrapper->destroy(wrapper);
|
||||||
|
if (!found || !valid)
|
||||||
|
{
|
||||||
|
valid = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e1->destroy(e1);
|
||||||
|
e2->destroy(e2);
|
||||||
|
|
||||||
|
if (this->flush_auth_cfg)
|
||||||
|
{
|
||||||
|
this->flush_auth_cfg = FALSE;
|
||||||
|
flush_auth_cfgs(this);
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(ike_sa_t, get_proposal, proposal_t*,
|
METHOD(ike_sa_t, get_proposal, proposal_t*,
|
||||||
private_ike_sa_t *this)
|
private_ike_sa_t *this)
|
||||||
{
|
{
|
||||||
@@ -1441,9 +1549,14 @@ METHOD(ike_sa_t, process_message, status_t,
|
|||||||
status = this->task_manager->process_message(this->task_manager, message);
|
status = this->task_manager->process_message(this->task_manager, message);
|
||||||
if (this->flush_auth_cfg && this->state == IKE_ESTABLISHED)
|
if (this->flush_auth_cfg && this->state == IKE_ESTABLISHED)
|
||||||
{
|
{
|
||||||
/* authentication completed */
|
/* authentication completed but if the online validation is suspended we
|
||||||
this->flush_auth_cfg = FALSE;
|
* need the auth cfgs until we did the delayed verification, we flush
|
||||||
flush_auth_cfgs(this);
|
* them afterwards */
|
||||||
|
if (!has_condition(this, COND_ONLINE_VALIDATION_SUSPENDED))
|
||||||
|
{
|
||||||
|
this->flush_auth_cfg = FALSE;
|
||||||
|
flush_auth_cfgs(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -2750,6 +2863,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
|
|||||||
.set_peer_cfg = _set_peer_cfg,
|
.set_peer_cfg = _set_peer_cfg,
|
||||||
.get_auth_cfg = _get_auth_cfg,
|
.get_auth_cfg = _get_auth_cfg,
|
||||||
.create_auth_cfg_enumerator = _create_auth_cfg_enumerator,
|
.create_auth_cfg_enumerator = _create_auth_cfg_enumerator,
|
||||||
|
.verify_peer_certificate = _verify_peer_certificate,
|
||||||
.add_auth_cfg = _add_auth_cfg,
|
.add_auth_cfg = _add_auth_cfg,
|
||||||
.get_proposal = _get_proposal,
|
.get_proposal = _get_proposal,
|
||||||
.set_proposal = _set_proposal,
|
.set_proposal = _set_proposal,
|
||||||
|
|||||||
@@ -217,6 +217,11 @@ enum ike_condition_t {
|
|||||||
* This IKE_SA has been redirected
|
* This IKE_SA has been redirected
|
||||||
*/
|
*/
|
||||||
COND_REDIRECTED = (1<<11),
|
COND_REDIRECTED = (1<<11),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Online certificate revocation checking is suspended for this IKE_SA
|
||||||
|
*/
|
||||||
|
COND_ONLINE_VALIDATION_SUSPENDED = (1<<12),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -521,6 +526,14 @@ struct ike_sa_t {
|
|||||||
*/
|
*/
|
||||||
enumerator_t* (*create_auth_cfg_enumerator)(ike_sa_t *this, bool local);
|
enumerator_t* (*create_auth_cfg_enumerator)(ike_sa_t *this, bool local);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the trustchains (validity, revocation) in completed public key
|
||||||
|
* auth rounds.
|
||||||
|
*
|
||||||
|
* @return TRUE if certificates were valid, FALSE otherwise
|
||||||
|
*/
|
||||||
|
bool (*verify_peer_certificate)(ike_sa_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the selected proposal of this IKE_SA.
|
* Get the selected proposal of this IKE_SA.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ METHOD(authenticator_t, process, status_t,
|
|||||||
sig = sig_payload->get_hash(sig_payload);
|
sig = sig_payload->get_hash(sig_payload);
|
||||||
auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
|
auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
|
||||||
enumerator = lib->credmgr->create_public_enumerator(lib->credmgr, this->type,
|
enumerator = lib->credmgr->create_public_enumerator(lib->credmgr, this->type,
|
||||||
id, auth);
|
id, auth, TRUE);
|
||||||
while (enumerator->enumerate(enumerator, &public, ¤t_auth))
|
while (enumerator->enumerate(enumerator, &public, ¤t_auth))
|
||||||
{
|
{
|
||||||
if (public->verify(public, scheme, hash, sig))
|
if (public->verify(public, scheme, hash, sig))
|
||||||
|
|||||||
@@ -365,6 +365,7 @@ METHOD(authenticator_t, process, status_t,
|
|||||||
status_t status = NOT_FOUND;
|
status_t status = NOT_FOUND;
|
||||||
keymat_v2_t *keymat;
|
keymat_v2_t *keymat;
|
||||||
const char *reason = "unsupported";
|
const char *reason = "unsupported";
|
||||||
|
bool online;
|
||||||
|
|
||||||
auth_payload = (auth_payload_t*)message->get_payload(message, PLV2_AUTH);
|
auth_payload = (auth_payload_t*)message->get_payload(message, PLV2_AUTH);
|
||||||
if (!auth_payload)
|
if (!auth_payload)
|
||||||
@@ -408,8 +409,10 @@ METHOD(authenticator_t, process, status_t,
|
|||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
|
auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
|
||||||
|
online = !this->ike_sa->has_condition(this->ike_sa,
|
||||||
|
COND_ONLINE_VALIDATION_SUSPENDED);
|
||||||
enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
|
enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
|
||||||
key_type, id, auth);
|
key_type, id, auth, online);
|
||||||
while (enumerator->enumerate(enumerator, &public, ¤t_auth))
|
while (enumerator->enumerate(enumerator, &public, ¤t_auth))
|
||||||
{
|
{
|
||||||
if (public->verify(public, scheme, octets, auth_data))
|
if (public->verify(public, scheme, octets, auth_data))
|
||||||
@@ -421,6 +424,10 @@ METHOD(authenticator_t, process, status_t,
|
|||||||
auth->merge(auth, current_auth, FALSE);
|
auth->merge(auth, current_auth, FALSE);
|
||||||
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
|
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
|
||||||
auth->add(auth, AUTH_RULE_IKE_SIGNATURE_SCHEME, (uintptr_t)scheme);
|
auth->add(auth, AUTH_RULE_IKE_SIGNATURE_SCHEME, (uintptr_t)scheme);
|
||||||
|
if (!online)
|
||||||
|
{
|
||||||
|
auth->add(auth, AUTH_RULE_CERT_VALIDATION_SUSPENDED, TRUE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <sa/ikev2/tasks/ike_config.h>
|
#include <sa/ikev2/tasks/ike_config.h>
|
||||||
#include <sa/ikev2/tasks/ike_dpd.h>
|
#include <sa/ikev2/tasks/ike_dpd.h>
|
||||||
#include <sa/ikev2/tasks/ike_vendor.h>
|
#include <sa/ikev2/tasks/ike_vendor.h>
|
||||||
|
#include <sa/ikev2/tasks/ike_verify_peer_cert.h>
|
||||||
#include <sa/ikev2/tasks/child_create.h>
|
#include <sa/ikev2/tasks/child_create.h>
|
||||||
#include <sa/ikev2/tasks/child_rekey.h>
|
#include <sa/ikev2/tasks/child_rekey.h>
|
||||||
#include <sa/ikev2/tasks/child_delete.h>
|
#include <sa/ikev2/tasks/child_delete.h>
|
||||||
@@ -527,6 +528,11 @@ METHOD(task_manager_t, initiate, status_t,
|
|||||||
exchange = INFORMATIONAL;
|
exchange = INFORMATIONAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (activate_task(this, TASK_IKE_VERIFY_PEER_CERT))
|
||||||
|
{
|
||||||
|
exchange = INFORMATIONAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case IKE_REKEYING:
|
case IKE_REKEYING:
|
||||||
if (activate_task(this, TASK_IKE_DELETE))
|
if (activate_task(this, TASK_IKE_DELETE))
|
||||||
{
|
{
|
||||||
@@ -624,7 +630,7 @@ METHOD(task_manager_t, initiate, status_t,
|
|||||||
if (this->initiating.type == EXCHANGE_TYPE_UNDEFINED)
|
if (this->initiating.type == EXCHANGE_TYPE_UNDEFINED)
|
||||||
{
|
{
|
||||||
message->destroy(message);
|
message->destroy(message);
|
||||||
return SUCCESS;
|
return initiate(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!generate_message(this, message, &this->initiating.packets))
|
if (!generate_message(this, message, &this->initiating.packets))
|
||||||
@@ -1650,8 +1656,12 @@ static void trigger_mbb_reauth(private_task_manager_t *this)
|
|||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
/* suspend online revocation checking until the SA is established */
|
||||||
|
new->set_condition(new, COND_ONLINE_VALIDATION_SUSPENDED, TRUE);
|
||||||
|
|
||||||
if (new->initiate(new, NULL, 0, NULL, NULL) != DESTROY_ME)
|
if (new->initiate(new, NULL, 0, NULL, NULL) != DESTROY_ME)
|
||||||
{
|
{
|
||||||
|
new->queue_task(new, (task_t*)ike_verify_peer_cert_create(new));
|
||||||
new->queue_task(new, (task_t*)ike_reauth_complete_create(new,
|
new->queue_task(new, (task_t*)ike_reauth_complete_create(new,
|
||||||
this->ike_sa->get_id(this->ike_sa)));
|
this->ike_sa->get_id(this->ike_sa)));
|
||||||
charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
|
charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Tobias Brunner
|
||||||
|
* Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ike_verify_peer_cert.h"
|
||||||
|
|
||||||
|
#include <daemon.h>
|
||||||
|
#include <sa/ikev2/tasks/ike_delete.h>
|
||||||
|
|
||||||
|
typedef struct private_ike_verify_peer_cert_t private_ike_verify_peer_cert_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private members
|
||||||
|
*/
|
||||||
|
struct private_ike_verify_peer_cert_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public methods and task_t interface.
|
||||||
|
*/
|
||||||
|
ike_verify_peer_cert_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigned IKE_SA.
|
||||||
|
*/
|
||||||
|
ike_sa_t *ike_sa;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child ike_delete task, if necessary
|
||||||
|
*/
|
||||||
|
ike_delete_t *ike_delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
METHOD(task_t, build_i, status_t,
|
||||||
|
private_ike_verify_peer_cert_t *this, message_t *message)
|
||||||
|
{
|
||||||
|
if (!this->ike_sa->verify_peer_certificate(this->ike_sa))
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "peer certificate verification failed, deleting SA");
|
||||||
|
this->ike_delete = ike_delete_create(this->ike_sa, TRUE);
|
||||||
|
return this->ike_delete->task.build(&this->ike_delete->task, message);
|
||||||
|
}
|
||||||
|
DBG1(DBG_IKE, "peer certificate successfully verified");
|
||||||
|
message->set_exchange_type(message, EXCHANGE_TYPE_UNDEFINED);
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(task_t, process_i, status_t,
|
||||||
|
private_ike_verify_peer_cert_t *this, message_t *message)
|
||||||
|
{
|
||||||
|
if (this->ike_delete)
|
||||||
|
{
|
||||||
|
this->ike_delete->task.process(&this->ike_delete->task, message);
|
||||||
|
/* try to reestablish the IKE_SA and all children */
|
||||||
|
this->ike_sa->reestablish(this->ike_sa);
|
||||||
|
}
|
||||||
|
return DESTROY_ME;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(task_t, get_type, task_type_t,
|
||||||
|
private_ike_verify_peer_cert_t *this)
|
||||||
|
{
|
||||||
|
return TASK_IKE_VERIFY_PEER_CERT;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(task_t, migrate, void,
|
||||||
|
private_ike_verify_peer_cert_t *this, ike_sa_t *ike_sa)
|
||||||
|
{
|
||||||
|
if (this->ike_delete)
|
||||||
|
{
|
||||||
|
this->ike_delete->task.migrate(&this->ike_delete->task, ike_sa);
|
||||||
|
}
|
||||||
|
this->ike_sa = ike_sa;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(task_t, destroy, void,
|
||||||
|
private_ike_verify_peer_cert_t *this)
|
||||||
|
{
|
||||||
|
if (this->ike_delete)
|
||||||
|
{
|
||||||
|
this->ike_delete->task.destroy(&this->ike_delete->task);
|
||||||
|
}
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
ike_verify_peer_cert_t *ike_verify_peer_cert_create(ike_sa_t *ike_sa)
|
||||||
|
{
|
||||||
|
private_ike_verify_peer_cert_t *this;
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.task = {
|
||||||
|
.get_type = _get_type,
|
||||||
|
.migrate = _migrate,
|
||||||
|
.build = _build_i,
|
||||||
|
.process = _process_i,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.ike_sa = ike_sa,
|
||||||
|
);
|
||||||
|
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Tobias Brunner
|
||||||
|
* Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup ike_verify_peer_cert ike_verify_peer_cert
|
||||||
|
* @{ @ingroup tasks_v2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IKE_VERIFY_PEER_CERT_H_
|
||||||
|
#define IKE_VERIFY_PEER_CERT_H_
|
||||||
|
|
||||||
|
typedef struct ike_verify_peer_cert_t ike_verify_peer_cert_t;
|
||||||
|
|
||||||
|
#include <library.h>
|
||||||
|
#include <sa/ike_sa.h>
|
||||||
|
#include <sa/task.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task of type ike_verify_peer_cert, verifies a peer's certificate.
|
||||||
|
*
|
||||||
|
* This task (re-)verifies the peer's certificate explicitly including online
|
||||||
|
* OCSP and CRL checks.
|
||||||
|
*/
|
||||||
|
struct ike_verify_peer_cert_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements the task_t interface
|
||||||
|
*/
|
||||||
|
task_t task;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ike_verify_peer_cert task.
|
||||||
|
*
|
||||||
|
* This task is initiator only.
|
||||||
|
*
|
||||||
|
* @param ike_sa IKE_SA this task works for
|
||||||
|
* @return ike_verify_peer_cert task to handle by the task_manager
|
||||||
|
*/
|
||||||
|
ike_verify_peer_cert_t *ike_verify_peer_cert_create(ike_sa_t *ike_sa);
|
||||||
|
|
||||||
|
#endif /** IKE_VERIFY_PEER_CERT_H_ @}*/
|
||||||
@@ -29,6 +29,7 @@ ENUM(task_type_names, TASK_IKE_INIT, TASK_ISAKMP_CERT_POST,
|
|||||||
"IKE_REAUTH",
|
"IKE_REAUTH",
|
||||||
"IKE_REAUTH_COMPLETE",
|
"IKE_REAUTH_COMPLETE",
|
||||||
"IKE_REDIRECT",
|
"IKE_REDIRECT",
|
||||||
|
"IKE_VERIFY_PEER_CERT",
|
||||||
"IKE_DELETE",
|
"IKE_DELETE",
|
||||||
"IKE_DPD",
|
"IKE_DPD",
|
||||||
"IKE_VENDOR",
|
"IKE_VENDOR",
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ enum task_type_t {
|
|||||||
TASK_IKE_REAUTH_COMPLETE,
|
TASK_IKE_REAUTH_COMPLETE,
|
||||||
/** redirect an active IKE_SA */
|
/** redirect an active IKE_SA */
|
||||||
TASK_IKE_REDIRECT,
|
TASK_IKE_REDIRECT,
|
||||||
|
/** verify a peer's certificate */
|
||||||
|
TASK_IKE_VERIFY_PEER_CERT,
|
||||||
/** delete an IKE_SA */
|
/** delete an IKE_SA */
|
||||||
TASK_IKE_DELETE,
|
TASK_IKE_DELETE,
|
||||||
/** liveness check */
|
/** liveness check */
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_AC_CERT,
|
|||||||
"RULE_SUBJECT_CERT",
|
"RULE_SUBJECT_CERT",
|
||||||
"RULE_CRL_VALIDATION",
|
"RULE_CRL_VALIDATION",
|
||||||
"RULE_OCSP_VALIDATION",
|
"RULE_OCSP_VALIDATION",
|
||||||
|
"RULE_CERT_VALIDATION_SUSPENDED",
|
||||||
"RULE_GROUP",
|
"RULE_GROUP",
|
||||||
"RULE_RSA_STRENGTH",
|
"RULE_RSA_STRENGTH",
|
||||||
"RULE_ECDSA_STRENGTH",
|
"RULE_ECDSA_STRENGTH",
|
||||||
@@ -80,6 +81,7 @@ static inline bool is_multi_value_rule(auth_rule_t type)
|
|||||||
case AUTH_RULE_AAA_IDENTITY:
|
case AUTH_RULE_AAA_IDENTITY:
|
||||||
case AUTH_RULE_XAUTH_IDENTITY:
|
case AUTH_RULE_XAUTH_IDENTITY:
|
||||||
case AUTH_RULE_XAUTH_BACKEND:
|
case AUTH_RULE_XAUTH_BACKEND:
|
||||||
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
||||||
case AUTH_HELPER_SUBJECT_CERT:
|
case AUTH_HELPER_SUBJECT_CERT:
|
||||||
case AUTH_HELPER_SUBJECT_HASH_URL:
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
||||||
case AUTH_RULE_MAX:
|
case AUTH_RULE_MAX:
|
||||||
@@ -214,6 +216,7 @@ static void init_entry(entry_t *this, auth_rule_t type, va_list args)
|
|||||||
case AUTH_RULE_BLISS_STRENGTH:
|
case AUTH_RULE_BLISS_STRENGTH:
|
||||||
case AUTH_RULE_SIGNATURE_SCHEME:
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
||||||
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
||||||
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
||||||
/* integer type */
|
/* integer type */
|
||||||
this->value = (void*)(uintptr_t)va_arg(args, u_int);
|
this->value = (void*)(uintptr_t)va_arg(args, u_int);
|
||||||
break;
|
break;
|
||||||
@@ -264,6 +267,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2)
|
|||||||
case AUTH_RULE_BLISS_STRENGTH:
|
case AUTH_RULE_BLISS_STRENGTH:
|
||||||
case AUTH_RULE_SIGNATURE_SCHEME:
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
||||||
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
||||||
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
||||||
{
|
{
|
||||||
return e1->value == e2->value;
|
return e1->value == e2->value;
|
||||||
}
|
}
|
||||||
@@ -356,6 +360,7 @@ static void destroy_entry_value(entry_t *entry)
|
|||||||
case AUTH_RULE_BLISS_STRENGTH:
|
case AUTH_RULE_BLISS_STRENGTH:
|
||||||
case AUTH_RULE_SIGNATURE_SCHEME:
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
||||||
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
||||||
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
||||||
case AUTH_RULE_MAX:
|
case AUTH_RULE_MAX:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -389,6 +394,7 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator,
|
|||||||
case AUTH_RULE_BLISS_STRENGTH:
|
case AUTH_RULE_BLISS_STRENGTH:
|
||||||
case AUTH_RULE_SIGNATURE_SCHEME:
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
||||||
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
||||||
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
||||||
/* integer type */
|
/* integer type */
|
||||||
entry->value = (void*)(uintptr_t)va_arg(args, u_int);
|
entry->value = (void*)(uintptr_t)va_arg(args, u_int);
|
||||||
break;
|
break;
|
||||||
@@ -471,6 +477,7 @@ METHOD(auth_cfg_t, get, void*,
|
|||||||
case AUTH_RULE_OCSP_VALIDATION:
|
case AUTH_RULE_OCSP_VALIDATION:
|
||||||
return (void*)VALIDATION_FAILED;
|
return (void*)VALIDATION_FAILED;
|
||||||
case AUTH_RULE_IDENTITY_LOOSE:
|
case AUTH_RULE_IDENTITY_LOOSE:
|
||||||
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
||||||
return (void*)FALSE;
|
return (void*)FALSE;
|
||||||
case AUTH_RULE_IDENTITY:
|
case AUTH_RULE_IDENTITY:
|
||||||
case AUTH_RULE_EAP_IDENTITY:
|
case AUTH_RULE_EAP_IDENTITY:
|
||||||
@@ -757,6 +764,11 @@ METHOD(auth_cfg_t, complies, bool,
|
|||||||
{
|
{
|
||||||
uintptr_t validated;
|
uintptr_t validated;
|
||||||
|
|
||||||
|
if (get(this, AUTH_RULE_CERT_VALIDATION_SUSPENDED))
|
||||||
|
{ /* skip validation, may happen later */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
e2 = create_enumerator(this);
|
e2 = create_enumerator(this);
|
||||||
while (e2->enumerate(e2, &t2, &validated))
|
while (e2->enumerate(e2, &t2, &validated))
|
||||||
{
|
{
|
||||||
@@ -934,6 +946,8 @@ METHOD(auth_cfg_t, complies, bool,
|
|||||||
/* just an indication when verifying AUTH_RULE_IDENTITY */
|
/* just an indication when verifying AUTH_RULE_IDENTITY */
|
||||||
case AUTH_RULE_XAUTH_BACKEND:
|
case AUTH_RULE_XAUTH_BACKEND:
|
||||||
/* not enforced, just a hint for local authentication */
|
/* not enforced, just a hint for local authentication */
|
||||||
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
||||||
|
/* not a constraint */
|
||||||
case AUTH_HELPER_IM_CERT:
|
case AUTH_HELPER_IM_CERT:
|
||||||
case AUTH_HELPER_SUBJECT_CERT:
|
case AUTH_HELPER_SUBJECT_CERT:
|
||||||
case AUTH_HELPER_IM_HASH_URL:
|
case AUTH_HELPER_IM_HASH_URL:
|
||||||
@@ -1086,6 +1100,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy
|
|||||||
case AUTH_RULE_BLISS_STRENGTH:
|
case AUTH_RULE_BLISS_STRENGTH:
|
||||||
case AUTH_RULE_SIGNATURE_SCHEME:
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
||||||
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
||||||
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
||||||
{
|
{
|
||||||
add(this, type, (uintptr_t)value);
|
add(this, type, (uintptr_t)value);
|
||||||
break;
|
break;
|
||||||
@@ -1257,6 +1272,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*,
|
|||||||
case AUTH_RULE_BLISS_STRENGTH:
|
case AUTH_RULE_BLISS_STRENGTH:
|
||||||
case AUTH_RULE_SIGNATURE_SCHEME:
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
||||||
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
||||||
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
||||||
clone->add(clone, type, (uintptr_t)value);
|
clone->add(clone, type, (uintptr_t)value);
|
||||||
break;
|
break;
|
||||||
case AUTH_RULE_MAX:
|
case AUTH_RULE_MAX:
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ enum auth_rule_t {
|
|||||||
AUTH_RULE_CRL_VALIDATION,
|
AUTH_RULE_CRL_VALIDATION,
|
||||||
/** result of a OCSP validation, cert_validation_t */
|
/** result of a OCSP validation, cert_validation_t */
|
||||||
AUTH_RULE_OCSP_VALIDATION,
|
AUTH_RULE_OCSP_VALIDATION,
|
||||||
|
/** CRL/OCSP validation is disabled, bool */
|
||||||
|
AUTH_RULE_CERT_VALIDATION_SUSPENDED,
|
||||||
/** subject is member of a group, identification_t*
|
/** subject is member of a group, identification_t*
|
||||||
* The group membership constraint is fulfilled if the subject is member of
|
* The group membership constraint is fulfilled if the subject is member of
|
||||||
* one group defined in the constraints. */
|
* one group defined in the constraints. */
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2015 Tobias Brunner
|
||||||
* Copyright (C) 2007 Martin Willi
|
* Copyright (C) 2007 Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
@@ -917,6 +918,8 @@ METHOD(enumerator_t, trusted_destroy, void,
|
|||||||
DESTROY_IF(this->auth);
|
DESTROY_IF(this->auth);
|
||||||
DESTROY_IF(this->candidates);
|
DESTROY_IF(this->candidates);
|
||||||
this->failed->destroy_offset(this->failed, offsetof(certificate_t, destroy));
|
this->failed->destroy_offset(this->failed, offsetof(certificate_t, destroy));
|
||||||
|
/* check for delayed certificate cache queue */
|
||||||
|
cache_queue(this->this);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -985,7 +988,6 @@ METHOD(enumerator_t, public_destroy, void,
|
|||||||
this->wrapper->destroy(this->wrapper);
|
this->wrapper->destroy(this->wrapper);
|
||||||
}
|
}
|
||||||
this->this->lock->unlock(this->this->lock);
|
this->this->lock->unlock(this->this->lock);
|
||||||
|
|
||||||
/* check for delayed certificate cache queue */
|
/* check for delayed certificate cache queue */
|
||||||
cache_queue(this->this);
|
cache_queue(this->this);
|
||||||
free(this);
|
free(this);
|
||||||
@@ -993,7 +995,7 @@ METHOD(enumerator_t, public_destroy, void,
|
|||||||
|
|
||||||
METHOD(credential_manager_t, create_public_enumerator, enumerator_t*,
|
METHOD(credential_manager_t, create_public_enumerator, enumerator_t*,
|
||||||
private_credential_manager_t *this, key_type_t type, identification_t *id,
|
private_credential_manager_t *this, key_type_t type, identification_t *id,
|
||||||
auth_cfg_t *auth)
|
auth_cfg_t *auth, bool online)
|
||||||
{
|
{
|
||||||
public_enumerator_t *enumerator;
|
public_enumerator_t *enumerator;
|
||||||
|
|
||||||
@@ -1002,7 +1004,7 @@ METHOD(credential_manager_t, create_public_enumerator, enumerator_t*,
|
|||||||
.enumerate = (void*)_public_enumerate,
|
.enumerate = (void*)_public_enumerate,
|
||||||
.destroy = _public_destroy,
|
.destroy = _public_destroy,
|
||||||
},
|
},
|
||||||
.inner = create_trusted_enumerator(this, type, id, TRUE),
|
.inner = create_trusted_enumerator(this, type, id, online),
|
||||||
.this = this,
|
.this = this,
|
||||||
);
|
);
|
||||||
if (auth)
|
if (auth)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2015 Tobias Brunner
|
||||||
* Copyright (C) 2007-2009 Martin Willi
|
* Copyright (C) 2007-2009 Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
@@ -202,14 +203,18 @@ struct credential_manager_t {
|
|||||||
* where the auth config helper contains rules for constraint checks.
|
* where the auth config helper contains rules for constraint checks.
|
||||||
* This function is very similar to create_trusted_enumerator(), but
|
* This function is very similar to create_trusted_enumerator(), but
|
||||||
* gets public keys directly.
|
* gets public keys directly.
|
||||||
|
* If online is set, revocations are checked online for the whole
|
||||||
|
* trustchain.
|
||||||
*
|
*
|
||||||
* @param type type of the key to get
|
* @param type type of the key to get
|
||||||
* @param id owner of the key, signer of the signature
|
* @param id owner of the key, signer of the signature
|
||||||
* @param auth authentication infos
|
* @param auth authentication infos
|
||||||
|
* @param online whether revocations should be checked online
|
||||||
* @return enumerator
|
* @return enumerator
|
||||||
*/
|
*/
|
||||||
enumerator_t* (*create_public_enumerator)(credential_manager_t *this,
|
enumerator_t* (*create_public_enumerator)(credential_manager_t *this,
|
||||||
key_type_t type, identification_t *id, auth_cfg_t *auth);
|
key_type_t type, identification_t *id, auth_cfg_t *auth,
|
||||||
|
bool online);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache a certificate by invoking cache_cert() on all registered sets.
|
* Cache a certificate by invoking cache_cert() on all registered sets.
|
||||||
|
|||||||
@@ -320,7 +320,8 @@ static public_key_t *find_public_key(private_tls_peer_t *this)
|
|||||||
if (cert)
|
if (cert)
|
||||||
{
|
{
|
||||||
enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
|
enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
|
||||||
KEY_ANY, cert->get_subject(cert), this->server_auth);
|
KEY_ANY, cert->get_subject(cert),
|
||||||
|
this->server_auth, TRUE);
|
||||||
while (enumerator->enumerate(enumerator, ¤t, &auth))
|
while (enumerator->enumerate(enumerator, ¤t, &auth))
|
||||||
{
|
{
|
||||||
found = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
|
found = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
|
||||||
|
|||||||
@@ -548,7 +548,7 @@ static status_t process_cert_verify(private_tls_server_t *this,
|
|||||||
bio_reader_t *sig;
|
bio_reader_t *sig;
|
||||||
|
|
||||||
enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
|
enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
|
||||||
KEY_ANY, this->peer, this->peer_auth);
|
KEY_ANY, this->peer, this->peer_auth, TRUE);
|
||||||
while (enumerator->enumerate(enumerator, &public, &auth))
|
while (enumerator->enumerate(enumerator, &public, &auth))
|
||||||
{
|
{
|
||||||
sig = bio_reader_create(reader->peek(reader));
|
sig = bio_reader_create(reader->peek(reader));
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ openssl crl -in crl.pem -outform der -out strongswan.crl
|
|||||||
cp strongswan.crl ${ROOT}
|
cp strongswan.crl ${ROOT}
|
||||||
cp strongswanCert.pem ${ROOT}
|
cp strongswanCert.pem ${ROOT}
|
||||||
cp index.html ${ROOT}
|
cp index.html ${ROOT}
|
||||||
|
# revoke moon's current CERT
|
||||||
|
pki --signcrl --cacert strongswanCert.pem --cakey strongswanKey.pem --lifetime 30 --reason key-compromise --cert newcerts/2B.pem --lastcrl strongswan.crl > strongswan_moon_revoked.crl
|
||||||
|
cp strongswan_moon_revoked.crl ${ROOT}
|
||||||
cd /etc/openssl/research
|
cd /etc/openssl/research
|
||||||
openssl ca -gencrl -crldays 15 -config /etc/openssl/research/openssl.cnf -out crl.pem
|
openssl ca -gencrl -crldays 15 -config /etc/openssl/research/openssl.cnf -out crl.pem
|
||||||
openssl crl -in crl.pem -outform der -out research.crl
|
openssl crl -in crl.pem -outform der -out research.crl
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
This scenario tests <b>make-before-break reauthentication</b> using overlapping
|
||||||
|
IKE_SAs by setting the <i>make_before_break</i> strongswan.conf option. The
|
||||||
|
initiator <b>carol</b> reauthenticates the IKE_SA with host <b>moon</b> using
|
||||||
|
<b>ikelifetime=10s</b>, but does not close the old IKE_SA before the replacement
|
||||||
|
CHILD_SA is in place. A constant ping from <b>carol</b> to client <b>alice</b>
|
||||||
|
hiding in the subnet behind <b>moon</b> tests if the CHILD_SA works during the
|
||||||
|
whole procedure.
|
||||||
|
<p/>
|
||||||
|
Because the responder is always able to install CHILD_SAs before the initiator
|
||||||
|
is, some traffic sent by the responder over such a CHILD_SA might get dropped by
|
||||||
|
the initiator (until it also installed the CHILD_SA). This is particularly
|
||||||
|
problematic if OCSP/CRL checks are delayed or if they can also be done via the
|
||||||
|
IPsec tunnel once it's established. Therefore, online OCSP/CRL checks are
|
||||||
|
suspended during the reauthentication and done afterwards. This is verified here
|
||||||
|
by revoking the responder's certificate after the SA got initially established.
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
winnetou::cp /var/www/strongswan.crl /var/www/strongswan.crl.bak
|
||||||
|
winnetou::cp /var/www/strongswan_moon_revoked.crl /var/www/strongswan.crl
|
||||||
|
carol::ipsec purgecrls
|
||||||
|
moon:: ipsec status 2> /dev/null::rw\[1]: ESTABLISHED.*moon.strongswan.org.*[email protected]::YES
|
||||||
|
carol::ipsec status 2> /dev/null::home\[1]: ESTABLISHED.*[email protected].*moon.strongswan.org::YES
|
||||||
|
carol::sleep 6
|
||||||
|
carol::cat /var/log/daemon.log::certificate was revoked.*key compromise::YES
|
||||||
|
carol::cat /var/log/daemon.log::peer certificate verification failed, deleting SA::YES
|
||||||
|
moon:: ipsec status 2> /dev/null::rw\[2]: ESTABLISHED.*moon.strongswan.org.*[email protected]::NO
|
||||||
|
carol::ipsec status 2> /dev/null::home\[2]: ESTABLISHED.*[email protected].*moon.strongswan.org::NO
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# /etc/ipsec.conf - strongSwan IPsec configuration file
|
||||||
|
|
||||||
|
config setup
|
||||||
|
strictcrlpolicy=yes
|
||||||
|
|
||||||
|
conn %default
|
||||||
|
keylife=20m
|
||||||
|
ikelifetime=10s
|
||||||
|
rekeymargin=5s
|
||||||
|
rekeyfuzz=0%
|
||||||
|
keyingtries=1
|
||||||
|
|
||||||
|
conn home
|
||||||
|
left=PH_IP_CAROL
|
||||||
|
leftcert=carolCert.pem
|
||||||
|
[email protected]
|
||||||
|
right=PH_IP_MOON
|
||||||
|
[email protected]
|
||||||
|
rightsubnet=10.1.0.0/16
|
||||||
|
keyexchange=ikev2
|
||||||
|
auto=add
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# /etc/strongswan.conf - strongSwan configuration file
|
||||||
|
|
||||||
|
charon {
|
||||||
|
load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac xcbc stroke kernel-netlink socket-default updown
|
||||||
|
|
||||||
|
make_before_break = yes
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# /etc/ipsec.conf - strongSwan IPsec configuration file
|
||||||
|
|
||||||
|
config setup
|
||||||
|
strictcrlpolicy=yes
|
||||||
|
|
||||||
|
conn %default
|
||||||
|
ikelifetime=30m
|
||||||
|
keylife=20m
|
||||||
|
rekeymargin=0s
|
||||||
|
keyingtries=1
|
||||||
|
|
||||||
|
conn rw
|
||||||
|
left=PH_IP_MOON
|
||||||
|
leftcert=moonCert.pem
|
||||||
|
[email protected]
|
||||||
|
leftsubnet=10.1.0.0/16
|
||||||
|
right=%any
|
||||||
|
keyexchange=ikev2
|
||||||
|
auto=add
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# /etc/strongswan.conf - strongSwan configuration file
|
||||||
|
|
||||||
|
charon {
|
||||||
|
load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac xcbc stroke kernel-netlink socket-default updown
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
winnetou::cp /var/www/strongswan.crl.bak /var/www/strongswan.crl
|
||||||
|
moon::ipsec stop
|
||||||
|
carol::ipsec stop
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
moon::ipsec start
|
||||||
|
carol::ipsec start
|
||||||
|
carol::expect-connection home
|
||||||
|
carol::ipsec up home
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#!/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="alice moon carol winnetou"
|
||||||
|
|
||||||
|
# Corresponding block diagram
|
||||||
|
#
|
||||||
|
DIAGRAM="a-m-c-w.png"
|
||||||
|
|
||||||
|
# Guest instances on which tcpdump is to be started
|
||||||
|
#
|
||||||
|
TCPDUMPHOSTS="moon"
|
||||||
|
|
||||||
|
# Guest instances on which IPsec is started
|
||||||
|
# Used for IPsec logging purposes
|
||||||
|
#
|
||||||
|
IPSECHOSTS="moon carol"
|
||||||
Reference in New Issue
Block a user