From 49d9266c31383ee3494a6762def70fa9b75829c3 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 3 Oct 2016 12:10:40 +0200 Subject: [PATCH 1/6] pki: Use serial of base CRL for delta CRLs According to RFC 5280 delta CRLs and complete CRLs MUST share one numbering sequence. --- src/pki/commands/signcrl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pki/commands/signcrl.c b/src/pki/commands/signcrl.c index 6c27289f9..6d873d326 100644 --- a/src/pki/commands/signcrl.c +++ b/src/pki/commands/signcrl.c @@ -369,7 +369,10 @@ static int sign_crl() } else { - crl_serial = chunk_from_chars(0x00); + if (!crl_serial.ptr) + { + crl_serial = chunk_from_chars(0x00); + } lastenum = enumerator_create_empty(); } From 790847d17c27c412b68a91a7f8505fbc083fa567 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 3 Oct 2016 12:15:10 +0200 Subject: [PATCH 2/6] pki: Don't remove zero bytes in CRL serials anymore This was added a few years ago because pki --signcrl once encoded serials incorrectly as eight byte blobs. But still ensure we have can handle overflows in case the serial is encoded incorrectly without zero-prefix. --- src/pki/commands/signcrl.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/pki/commands/signcrl.c b/src/pki/commands/signcrl.c index 6d873d326..b9cf9c466 100644 --- a/src/pki/commands/signcrl.c +++ b/src/pki/commands/signcrl.c @@ -376,14 +376,15 @@ static int sign_crl() lastenum = enumerator_create_empty(); } - /* remove superfluous leading zeros */ - while (crl_serial.len > 1 && crl_serial.ptr[0] == 0x00 && - (crl_serial.ptr[1] & 0x80) == 0x00) + if (!crl_serial.len || crl_serial.ptr[0] & 0x80) + { /* add leading 0x00 to handle potential overflow if serial is encoded + * incorrectly */ + crl_serial = chunk_cat("cc", chunk_from_chars(0x00), crl_serial); + } + else { - crl_serial = chunk_skip_zero(crl_serial); + crl_serial = chunk_clone(crl_serial); } - crl_serial = chunk_clone(crl_serial); - /* increment the serial number by one */ chunk_increment(crl_serial); From cee01fc9bf58ba513b13a1e003e8f8473117773d Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 3 Oct 2016 12:40:24 +0200 Subject: [PATCH 3/6] revocation: Cache valid CRL also if certificate is revoked --- .../plugins/revocation/revocation_validator.c | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/libstrongswan/plugins/revocation/revocation_validator.c b/src/libstrongswan/plugins/revocation/revocation_validator.c index fdcb9902b..f2e3cdd83 100644 --- a/src/libstrongswan/plugins/revocation/revocation_validator.c +++ b/src/libstrongswan/plugins/revocation/revocation_validator.c @@ -403,6 +403,26 @@ static bool verify_crl(certificate_t *crl) return verified; } +/** + * Report the given CRL's validity and cache it if valid and requested + */ +static bool is_crl_valid(certificate_t *crl, bool cache) +{ + time_t valid_until; + + if (crl->get_validity(crl, NULL, NULL, &valid_until)) + { + DBG1(DBG_CFG, " crl is valid: until %T", &valid_until, FALSE); + if (cache) + { + lib->credmgr->cache_cert(lib->credmgr, crl); + } + return TRUE; + } + DBG1(DBG_CFG, " crl is stale: since %T", &valid_until, FALSE); + return FALSE; +} + /** * Get the better of two CRLs, and check for usable CRL info */ @@ -411,7 +431,7 @@ static certificate_t *get_better_crl(certificate_t *cand, certificate_t *best, bool cache, crl_t *base) { enumerator_t *enumerator; - time_t revocation, valid_until; + time_t revocation; crl_reason_t reason; chunk_t serial; crl_t *crl = (crl_t*)cand; @@ -447,8 +467,6 @@ static certificate_t *get_better_crl(certificate_t *cand, certificate_t *best, { if (chunk_equals(serial, subject->get_serial(subject))) { - DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N", - &revocation, TRUE, crl_reason_names, reason); if (reason != CRL_REASON_CERTIFICATE_HOLD) { *valid = VALIDATION_REVOKED; @@ -458,6 +476,9 @@ static certificate_t *get_better_crl(certificate_t *cand, certificate_t *best, /* if the cert is on hold, a newer CRL might not contain it */ *valid = VALIDATION_ON_HOLD; } + is_crl_valid(cand, cache); + DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N", + &revocation, TRUE, crl_reason_names, reason); enumerator->destroy(enumerator); DESTROY_IF(best); return cand; @@ -470,18 +491,12 @@ static certificate_t *get_better_crl(certificate_t *cand, certificate_t *best, { DESTROY_IF(best); best = cand; - if (best->get_validity(best, NULL, NULL, &valid_until)) + if (is_crl_valid(best, cache)) { - DBG1(DBG_CFG, " crl is valid: until %T", &valid_until, FALSE); *valid = VALIDATION_GOOD; - if (cache) - { /* we cache non-stale crls only, as a stale crls are refetched */ - lib->credmgr->cache_cert(lib->credmgr, best); - } } else { - DBG1(DBG_CFG, " crl is stale: since %T", &valid_until, FALSE); *valid = VALIDATION_STALE; } } From 9ba6548766e69d273884375b5acb2df0b37b3a2c Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 7 Oct 2016 10:56:06 +0200 Subject: [PATCH 4/6] mem-cred: Support storing a delta CRL together with its base So far every "newer" CRL (higher serial or by date) replaced an existing "older" CRL. This meant that delta CRLs replaced an existing base CRL and that base CRLs weren't added if a delta CRL was already stored. So the base had to be re-fetched every time after a delta CRL was added. With this change one delta CRL to the latest base may be stored. A newer delta CRL will replace an existing delta CRL (but not its base, older base CRLs are removed, though). And a newer base will replace the existing base and optional delta CRL. --- src/libstrongswan/credentials/sets/mem_cred.c | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c index 988e709ad..0f8bff23f 100644 --- a/src/libstrongswan/credentials/sets/mem_cred.c +++ b/src/libstrongswan/credentials/sets/mem_cred.c @@ -1,6 +1,7 @@ /* - * Copyright (C) 2010-2015 Tobias Brunner - * Hochschule fuer Technik Rapperwsil + * Copyright (C) 2010-2016 Tobias Brunner + * HSR Hochschule fuer Technik Rapperwsil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -223,6 +224,7 @@ METHOD(mem_cred_t, add_crl, bool, { if (current->get_type(current) == CERT_X509_CRL) { + chunk_t base; bool found = FALSE; crl_t *crl_c = (crl_t*)current; chunk_t authkey = crl->get_authKeyIdentifier(crl); @@ -246,17 +248,37 @@ METHOD(mem_cred_t, add_crl, bool, } if (found) { - new = crl_is_newer(crl, crl_c); - if (new) + /* we keep at most one delta CRL for each base CRL */ + if (crl->is_delta_crl(crl, &base)) { - this->untrusted->remove_at(this->untrusted, enumerator); - current->destroy(current); + if (!crl_c->is_delta_crl(crl_c, NULL)) + { + if (chunk_equals(base, crl_c->get_serial(crl_c))) + { /* keep the added delta and the existing base CRL + * but check if this is the newest delta CRL for + * the same base */ + continue; + } + } } - else + else if (crl_c->is_delta_crl(crl_c, &base)) + { + if (chunk_equals(base, crl->get_serial(crl))) + { /* keep the existing delta and the added base CRL, + * but check if we don't store it already */ + continue; + } + } + new = crl_is_newer(crl, crl_c); + if (!new) { cert->destroy(cert); + break; } - break; + /* we remove the existing older CRL but there might be other + * delta or base CRLs we can replace */ + this->untrusted->remove_at(this->untrusted, enumerator); + current->destroy(current); } } } From 2a2669ee3e7ec6ba2642cacbfa28ad235e09ac32 Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Tue, 27 Sep 2016 14:42:08 +0200 Subject: [PATCH 5/6] vici: strongswan.conf cache_crls = yes saves fetched CRLs to disk --- conf/options/charon.opt | 6 ++ src/libcharon/plugins/stroke/stroke_cred.c | 6 +- src/libcharon/plugins/stroke/stroke_socket.c | 2 +- src/libcharon/plugins/vici/Makefile.am | 1 + src/libcharon/plugins/vici/vici_cred.c | 64 ++++++++++++++++++- src/libcharon/plugins/vici/vici_cred.h | 10 +++ src/libcharon/plugins/vici/vici_plugin.c | 4 +- .../crl-from-cache/hosts/moon/etc/ipsec.conf | 1 - .../hosts/moon/etc/strongswan.conf | 2 + .../crl-to-cache/hosts/moon/etc/ipsec.conf | 1 - .../hosts/moon/etc/strongswan.conf | 2 + .../swanctl/crl-to-cache/description.txt | 6 ++ .../tests/swanctl/crl-to-cache/evaltest.dat | 4 ++ .../hosts/carol/etc/strongswan.conf | 16 +++++ .../hosts/carol/etc/swanctl/swanctl.conf | 23 +++++++ .../hosts/moon/etc/strongswan.conf | 16 +++++ .../hosts/moon/etc/swanctl/swanctl.conf | 21 ++++++ .../tests/swanctl/crl-to-cache/posttest.dat | 5 ++ .../tests/swanctl/crl-to-cache/pretest.dat | 5 ++ testing/tests/swanctl/crl-to-cache/test.conf | 24 +++++++ 20 files changed, 213 insertions(+), 6 deletions(-) create mode 100644 testing/tests/swanctl/crl-to-cache/description.txt create mode 100644 testing/tests/swanctl/crl-to-cache/evaltest.dat create mode 100644 testing/tests/swanctl/crl-to-cache/hosts/carol/etc/strongswan.conf create mode 100755 testing/tests/swanctl/crl-to-cache/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/crl-to-cache/hosts/moon/etc/strongswan.conf create mode 100755 testing/tests/swanctl/crl-to-cache/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/crl-to-cache/posttest.dat create mode 100644 testing/tests/swanctl/crl-to-cache/pretest.dat create mode 100644 testing/tests/swanctl/crl-to-cache/test.conf diff --git a/conf/options/charon.opt b/conf/options/charon.opt index 04e099e12..6e0b37c57 100644 --- a/conf/options/charon.opt +++ b/conf/options/charon.opt @@ -30,6 +30,12 @@ charon.cert_cache = yes Whether relations in validated certificate chains should be cached in memory. +charon.cache_crls = no + Whether Certicate Revocation Lists (CRLs) fetched via HTTP or LDAP should + be saved under a unique file name derived from the public key of the + Certification Authority (CA) to **/etc/ipsec.d/crls** (stroke) or + **/etc/swanctl/x509crl** (vici), respectively. + charon.cisco_unity = no Send Cisco Unity vendor ID payload (IKEv1 only). diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c index 929e6fc84..44be512c0 100644 --- a/src/libcharon/plugins/stroke/stroke_cred.c +++ b/src/libcharon/plugins/stroke/stroke_cred.c @@ -562,7 +562,7 @@ static void load_certdir(private_stroke_cred_t *this, char *path, } } -METHOD(stroke_cred_t, cache_cert, void, +METHOD(credential_set_t, cache_cert, void, private_stroke_cred_t *this, certificate_t *cert) { if (cert->get_type(cert) == CERT_X509_CRL && this->cachecrl) @@ -1497,6 +1497,10 @@ stroke_cred_t *stroke_cred_create(stroke_ca_t *ca) .ca = ca, ); + if (lib->settings->get_bool(lib->settings, "%s.cache_crls", FALSE, lib->ns)) + { + cachecrl(this, TRUE); + } lib->credmgr->add_set(lib->credmgr, &this->creds->set); lib->credmgr->add_set(lib->credmgr, &this->aacerts->set); diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c index 4f7483666..46de90ca6 100644 --- a/src/libcharon/plugins/stroke/stroke_socket.c +++ b/src/libcharon/plugins/stroke/stroke_socket.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2011-2013 Tobias Brunner * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil + * HSR 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 diff --git a/src/libcharon/plugins/vici/Makefile.am b/src/libcharon/plugins/vici/Makefile.am index ca9b49906..af0b65cd0 100644 --- a/src/libcharon/plugins/vici/Makefile.am +++ b/src/libcharon/plugins/vici/Makefile.am @@ -2,6 +2,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ -I$(top_srcdir)/src/libstrongswan/plugins/pubkey \ -I$(top_srcdir)/src/libcharon \ + -DSWANCTLDIR=\""${swanctldir}\"" \ -DIPSEC_PIDDIR=\"${piddir}\" AM_CFLAGS = \ diff --git a/src/libcharon/plugins/vici/vici_cred.c b/src/libcharon/plugins/vici/vici_cred.c index 40ba57e98..453b743a1 100644 --- a/src/libcharon/plugins/vici/vici_cred.c +++ b/src/libcharon/plugins/vici/vici_cred.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Martin Willi * Copyright (C) 2014 revosec AG * - * Copyright (C) 2015 Andreas Steffen + * Copyright (C) 2015-2016 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -25,8 +25,15 @@ #include #include +#include + typedef struct private_vici_cred_t private_vici_cred_t; +/** + * Directory for saved X.509 CRLs + */ +#define CRL_DIR SWANCTLDIR "/x509crl" + /** * Private data of an vici_cred_t object. */ @@ -46,8 +53,51 @@ struct private_vici_cred_t { * credentials */ mem_cred_t *creds; + + /** + * cache CRLs to disk? + */ + bool cachecrl; + }; +METHOD(credential_set_t, cache_cert, void, + private_vici_cred_t *this, certificate_t *cert) +{ + if (cert->get_type(cert) == CERT_X509_CRL && this->cachecrl) + { + /* CRLs get written to /etc/swanctl/x509crl/.crl */ + crl_t *crl = (crl_t*)cert; + + cert->get_ref(cert); + if (this->creds->add_crl(this->creds, crl)) + { + char buf[BUF_LEN]; + chunk_t chunk, hex; + + chunk = crl->get_authKeyIdentifier(crl); + hex = chunk_to_hex(chunk, NULL, FALSE); + snprintf(buf, sizeof(buf), "%s/%s.crl", CRL_DIR, hex.ptr); + free(hex.ptr); + + if (cert->get_encoding(cert, CERT_ASN1_DER, &chunk)) + { + if (chunk_write(chunk, buf, 022, TRUE)) + { + DBG1(DBG_CFG, " written crl file '%s' (%d bytes)", + buf, chunk.len); + } + else + { + DBG1(DBG_CFG, " writing crl file '%s' failed: %s", + buf, strerror(errno)); + } + free(chunk.ptr); + } + } + } +} + /** * Create a (error) reply message */ @@ -349,6 +399,13 @@ vici_cred_t *vici_cred_create(vici_dispatcher_t *dispatcher) INIT(this, .public = { + .set = { + .create_private_enumerator = (void*)return_null, + .create_cert_enumerator = (void*)return_null, + .create_shared_enumerator = (void*)return_null, + .create_cdp_enumerator = (void*)return_null, + .cache_cert = (void*)_cache_cert, + }, .add_cert = _add_cert, .destroy = _destroy, }, @@ -356,6 +413,11 @@ vici_cred_t *vici_cred_create(vici_dispatcher_t *dispatcher) .creds = mem_cred_create(), ); + if (lib->settings->get_bool(lib->settings, "%s.cache_crls", FALSE, lib->ns)) + { + this->cachecrl = TRUE; + DBG1(DBG_CFG, "crl caching to %s enabled", CRL_DIR); + } lib->credmgr->add_set(lib->credmgr, &this->creds->set); manage_commands(this, TRUE); diff --git a/src/libcharon/plugins/vici/vici_cred.h b/src/libcharon/plugins/vici/vici_cred.h index 8359c0e88..6ce514786 100644 --- a/src/libcharon/plugins/vici/vici_cred.h +++ b/src/libcharon/plugins/vici/vici_cred.h @@ -2,6 +2,9 @@ * Copyright (C) 2014 Martin Willi * Copyright (C) 2014 revosec AG * + * Copyright (C) 2016 Andreas Steffen + * HSR 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 @@ -23,6 +26,8 @@ #include "vici_dispatcher.h" +#include + typedef struct vici_cred_t vici_cred_t; /** @@ -30,6 +35,11 @@ typedef struct vici_cred_t vici_cred_t; */ struct vici_cred_t { + /** + * Implements credential_set_t + */ + credential_set_t set; + /** * Add a certificate to the certificate store * diff --git a/src/libcharon/plugins/vici/vici_plugin.c b/src/libcharon/plugins/vici/vici_plugin.c index ed7c743c7..136651261 100644 --- a/src/libcharon/plugins/vici/vici_plugin.c +++ b/src/libcharon/plugins/vici/vici_plugin.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Martin Willi * Copyright (C) 2014 revosec AG * - * Copyright (C) 2015 Andreas Steffen + * Copyright (C) 2015-2016 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -130,6 +130,7 @@ static bool register_vici(private_vici_plugin_t *this, this->cred = vici_cred_create(this->dispatcher); this->authority = vici_authority_create(this->dispatcher, this->cred); + lib->credmgr->add_set(lib->credmgr, &this->cred->set); lib->credmgr->add_set(lib->credmgr, &this->authority->set); this->config = vici_config_create(this->dispatcher, this->authority, this->cred); @@ -158,6 +159,7 @@ static bool register_vici(private_vici_plugin_t *this, this->logger->destroy(this->logger); this->attrs->destroy(this->attrs); this->config->destroy(this->config); + lib->credmgr->remove_set(lib->credmgr, &this->cred->set); lib->credmgr->remove_set(lib->credmgr, &this->authority->set); this->authority->destroy(this->authority); this->cred->destroy(this->cred); diff --git a/testing/tests/ikev2/crl-from-cache/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/crl-from-cache/hosts/moon/etc/ipsec.conf index 3314f7538..d2137d969 100644 --- a/testing/tests/ikev2/crl-from-cache/hosts/moon/etc/ipsec.conf +++ b/testing/tests/ikev2/crl-from-cache/hosts/moon/etc/ipsec.conf @@ -2,7 +2,6 @@ config setup strictcrlpolicy=yes - cachecrls=yes conn %default ikelifetime=60m diff --git a/testing/tests/ikev2/crl-from-cache/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/crl-from-cache/hosts/moon/etc/strongswan.conf index 7014c369e..ea1b90593 100644 --- a/testing/tests/ikev2/crl-from-cache/hosts/moon/etc/strongswan.conf +++ b/testing/tests/ikev2/crl-from-cache/hosts/moon/etc/strongswan.conf @@ -2,4 +2,6 @@ charon { load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac xcbc stroke kernel-netlink socket-default + + cache_crls = yes } diff --git a/testing/tests/ikev2/crl-to-cache/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/crl-to-cache/hosts/moon/etc/ipsec.conf index 3314f7538..d2137d969 100644 --- a/testing/tests/ikev2/crl-to-cache/hosts/moon/etc/ipsec.conf +++ b/testing/tests/ikev2/crl-to-cache/hosts/moon/etc/ipsec.conf @@ -2,7 +2,6 @@ config setup strictcrlpolicy=yes - cachecrls=yes conn %default ikelifetime=60m diff --git a/testing/tests/ikev2/crl-to-cache/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/crl-to-cache/hosts/moon/etc/strongswan.conf index 7014c369e..ea1b90593 100644 --- a/testing/tests/ikev2/crl-to-cache/hosts/moon/etc/strongswan.conf +++ b/testing/tests/ikev2/crl-to-cache/hosts/moon/etc/strongswan.conf @@ -2,4 +2,6 @@ charon { load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac xcbc stroke kernel-netlink socket-default + + cache_crls = yes } diff --git a/testing/tests/swanctl/crl-to-cache/description.txt b/testing/tests/swanctl/crl-to-cache/description.txt new file mode 100644 index 000000000..9f542e73d --- /dev/null +++ b/testing/tests/swanctl/crl-to-cache/description.txt @@ -0,0 +1,6 @@ +By setting cachecrls=yes in ipsec.conf, a copy of the CRL fetched +via http from the web server winnetou is saved locally in the +directory /etc/ipsec.d/crls on both the roadwarrior carol +and the gateway moon when the IPsec connection is set up. The +subjectKeyIdentifier of the issuing CA plus the suffix .crl +is used as a unique filename for the cached CRL. diff --git a/testing/tests/swanctl/crl-to-cache/evaltest.dat b/testing/tests/swanctl/crl-to-cache/evaltest.dat new file mode 100644 index 000000000..1bdd666ba --- /dev/null +++ b/testing/tests/swanctl/crl-to-cache/evaltest.dat @@ -0,0 +1,4 @@ +carol::swanctl --list-sas --raw 2> /dev/null::home.*version=2 state=ESTABLISHED local-host=192.168.0.100 local-port=4500 local-id=carol@strongswan.org remote-host=192.168.0.1 remote-port=4500 remote-id=moon.strongswan.org initiator=yes.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=MODP_3072.*child-sas.*home.*state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128.*local-ts=\[192.168.0.100/32] remote-ts=\[10.1.0.0/16]::YES +moon:: swanctl --list-sas --ike-id 1 --raw 2> /dev/null::rw.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-port=4500 local-id=moon.strongswan.org remote-host=192.168.0.100 remote-port=4500 remote-id=carol@strongswan.org.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=MODP_3072.*child-sas.*net.*reqid=1 state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128.*local-ts=\[10.1.0.0/16] remote-ts=\[192.168.0.100/32]::YES +moon:: cat /var/log/daemon.log::written crl .*/etc/swanctl/x509crl/5da7dd700651327ee7b66db3b5e5e060ea2e4def.crl::YES +carol::cat /var/log/daemon.log::written crl .*/etc/swanctl/x509crl/5da7dd700651327ee7b66db3b5e5e060ea2e4def.crl::YES diff --git a/testing/tests/swanctl/crl-to-cache/hosts/carol/etc/strongswan.conf b/testing/tests/swanctl/crl-to-cache/hosts/carol/etc/strongswan.conf new file mode 100644 index 000000000..61ff4005b --- /dev/null +++ b/testing/tests/swanctl/crl-to-cache/hosts/carol/etc/strongswan.conf @@ -0,0 +1,16 @@ +# /etc/strongswan.conf - strongSwan configuration file + +swanctl { + load = pem pkcs1 x509 revocation constraints pubkey openssl random +} + +charon { + load = random nonce aes sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac kernel-netlink socket-default vici + + start-scripts { + creds = /usr/local/sbin/swanctl --load-creds + conns = /usr/local/sbin/swanctl --load-conns + } + + cache_crls = yes +} diff --git a/testing/tests/swanctl/crl-to-cache/hosts/carol/etc/swanctl/swanctl.conf b/testing/tests/swanctl/crl-to-cache/hosts/carol/etc/swanctl/swanctl.conf new file mode 100755 index 000000000..e84508d19 --- /dev/null +++ b/testing/tests/swanctl/crl-to-cache/hosts/carol/etc/swanctl/swanctl.conf @@ -0,0 +1,23 @@ +connections { + + home { + local_addrs = 192.168.0.100 + remote_addrs = 192.168.0.1 + + local { + auth = pubkey + certs = carolCert.pem + id = carol@strongswan.org + } + remote { + auth = pubkey + id = moon.strongswan.org + } + children { + home { + remote_ts = 10.1.0.0/16 + } + } + version = 2 + } +} diff --git a/testing/tests/swanctl/crl-to-cache/hosts/moon/etc/strongswan.conf b/testing/tests/swanctl/crl-to-cache/hosts/moon/etc/strongswan.conf new file mode 100644 index 000000000..61ff4005b --- /dev/null +++ b/testing/tests/swanctl/crl-to-cache/hosts/moon/etc/strongswan.conf @@ -0,0 +1,16 @@ +# /etc/strongswan.conf - strongSwan configuration file + +swanctl { + load = pem pkcs1 x509 revocation constraints pubkey openssl random +} + +charon { + load = random nonce aes sha1 sha2 pem pkcs1 gmp x509 curl revocation hmac kernel-netlink socket-default vici + + start-scripts { + creds = /usr/local/sbin/swanctl --load-creds + conns = /usr/local/sbin/swanctl --load-conns + } + + cache_crls = yes +} diff --git a/testing/tests/swanctl/crl-to-cache/hosts/moon/etc/swanctl/swanctl.conf b/testing/tests/swanctl/crl-to-cache/hosts/moon/etc/swanctl/swanctl.conf new file mode 100755 index 000000000..47dd36684 --- /dev/null +++ b/testing/tests/swanctl/crl-to-cache/hosts/moon/etc/swanctl/swanctl.conf @@ -0,0 +1,21 @@ +connections { + + rw { + local_addrs = 192.168.0.1 + + local { + auth = pubkey + certs = moonCert.pem + id = moon.strongswan.org + } + remote { + auth = pubkey + } + children { + net { + local_ts = 10.1.0.0/16 + } + } + version = 2 + } +} diff --git a/testing/tests/swanctl/crl-to-cache/posttest.dat b/testing/tests/swanctl/crl-to-cache/posttest.dat new file mode 100644 index 000000000..b0dd70323 --- /dev/null +++ b/testing/tests/swanctl/crl-to-cache/posttest.dat @@ -0,0 +1,5 @@ +carol::swanctl --terminate --ike home +carol::service charon stop 2> /dev/null +moon::service charon stop 2> /dev/null +moon::rm /etc/swanctl/x509crl/* +carol::rm /etc/swanctl/x509crl/* diff --git a/testing/tests/swanctl/crl-to-cache/pretest.dat b/testing/tests/swanctl/crl-to-cache/pretest.dat new file mode 100644 index 000000000..8f72f9cc7 --- /dev/null +++ b/testing/tests/swanctl/crl-to-cache/pretest.dat @@ -0,0 +1,5 @@ +moon::service charon start 2> /dev/null +carol::service charon start 2> /dev/null +moon::expect-connection rw +carol::expect-connection home +carol::swanctl --initiate --child home 2> /dev/null diff --git a/testing/tests/swanctl/crl-to-cache/test.conf b/testing/tests/swanctl/crl-to-cache/test.conf new file mode 100644 index 000000000..fdda0a04c --- /dev/null +++ b/testing/tests/swanctl/crl-to-cache/test.conf @@ -0,0 +1,24 @@ +#!/bin/bash +# +# This configuration file provides information on the +# guest instances used for this test + +# All guest instances that are required for this test +# +VIRTHOSTS="moon carol winnetou" + +# Corresponding block diagram +# +DIAGRAM="m-c-w.png" + +# Guest instances on which tcpdump is to be started +# +TCPDUMPHOSTS="" + +# Guest instances on which IPsec is started +# Used for IPsec logging purposes +# +IPSECHOSTS="moon carol" + +# charon controlled by swanctl +SWANCTL=1 From 85b5a6ace2a7c220c9ed54c1f5c1d33d9395a5cc Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Fri, 30 Sep 2016 08:05:20 +0200 Subject: [PATCH 6/6] Save both base and delta CRLs to disk --- src/libcharon/plugins/stroke/stroke_cred.c | 6 ++++- src/libcharon/plugins/vici/vici_cred.c | 5 ++++- .../hosts/winnetou/etc/openssl/generate-crl | 6 +++++ .../swanctl/crl-to-cache/description.txt | 14 +++++++----- .../tests/swanctl/crl-to-cache/evaltest.dat | 8 +++++-- .../carol/etc/swanctl/x509/carolCert.pem | 22 +++++++++++++++++++ .../hosts/moon/etc/swanctl/x509/moonCert.pem | 22 +++++++++++++++++++ .../tests/swanctl/crl-to-cache/posttest.dat | 1 - 8 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 testing/tests/swanctl/crl-to-cache/hosts/carol/etc/swanctl/x509/carolCert.pem create mode 100644 testing/tests/swanctl/crl-to-cache/hosts/moon/etc/swanctl/x509/moonCert.pem diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c index 44be512c0..77911c7b0 100644 --- a/src/libcharon/plugins/stroke/stroke_cred.c +++ b/src/libcharon/plugins/stroke/stroke_cred.c @@ -575,10 +575,14 @@ METHOD(credential_set_t, cache_cert, void, { char buf[BUF_LEN]; chunk_t chunk, hex; + bool is_delta_crl; + + is_delta_crl = crl->is_delta_crl(crl, NULL); chunk = crl->get_authKeyIdentifier(crl); hex = chunk_to_hex(chunk, NULL, FALSE); - snprintf(buf, sizeof(buf), "%s/%s.crl", CRL_DIR, hex.ptr); + snprintf(buf, sizeof(buf), "%s/%s%s.crl", CRL_DIR, hex.ptr, + is_delta_crl ? "_delta" : ""); free(hex.ptr); if (cert->get_encoding(cert, CERT_ASN1_DER, &chunk)) diff --git a/src/libcharon/plugins/vici/vici_cred.c b/src/libcharon/plugins/vici/vici_cred.c index 453b743a1..baf285fb8 100644 --- a/src/libcharon/plugins/vici/vici_cred.c +++ b/src/libcharon/plugins/vici/vici_cred.c @@ -74,10 +74,13 @@ METHOD(credential_set_t, cache_cert, void, { char buf[BUF_LEN]; chunk_t chunk, hex; + bool is_delta_crl; + is_delta_crl = crl->is_delta_crl(crl, NULL); chunk = crl->get_authKeyIdentifier(crl); hex = chunk_to_hex(chunk, NULL, FALSE); - snprintf(buf, sizeof(buf), "%s/%s.crl", CRL_DIR, hex.ptr); + snprintf(buf, sizeof(buf), "%s/%s%s.crl", CRL_DIR, hex.ptr, + is_delta_crl ? "_delta" : ""); free(hex.ptr); if (cert->get_encoding(cert, CERT_ASN1_DER, &chunk)) diff --git a/testing/hosts/winnetou/etc/openssl/generate-crl b/testing/hosts/winnetou/etc/openssl/generate-crl index 89534e422..1a375e051 100755 --- a/testing/hosts/winnetou/etc/openssl/generate-crl +++ b/testing/hosts/winnetou/etc/openssl/generate-crl @@ -31,6 +31,12 @@ 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} +# generate a base CRL +pki --signcrl --lastcrl strongswan.crl --cacert strongswanCert.der --cakey strongswanKey.pem --lifetime 30 --crluri http://crl.strongswan.org/strongswan_delta.crl --digest sha256 > strongswan_base.crl +cp strongswan_base.crl ${ROOT} +# generate a delta CRL revoking moon's current cert +pki --signcrl --basecrl strongswan_base.crl --reason key-compromise --cert newcerts/2B.pem --cacert strongswanCert.der --cakey strongswanKey.pem --lifetime 10 --digest sha256 > strongswan_delta.crl +cp strongswan_delta.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 diff --git a/testing/tests/swanctl/crl-to-cache/description.txt b/testing/tests/swanctl/crl-to-cache/description.txt index 9f542e73d..0e6f1cbd6 100644 --- a/testing/tests/swanctl/crl-to-cache/description.txt +++ b/testing/tests/swanctl/crl-to-cache/description.txt @@ -1,6 +1,8 @@ -By setting cachecrls=yes in ipsec.conf, a copy of the CRL fetched -via http from the web server winnetou is saved locally in the -directory /etc/ipsec.d/crls on both the roadwarrior carol -and the gateway moon when the IPsec connection is set up. The -subjectKeyIdentifier of the issuing CA plus the suffix .crl -is used as a unique filename for the cached CRL. +By setting cache_crls = yes in /etc/strongswan.conf, a copy of +both the base CRL and the latest delta CRL fetched via http from +the web server winnetou is saved locally in the directory +/etc/swanctl/x509crl on both the roadwarrior carol and the +gateway moon when the IPsec connection is set up. +The subjectKeyIdentifier of the issuing CA plus the suffixes +.crl and _delta.crl are used as unique filename for the +cached base CRL and delta CRL, respectively. diff --git a/testing/tests/swanctl/crl-to-cache/evaltest.dat b/testing/tests/swanctl/crl-to-cache/evaltest.dat index 1bdd666ba..fa61f19fb 100644 --- a/testing/tests/swanctl/crl-to-cache/evaltest.dat +++ b/testing/tests/swanctl/crl-to-cache/evaltest.dat @@ -1,4 +1,8 @@ -carol::swanctl --list-sas --raw 2> /dev/null::home.*version=2 state=ESTABLISHED local-host=192.168.0.100 local-port=4500 local-id=carol@strongswan.org remote-host=192.168.0.1 remote-port=4500 remote-id=moon.strongswan.org initiator=yes.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=MODP_3072.*child-sas.*home.*state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128.*local-ts=\[192.168.0.100/32] remote-ts=\[10.1.0.0/16]::YES -moon:: swanctl --list-sas --ike-id 1 --raw 2> /dev/null::rw.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-port=4500 local-id=moon.strongswan.org remote-host=192.168.0.100 remote-port=4500 remote-id=carol@strongswan.org.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=MODP_3072.*child-sas.*net.*reqid=1 state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128.*local-ts=\[10.1.0.0/16] remote-ts=\[192.168.0.100/32]::YES +carol::swanctl --list-sas --raw 2> /dev/null::home.*version=2 state=ESTABLISHED local-host=192.168.0.100 local-port=4500 local-id=carol@strongswan.org remote-host=192.168.0.1 remote-port=4500 remote-id=moon.strongswan.org::NO +moon:: swanctl --list-sas --ike-id 1 --raw 2> /dev/null::rw.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-port=4500 local-id=moon.strongswan.org remote-host=192.168.0.100 remote-port=4500 remote-id=carol@strongswan.org::NO moon:: cat /var/log/daemon.log::written crl .*/etc/swanctl/x509crl/5da7dd700651327ee7b66db3b5e5e060ea2e4def.crl::YES +moon:: cat /var/log/daemon.log::written crl .*/etc/swanctl/x509crl/5da7dd700651327ee7b66db3b5e5e060ea2e4def_delta.crl::YES carol::cat /var/log/daemon.log::written crl .*/etc/swanctl/x509crl/5da7dd700651327ee7b66db3b5e5e060ea2e4def.crl::YES +carol::cat /var/log/daemon.log::written crl .*/etc/swanctl/x509crl/5da7dd700651327ee7b66db3b5e5e060ea2e4def_delta.crl::YES +carol::cat /var/log/daemon.log::certificate was revoked::YES +carol::cat /var/log/daemon.log::no trusted RSA public key found for.*moon.strongswan.org::YES diff --git a/testing/tests/swanctl/crl-to-cache/hosts/carol/etc/swanctl/x509/carolCert.pem b/testing/tests/swanctl/crl-to-cache/hosts/carol/etc/swanctl/x509/carolCert.pem new file mode 100644 index 000000000..60c368794 --- /dev/null +++ b/testing/tests/swanctl/crl-to-cache/hosts/carol/etc/swanctl/x509/carolCert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDoDCCAoigAwIBAgIBMDANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJDSDEZ +MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS +b290IENBMB4XDTE0MDgyNzE1MDUzNloXDTE5MDgyNjE1MDUzNlowWjELMAkGA1UE +BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xETAPBgNVBAsTCFJlc2Vh +cmNoMR0wGwYDVQQDDBRjYXJvbEBzdHJvbmdzd2FuLm9yZzCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALfz1DcXyt/sOALi1IZ/RcuPa5m+4fiSST2wVWWr +lw3hUjeiwLfgoLrtKaGX4i+At82Zol2mdbEXFpO+9qxXliP2u0fexqP4mBuZus3E +LA82EOL0lQ2ahAi8O3qafkDMBSgvoeJpEwNe00Ugh53g7hT7dw8tSgcPGqQkWutI +IKT9T6e/HbHNjRtYlw9ZlHsp8gSYjg/Q6vV6ofttueMUD9NRv8w2Y76rnRRmUGf3 +GlNFFmgxZntCJRuYltnxV7VcCFoppyauYt/fPmjAxbPRuhHKacnzIzq83Ixf5fSj +MTlluGCfWFX/NGENXamBqChkRLHmuCHNexxRp9s2F1S10hECAwEAAaOBhTCBgjAf +BgNVHSMEGDAWgBRdp91wBlEyfue2bbO15eBg6i5N7zAfBgNVHREEGDAWgRRjYXJv +bEBzdHJvbmdzd2FuLm9yZzA+BgNVHR8ENzA1MDOgMaAvhi1odHRwOi8vY3JsLnN0 +cm9uZ3N3YW4ub3JnL3N0cm9uZ3N3YW5fYmFzZS5jcmwwDQYJKoZIhvcNAQELBQAD +ggEBABxfR7BK9IlDFdycldmYVfL2W2U/2b5tEZx/n943wEhc+AM+J1bba3yTeo61 +6AOEhO7QeaNnsAY9ZIRHfH827Lk1dWjub88ze/rS7qmozStF23Rzs4BimeiMQ6xI +f1hJA1OiNXja2/lLijprevBY824Cd2iEq8LdU+9PIstsYKoLaSD/Ohilk4PGHIqX +unhdasBKogtvS/PxKWSq+qdEFgHjM70uaf1Tx6QnPS9sqo/qxAQqxKOLstRmXRd6 +ojkTNWRO1miG1rOQkMcc4L2nbsb8nYFrUFLw7PjeJ1ugPL6R+tVjp32OWqCwvWtP +SGaAJ/regpHs89VLbTKz1ybcqhw= +-----END CERTIFICATE----- diff --git a/testing/tests/swanctl/crl-to-cache/hosts/moon/etc/swanctl/x509/moonCert.pem b/testing/tests/swanctl/crl-to-cache/hosts/moon/etc/swanctl/x509/moonCert.pem new file mode 100644 index 000000000..ce570cef7 --- /dev/null +++ b/testing/tests/swanctl/crl-to-cache/hosts/moon/etc/swanctl/x509/moonCert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDoDCCAoigAwIBAgIBKzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJDSDEZ +MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS +b290IENBMB4XDTE0MDgyNzE0NDQ1NloXDTE5MDgyNjE0NDQ1NlowRjELMAkGA1UE +BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xHDAaBgNVBAMTE21vb24u +c3Ryb25nc3dhbi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCk +fAX6xRdB0f5bBjN08zOmO7CEYa8eCyYFqHUhCw+x10v2BnKB6vOlMzW+9DiRtG68 +TdJlYt/24oRuJBX0gAGvzsv0kC9rnoQcgCJQy4bxaLNVsgoiFCVlzxLaYjABbQlz +oSaegm/2PoX+1UP37rG8wlvAcuLSHsFQ720FUs/LvZh4Y0FjoKhvgKs64U4nIAJ7 +MnuL29n5fM5+dem7uovQOBg/+faZo8QkYSK9MW6eQkP+YnwN5zItNBxyGwKPbXXw +Ey5/aqNWfhRY8IEG6HJgrnCwBMHUA14C2UV+Af7Cy4eNnC1Mmu7TmUYcFncXaFn0 +87ryFUdshlmPpIHxfjufAgMBAAGjgZkwgZYwHwYDVR0jBBgwFoAUXafdcAZRMn7n +tm2zteXgYOouTe8wHgYDVR0RBBcwFYITbW9vbi5zdHJvbmdzd2FuLm9yZzATBgNV +HSUEDDAKBggrBgEFBQcDATA+BgNVHR8ENzA1MDOgMaAvhi1odHRwOi8vY3JsLnN0 +cm9uZ3N3YW4ub3JnL3N0cm9uZ3N3YW5fYmFzZS5jcmwwDQYJKoZIhvcNAQELBQAD +ggEBAD7YFpbQoRC0nte5t/hpoaxiOwE4Wm+rKexOt8zbYhUc0Yrw6a89LELdqoa8 +vuSAxeHAUY4VmeWLOy7rSf/wURmjdMGO2su3Db+ZaOcrA8J5Oqxv3IAhdBcO4PUz +e0Lu2+f8RyKhKUQGpkSJBIlHhv0APN6TBX0R8cvvZ5XnFKj+GNd7fT4RN5Qjp+9H +f8kZboA3/Rg2+JcWOWgNu9sjqevoqjSJiDV8s3n5QO1VRZi32DAgSMAWWorDdKtd +uMPizLDy7W1nSQGf/vhXDkE95g689Md04dul6vAerCdsf389ckjthCIUqAPoLWn7 +XZnkIiV5xba29D9dTq0QElCzU+M= +-----END CERTIFICATE----- diff --git a/testing/tests/swanctl/crl-to-cache/posttest.dat b/testing/tests/swanctl/crl-to-cache/posttest.dat index b0dd70323..210685a90 100644 --- a/testing/tests/swanctl/crl-to-cache/posttest.dat +++ b/testing/tests/swanctl/crl-to-cache/posttest.dat @@ -1,4 +1,3 @@ -carol::swanctl --terminate --ike home carol::service charon stop 2> /dev/null moon::service charon stop 2> /dev/null moon::rm /etc/swanctl/x509crl/*