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:
Tobias Brunner
2016-03-10 11:50:57 +01:00
28 changed files with 477 additions and 14 deletions
+9
View File
@@ -11,6 +11,15 @@ strongswan-5.4.0
constraints against IKEv2 authentication in rightauth, which allows the use
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
Perl applications to control and/or monitor the IKE daemon using the VICI
interface, similar to the existing Python egg or Ruby gem.
+2 -1
View File
@@ -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_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_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 += \
sa/ikev1/keymat_v1.c sa/ikev1/keymat_v1.h \
+2 -1
View File
@@ -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_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_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
if USE_IKEV1
+117 -3
View File
@@ -58,6 +58,7 @@
#include <sa/ikev2/tasks/ike_auth_lifetime.h>
#include <sa/ikev2/tasks/ike_reauth_complete.h>
#include <sa/ikev2/tasks/ike_redirect.h>
#include <credentials/sets/auth_cfg_wrapper.h>
#ifdef ME
#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, &not_before, &not_after))
{
DBG1(DBG_IKE, "peer certificate invalid (valid from %T to %T)",
&not_before, FALSE, &not_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*,
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);
if (this->flush_auth_cfg && this->state == IKE_ESTABLISHED)
{
/* authentication completed */
this->flush_auth_cfg = FALSE;
flush_auth_cfgs(this);
/* authentication completed but if the online validation is suspended we
* need the auth cfgs until we did the delayed verification, we flush
* them afterwards */
if (!has_condition(this, COND_ONLINE_VALIDATION_SUSPENDED))
{
this->flush_auth_cfg = FALSE;
flush_auth_cfgs(this);
}
}
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,
.get_auth_cfg = _get_auth_cfg,
.create_auth_cfg_enumerator = _create_auth_cfg_enumerator,
.verify_peer_certificate = _verify_peer_certificate,
.add_auth_cfg = _add_auth_cfg,
.get_proposal = _get_proposal,
.set_proposal = _set_proposal,
+13
View File
@@ -217,6 +217,11 @@ enum ike_condition_t {
* This IKE_SA has been redirected
*/
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);
/**
* 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.
*
@@ -173,7 +173,7 @@ METHOD(authenticator_t, process, status_t,
sig = sig_payload->get_hash(sig_payload);
auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
enumerator = lib->credmgr->create_public_enumerator(lib->credmgr, this->type,
id, auth);
id, auth, TRUE);
while (enumerator->enumerate(enumerator, &public, &current_auth))
{
if (public->verify(public, scheme, hash, sig))
@@ -365,6 +365,7 @@ METHOD(authenticator_t, process, status_t,
status_t status = NOT_FOUND;
keymat_v2_t *keymat;
const char *reason = "unsupported";
bool online;
auth_payload = (auth_payload_t*)message->get_payload(message, PLV2_AUTH);
if (!auth_payload)
@@ -408,8 +409,10 @@ METHOD(authenticator_t, process, status_t,
return FAILED;
}
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,
key_type, id, auth);
key_type, id, auth, online);
while (enumerator->enumerate(enumerator, &public, &current_auth))
{
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->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
auth->add(auth, AUTH_RULE_IKE_SIGNATURE_SCHEME, (uintptr_t)scheme);
if (!online)
{
auth->add(auth, AUTH_RULE_CERT_VALIDATION_SUSPENDED, TRUE);
}
break;
}
else
+11 -1
View File
@@ -35,6 +35,7 @@
#include <sa/ikev2/tasks/ike_config.h>
#include <sa/ikev2/tasks/ike_dpd.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_rekey.h>
#include <sa/ikev2/tasks/child_delete.h>
@@ -527,6 +528,11 @@ METHOD(task_manager_t, initiate, status_t,
exchange = INFORMATIONAL;
break;
}
if (activate_task(this, TASK_IKE_VERIFY_PEER_CERT))
{
exchange = INFORMATIONAL;
break;
}
case IKE_REKEYING:
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)
{
message->destroy(message);
return SUCCESS;
return initiate(this);
}
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);
/* 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)
{
new->queue_task(new, (task_t*)ike_verify_peer_cert_create(new));
new->queue_task(new, (task_t*)ike_reauth_complete_create(new,
this->ike_sa->get_id(this->ike_sa)));
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_ @}*/
+1
View File
@@ -29,6 +29,7 @@ ENUM(task_type_names, TASK_IKE_INIT, TASK_ISAKMP_CERT_POST,
"IKE_REAUTH",
"IKE_REAUTH_COMPLETE",
"IKE_REDIRECT",
"IKE_VERIFY_PEER_CERT",
"IKE_DELETE",
"IKE_DPD",
"IKE_VENDOR",
+2
View File
@@ -59,6 +59,8 @@ enum task_type_t {
TASK_IKE_REAUTH_COMPLETE,
/** redirect an active IKE_SA */
TASK_IKE_REDIRECT,
/** verify a peer's certificate */
TASK_IKE_VERIFY_PEER_CERT,
/** delete an IKE_SA */
TASK_IKE_DELETE,
/** liveness check */
+16
View File
@@ -46,6 +46,7 @@ ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_AC_CERT,
"RULE_SUBJECT_CERT",
"RULE_CRL_VALIDATION",
"RULE_OCSP_VALIDATION",
"RULE_CERT_VALIDATION_SUSPENDED",
"RULE_GROUP",
"RULE_RSA_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_XAUTH_IDENTITY:
case AUTH_RULE_XAUTH_BACKEND:
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
case AUTH_HELPER_SUBJECT_CERT:
case AUTH_HELPER_SUBJECT_HASH_URL:
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_SIGNATURE_SCHEME:
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
/* integer type */
this->value = (void*)(uintptr_t)va_arg(args, u_int);
break;
@@ -264,6 +267,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2)
case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
{
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_SIGNATURE_SCHEME:
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
case AUTH_RULE_MAX:
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_SIGNATURE_SCHEME:
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
/* integer type */
entry->value = (void*)(uintptr_t)va_arg(args, u_int);
break;
@@ -471,6 +477,7 @@ METHOD(auth_cfg_t, get, void*,
case AUTH_RULE_OCSP_VALIDATION:
return (void*)VALIDATION_FAILED;
case AUTH_RULE_IDENTITY_LOOSE:
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
return (void*)FALSE;
case AUTH_RULE_IDENTITY:
case AUTH_RULE_EAP_IDENTITY:
@@ -757,6 +764,11 @@ METHOD(auth_cfg_t, complies, bool,
{
uintptr_t validated;
if (get(this, AUTH_RULE_CERT_VALIDATION_SUSPENDED))
{ /* skip validation, may happen later */
break;
}
e2 = create_enumerator(this);
while (e2->enumerate(e2, &t2, &validated))
{
@@ -934,6 +946,8 @@ METHOD(auth_cfg_t, complies, bool,
/* just an indication when verifying AUTH_RULE_IDENTITY */
case AUTH_RULE_XAUTH_BACKEND:
/* 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_SUBJECT_CERT:
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_SIGNATURE_SCHEME:
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
{
add(this, type, (uintptr_t)value);
break;
@@ -1257,6 +1272,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*,
case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
clone->add(clone, type, (uintptr_t)value);
break;
case AUTH_RULE_MAX:
+2
View File
@@ -94,6 +94,8 @@ enum auth_rule_t {
AUTH_RULE_CRL_VALIDATION,
/** result of a OCSP validation, cert_validation_t */
AUTH_RULE_OCSP_VALIDATION,
/** CRL/OCSP validation is disabled, bool */
AUTH_RULE_CERT_VALIDATION_SUSPENDED,
/** subject is member of a group, identification_t*
* The group membership constraint is fulfilled if the subject is member of
* one group defined in the constraints. */
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2015 Tobias Brunner
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -917,6 +918,8 @@ METHOD(enumerator_t, trusted_destroy, void,
DESTROY_IF(this->auth);
DESTROY_IF(this->candidates);
this->failed->destroy_offset(this->failed, offsetof(certificate_t, destroy));
/* check for delayed certificate cache queue */
cache_queue(this->this);
free(this);
}
@@ -985,7 +988,6 @@ METHOD(enumerator_t, public_destroy, void,
this->wrapper->destroy(this->wrapper);
}
this->this->lock->unlock(this->this->lock);
/* check for delayed certificate cache queue */
cache_queue(this->this);
free(this);
@@ -993,7 +995,7 @@ METHOD(enumerator_t, public_destroy, void,
METHOD(credential_manager_t, create_public_enumerator, enumerator_t*,
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;
@@ -1002,7 +1004,7 @@ METHOD(credential_manager_t, create_public_enumerator, enumerator_t*,
.enumerate = (void*)_public_enumerate,
.destroy = _public_destroy,
},
.inner = create_trusted_enumerator(this, type, id, TRUE),
.inner = create_trusted_enumerator(this, type, id, online),
.this = this,
);
if (auth)
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2015 Tobias Brunner
* Copyright (C) 2007-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -202,14 +203,18 @@ struct credential_manager_t {
* where the auth config helper contains rules for constraint checks.
* This function is very similar to create_trusted_enumerator(), but
* 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 id owner of the key, signer of the signature
* @param auth authentication infos
* @param online whether revocations should be checked online
* @return enumerator
*/
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.
+2 -1
View File
@@ -320,7 +320,8 @@ static public_key_t *find_public_key(private_tls_peer_t *this)
if (cert)
{
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, &current, &auth))
{
found = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+1 -1
View File
@@ -548,7 +548,7 @@ static status_t process_cert_verify(private_tls_server_t *this,
bio_reader_t *sig;
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))
{
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 strongswanCert.pem ${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
openssl ca -gencrl -crldays 15 -config /etc/openssl/research/openssl.cnf -out crl.pem
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"