From 5452e3d66e6bc20f1052f3d616a0f29eab17256c Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 26 Oct 2015 15:35:23 +0100 Subject: [PATCH 01/13] credential-manager: Make online revocation checks optional for public key enumerator --- .../sa/ikev1/authenticators/pubkey_v1_authenticator.c | 2 +- .../sa/ikev2/authenticators/pubkey_authenticator.c | 2 +- src/libstrongswan/credentials/credential_manager.c | 5 +++-- src/libstrongswan/credentials/credential_manager.h | 7 ++++++- src/libtls/tls_peer.c | 3 ++- src/libtls/tls_server.c | 2 +- 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c index 793e6d5c1..eee7dd10b 100644 --- a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c +++ b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c @@ -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, ¤t_auth)) { if (public->verify(public, scheme, hash, sig)) diff --git a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c index 110c50973..dca80a4d8 100644 --- a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c +++ b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c @@ -409,7 +409,7 @@ METHOD(authenticator_t, process, status_t, } auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); enumerator = lib->credmgr->create_public_enumerator(lib->credmgr, - key_type, id, auth); + key_type, id, auth, TRUE); while (enumerator->enumerate(enumerator, &public, ¤t_auth)) { if (public->verify(public, scheme, octets, auth_data)) diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index 371e6404d..736111b93 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015 Tobias Brunner * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -993,7 +994,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 +1003,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) diff --git a/src/libstrongswan/credentials/credential_manager.h b/src/libstrongswan/credentials/credential_manager.h index 445ea3f9c..022ca566c 100644 --- a/src/libstrongswan/credentials/credential_manager.h +++ b/src/libstrongswan/credentials/credential_manager.h @@ -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. diff --git a/src/libtls/tls_peer.c b/src/libtls/tls_peer.c index 000dda43b..8087e2e2d 100644 --- a/src/libtls/tls_peer.c +++ b/src/libtls/tls_peer.c @@ -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, ¤t, &auth)) { found = auth->get(auth, AUTH_RULE_SUBJECT_CERT); diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c index f9295a160..cfbe02037 100644 --- a/src/libtls/tls_server.c +++ b/src/libtls/tls_server.c @@ -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)); From f371effc5d59c15ff72184898193c6119fb8889b Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 27 Oct 2015 17:17:54 +0100 Subject: [PATCH 02/13] credential-manager: Check cache queue when destroying trusted certificate enumerator We already do this in the trusted public key enumerator (which internally uses the trusted certificate enumerator) but should do so also when this enumerator is used directly (since the public key enumerator has the read lock the additional call will just be skipped there). --- src/libstrongswan/credentials/credential_manager.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index 736111b93..95c5cd777 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -918,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); } @@ -986,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); From ef9171ad1ee9145a7139c365524006abb930a41d Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 27 Oct 2015 17:21:18 +0100 Subject: [PATCH 03/13] auth-cfg: Add a rule to suspend certificate validation constraints --- src/libstrongswan/credentials/auth_cfg.c | 16 ++++++++++++++++ src/libstrongswan/credentials/auth_cfg.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index 5466a2e08..956ce08c9 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -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: diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h index 75bc7e97b..6940069de 100644 --- a/src/libstrongswan/credentials/auth_cfg.h +++ b/src/libstrongswan/credentials/auth_cfg.h @@ -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. */ From 1b9c1ae018aa176aaf9e1f11503b72cc622ba771 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 27 Oct 2015 17:25:22 +0100 Subject: [PATCH 04/13] ike-sa: Add method to verify certificates in completed authentication rounds --- src/libcharon/sa/ike_sa.c | 103 ++++++++++++++++++++++++++++++++++++++ src/libcharon/sa/ike_sa.h | 8 +++ 2 files changed, 111 insertions(+) diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index b07ff0e74..3384c0278 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -58,6 +58,7 @@ #include #include #include +#include #ifdef ME #include @@ -462,6 +463,107 @@ METHOD(ike_sa_t, create_auth_cfg_enumerator, enumerator_t*, return array_create_enumerator(this->other_auths); } +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 (lib->settings->get_bool(lib->settings, + "%s.flush_auth_cfg", FALSE, lib->ns)) + { + DBG1(DBG_IKE, "unable to verify peer certificate as authentication " + "information has been flushed"); + return 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)) + { + /* FIXME: theoretically we could find a newer cert with the same + * identity and public key below...but it's not the cert used by + * the peer during the original authentication so... */ + 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); + return valid; +} + /** * Flush the stored authentication round information */ @@ -2750,6 +2852,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, diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index 158a690df..0f47ad31f 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -521,6 +521,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. * From e19162a50964f394eab891f661963be732817330 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 27 Oct 2015 17:27:02 +0100 Subject: [PATCH 05/13] ike-sa: Add condition to suspend online certificate revocation checks for an IKE_SA --- src/libcharon/sa/ike_sa.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index 0f47ad31f..836360e3c 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -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), }; /** From a05cff1ec0c7473bee147a5213de9dd0317cb5ec Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 27 Oct 2015 17:28:20 +0100 Subject: [PATCH 06/13] ikev2: Don't do online revocation checks in pubkey authenticator if requested We also update the auth config so the constraints are not enforced. --- .../sa/ikev2/authenticators/pubkey_authenticator.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c index dca80a4d8..04ccd4f4f 100644 --- a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c +++ b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c @@ -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, TRUE); + key_type, id, auth, online); while (enumerator->enumerate(enumerator, &public, ¤t_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 From 034a462901209dd8f04bf984ef90c2d6ba2c776e Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 27 Oct 2015 17:29:53 +0100 Subject: [PATCH 07/13] ikev2: Initiate other tasks after a no-op task --- src/libcharon/sa/ikev2/task_manager_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index 8ed86302b..b7c5f6691 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -624,7 +624,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)) From 8ce78e43a4746ce4d3d107ef2ed2f4e13f1c9c8f Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 27 Oct 2015 17:31:43 +0100 Subject: [PATCH 08/13] ikev2: Add task that verifies a peer's certificate On failure the SA is deleted and reestablished as configured. The task is activated after the REAUTH_COMPLETE task so a make-before-break reauth is completed before the new SA might get torn down. --- src/libcharon/Android.mk | 3 +- src/libcharon/Makefile.am | 3 +- src/libcharon/sa/ikev2/task_manager_v2.c | 5 + .../sa/ikev2/tasks/ike_verify_peer_cert.c | 117 ++++++++++++++++++ .../sa/ikev2/tasks/ike_verify_peer_cert.h | 54 ++++++++ src/libcharon/sa/task.c | 1 + src/libcharon/sa/task.h | 2 + 7 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 src/libcharon/sa/ikev2/tasks/ike_verify_peer_cert.c create mode 100644 src/libcharon/sa/ikev2/tasks/ike_verify_peer_cert.h diff --git a/src/libcharon/Android.mk b/src/libcharon/Android.mk index 0b09d100d..8f8c96588 100644 --- a/src/libcharon/Android.mk +++ b/src/libcharon/Android.mk @@ -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 \ diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am index 062b96aff..61e57c1cb 100644 --- a/src/libcharon/Makefile.am +++ b/src/libcharon/Makefile.am @@ -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 diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index b7c5f6691..c573c23c8 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -527,6 +527,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)) { diff --git a/src/libcharon/sa/ikev2/tasks/ike_verify_peer_cert.c b/src/libcharon/sa/ikev2/tasks/ike_verify_peer_cert.c new file mode 100644 index 000000000..069d51d00 --- /dev/null +++ b/src/libcharon/sa/ikev2/tasks/ike_verify_peer_cert.c @@ -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 . + * + * 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 +#include + +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; +} diff --git a/src/libcharon/sa/ikev2/tasks/ike_verify_peer_cert.h b/src/libcharon/sa/ikev2/tasks/ike_verify_peer_cert.h new file mode 100644 index 000000000..3d9aae0b3 --- /dev/null +++ b/src/libcharon/sa/ikev2/tasks/ike_verify_peer_cert.h @@ -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 . + * + * 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 +#include +#include + +/** + * 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_ @}*/ diff --git a/src/libcharon/sa/task.c b/src/libcharon/sa/task.c index 4bd2ba221..405eda66b 100644 --- a/src/libcharon/sa/task.c +++ b/src/libcharon/sa/task.c @@ -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", diff --git a/src/libcharon/sa/task.h b/src/libcharon/sa/task.h index b2e9d8886..31d70fb3b 100644 --- a/src/libcharon/sa/task.h +++ b/src/libcharon/sa/task.h @@ -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 */ From f1cbacc5d1be01938f35d04dfad10e0ed441ce0f Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 27 Oct 2015 17:34:50 +0100 Subject: [PATCH 09/13] ikev2: Delay online revocation checks during make-before-break reauthentication We do these checks after the SA is fully established. When establishing an SA the responder is always able to install the CHILD_SA created with the IKE_SA before the initiator can do so. During make-before-break reauthentication this could cause traffic sent by the responder to get dropped if the installation of the SA on the initiator is delayed e.g. by OCSP/CRL checks. In particular, if the OCSP/CRL URIs are reachable via IPsec tunnel (e.g. with rightsubnet=0.0.0.0/0) the initiator is unable to reach them during make-before-break reauthentication as it wouldn't be able to decrypt the response that the responder sends using the new CHILD_SA. By delaying the revocation checks until the make-before-break reauthentication is completed we avoid the problems described above. Since this only affects reauthentication, not the original IKE_SA, and the delay until the checks are performed is usually not that long this doesn't impose much of a reduction in the overall security. --- src/libcharon/sa/ikev2/task_manager_v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index c573c23c8..c2f972ab1 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -1655,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); From e41adf5f05a35bf6a2f8cd1d5a566f8f1fb6a25b Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 28 Oct 2015 16:09:59 +0100 Subject: [PATCH 10/13] ike-sa: Improve interaction between flush_auth_cfg and delayed revocation checks --- src/libcharon/sa/ike_sa.c | 67 +++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 3384c0278..bcbff3211 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -463,6 +463,26 @@ METHOD(ike_sa_t, create_auth_cfg_enumerator, enumerator_t*, return array_create_enumerator(this->other_auths); } +/** + * Flush the stored authentication round information + */ +static void flush_auth_cfgs(private_ike_sa_t *this) +{ + auth_cfg_t *cfg; + + this->my_auth->purge(this->my_auth, FALSE); + this->other_auth->purge(this->other_auth, FALSE); + + while (array_remove(this->my_auths, ARRAY_TAIL, &cfg)) + { + cfg->destroy(cfg); + } + while (array_remove(this->other_auths, ARRAY_TAIL, &cfg)) + { + cfg->destroy(cfg); + } +} + METHOD(ike_sa_t, verify_peer_certificate, bool, private_ike_sa_t *this) { @@ -482,13 +502,16 @@ METHOD(ike_sa_t, verify_peer_certificate, bool, return FALSE; } - if (lib->settings->get_bool(lib->settings, + 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); @@ -514,9 +537,6 @@ METHOD(ike_sa_t, verify_peer_certificate, bool, } if (!peer->get_validity(peer, NULL, ¬_before, ¬_after)) { - /* FIXME: theoretically we could find a newer cert with the same - * identity and public key below...but it's not the cert used by - * the peer during the original authentication so... */ DBG1(DBG_IKE, "peer certificate invalid (valid from %T to %T)", ¬_before, FALSE, ¬_after, FALSE); valid = FALSE; @@ -561,29 +581,15 @@ METHOD(ike_sa_t, verify_peer_certificate, bool, } e1->destroy(e1); e2->destroy(e2); + + if (this->flush_auth_cfg) + { + this->flush_auth_cfg = FALSE; + flush_auth_cfgs(this); + } return valid; } -/** - * Flush the stored authentication round information - */ -static void flush_auth_cfgs(private_ike_sa_t *this) -{ - auth_cfg_t *cfg; - - this->my_auth->purge(this->my_auth, FALSE); - this->other_auth->purge(this->other_auth, FALSE); - - while (array_remove(this->my_auths, ARRAY_TAIL, &cfg)) - { - cfg->destroy(cfg); - } - while (array_remove(this->other_auths, ARRAY_TAIL, &cfg)) - { - cfg->destroy(cfg); - } -} - METHOD(ike_sa_t, get_proposal, proposal_t*, private_ike_sa_t *this) { @@ -1543,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; } From d163aa5eaf265ae7fc69fe0689ad82ea1149b410 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 27 Oct 2015 17:42:15 +0100 Subject: [PATCH 11/13] testing: Generate a CRL that has moon's actual certificate revoked --- testing/hosts/winnetou/etc/openssl/generate-crl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testing/hosts/winnetou/etc/openssl/generate-crl b/testing/hosts/winnetou/etc/openssl/generate-crl index 842c3a1b2..de3c13dcf 100755 --- a/testing/hosts/winnetou/etc/openssl/generate-crl +++ b/testing/hosts/winnetou/etc/openssl/generate-crl @@ -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 From dc57c1b81787d726d57f3e6c8f3c907876ef2fa5 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 27 Oct 2015 17:42:45 +0100 Subject: [PATCH 12/13] testing: Add ikev2/reauth-mbb-revoked scenario --- .../ikev2/reauth-mbb-revoked/description.txt | 15 +++++++++++++ .../ikev2/reauth-mbb-revoked/evaltest.dat | 10 +++++++++ .../hosts/carol/etc/ipsec.conf | 21 +++++++++++++++++++ .../hosts/carol/etc/strongswan.conf | 7 +++++++ .../hosts/moon/etc/ipsec.conf | 19 +++++++++++++++++ .../hosts/moon/etc/strongswan.conf | 5 +++++ .../ikev2/reauth-mbb-revoked/posttest.dat | 3 +++ .../ikev2/reauth-mbb-revoked/pretest.dat | 4 ++++ .../tests/ikev2/reauth-mbb-revoked/test.conf | 21 +++++++++++++++++++ 9 files changed, 105 insertions(+) create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/description.txt create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/evaltest.dat create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/hosts/carol/etc/ipsec.conf create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/hosts/carol/etc/strongswan.conf create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/hosts/moon/etc/ipsec.conf create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/hosts/moon/etc/strongswan.conf create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/posttest.dat create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/pretest.dat create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/test.conf diff --git a/testing/tests/ikev2/reauth-mbb-revoked/description.txt b/testing/tests/ikev2/reauth-mbb-revoked/description.txt new file mode 100644 index 000000000..4e27a0b82 --- /dev/null +++ b/testing/tests/ikev2/reauth-mbb-revoked/description.txt @@ -0,0 +1,15 @@ +This scenario tests make-before-break reauthentication using overlapping +IKE_SAs by setting the make_before_break strongswan.conf option. The +initiator carol reauthenticates the IKE_SA with host moon using +ikelifetime=10s, but does not close the old IKE_SA before the replacement +CHILD_SA is in place. A constant ping from carol to client alice +hiding in the subnet behind moon tests if the CHILD_SA works during the +whole procedure. +

+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. diff --git a/testing/tests/ikev2/reauth-mbb-revoked/evaltest.dat b/testing/tests/ikev2/reauth-mbb-revoked/evaltest.dat new file mode 100644 index 000000000..8fe9a2360 --- /dev/null +++ b/testing/tests/ikev2/reauth-mbb-revoked/evaltest.dat @@ -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.*carol@strongswan.org::YES +carol::ipsec status 2> /dev/null::home\[1]: ESTABLISHED.*carol@strongswan.org.*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.*carol@strongswan.org::NO +carol::ipsec status 2> /dev/null::home\[2]: ESTABLISHED.*carol@strongswan.org.*moon.strongswan.org::NO diff --git a/testing/tests/ikev2/reauth-mbb-revoked/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/reauth-mbb-revoked/hosts/carol/etc/ipsec.conf new file mode 100644 index 000000000..ec2b41d29 --- /dev/null +++ b/testing/tests/ikev2/reauth-mbb-revoked/hosts/carol/etc/ipsec.conf @@ -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 + leftid=carol@strongswan.org + right=PH_IP_MOON + rightid=@moon.strongswan.org + rightsubnet=10.1.0.0/16 + keyexchange=ikev2 + auto=add diff --git a/testing/tests/ikev2/reauth-mbb-revoked/hosts/carol/etc/strongswan.conf b/testing/tests/ikev2/reauth-mbb-revoked/hosts/carol/etc/strongswan.conf new file mode 100644 index 000000000..f89437e43 --- /dev/null +++ b/testing/tests/ikev2/reauth-mbb-revoked/hosts/carol/etc/strongswan.conf @@ -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 +} diff --git a/testing/tests/ikev2/reauth-mbb-revoked/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/reauth-mbb-revoked/hosts/moon/etc/ipsec.conf new file mode 100644 index 000000000..93ae34cf7 --- /dev/null +++ b/testing/tests/ikev2/reauth-mbb-revoked/hosts/moon/etc/ipsec.conf @@ -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 + leftid=@moon.strongswan.org + leftsubnet=10.1.0.0/16 + right=%any + keyexchange=ikev2 + auto=add diff --git a/testing/tests/ikev2/reauth-mbb-revoked/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/reauth-mbb-revoked/hosts/moon/etc/strongswan.conf new file mode 100644 index 000000000..f585edfca --- /dev/null +++ b/testing/tests/ikev2/reauth-mbb-revoked/hosts/moon/etc/strongswan.conf @@ -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 +} diff --git a/testing/tests/ikev2/reauth-mbb-revoked/posttest.dat b/testing/tests/ikev2/reauth-mbb-revoked/posttest.dat new file mode 100644 index 000000000..d0d591585 --- /dev/null +++ b/testing/tests/ikev2/reauth-mbb-revoked/posttest.dat @@ -0,0 +1,3 @@ +winnetou::cp /var/www/strongswan.crl.bak /var/www/strongswan.crl +moon::ipsec stop +carol::ipsec stop diff --git a/testing/tests/ikev2/reauth-mbb-revoked/pretest.dat b/testing/tests/ikev2/reauth-mbb-revoked/pretest.dat new file mode 100644 index 000000000..3a1982f8a --- /dev/null +++ b/testing/tests/ikev2/reauth-mbb-revoked/pretest.dat @@ -0,0 +1,4 @@ +moon::ipsec start +carol::ipsec start +carol::expect-connection home +carol::ipsec up home diff --git a/testing/tests/ikev2/reauth-mbb-revoked/test.conf b/testing/tests/ikev2/reauth-mbb-revoked/test.conf new file mode 100644 index 000000000..4a5fc470f --- /dev/null +++ b/testing/tests/ikev2/reauth-mbb-revoked/test.conf @@ -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" From b4337c5b027871d6bb076b85d9a8699f86a74fa6 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 10 Mar 2016 11:46:44 +0100 Subject: [PATCH 13/13] NEWS: Added note on online revocation checks during make-before-break reauthentication --- NEWS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/NEWS b/NEWS index fcb89f09e..1d69cd822 100644 --- a/NEWS +++ b/NEWS @@ -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.