From: Andreas Steffen Date: Mon, 4 Jan 2016 09:34:21 +0000 (+0100) Subject: vici: Support of raw public keys X-Git-Tag: 5.4.0dr4~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=87371460f660e245bae49d60b5ed26e7b8c8e0b0;p=thirdparty%2Fstrongswan.git vici: Support of raw public keys --- diff --git a/src/libcharon/plugins/vici/Makefile.am b/src/libcharon/plugins/vici/Makefile.am index f51670de4b..5521283976 100644 --- a/src/libcharon/plugins/vici/Makefile.am +++ b/src/libcharon/plugins/vici/Makefile.am @@ -1,5 +1,6 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libstrongswan/plugins/pubkey \ -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c index 52e4a92045..b0615df5ba 100644 --- a/src/libcharon/plugins/vici/vici_config.c +++ b/src/libcharon/plugins/vici/vici_config.c @@ -48,6 +48,8 @@ #include #include +#include + #include /** @@ -97,6 +99,11 @@ struct private_vici_config_t { */ rwlock_t *lock; + /** + * Credential backend managed by VICI used for our certificates + */ + vici_cred_t *cred; + /** * Auxiliary certification authority information */ @@ -1057,6 +1064,7 @@ CALLBACK(parse_group, bool, static bool parse_cert(auth_data_t *auth, auth_rule_t rule, chunk_t v) { vici_authority_t *authority; + vici_cred_t *cred; certificate_t *cert; cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, @@ -1068,6 +1076,8 @@ static bool parse_cert(auth_data_t *auth, auth_rule_t rule, chunk_t v) authority = auth->request->this->authority; authority->check_for_hash_and_url(authority, cert); } + cred = auth->request->this->cred; + cert = cred->add_cert(cred, cert); auth->cfg->add(auth->cfg, rule, cert); return TRUE; } @@ -1092,6 +1102,27 @@ CALLBACK(parse_cacerts, bool, return parse_cert(auth, AUTH_RULE_CA_CERT, v); } +/** + * Parse raw public keys + */ +CALLBACK(parse_pubkeys, bool, + auth_data_t *auth, chunk_t v) +{ + vici_cred_t *cred; + certificate_t *cert; + + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY, + BUILD_BLOB_PEM, v, BUILD_END); + if (cert) + { + cred = auth->request->this->cred; + cert = cred->add_cert(cred, cert); + auth->cfg->add(auth->cfg, AUTH_RULE_SUBJECT_CERT, cert); + return TRUE; + } + return FALSE; +} + /** * Parse revocation status */ @@ -1287,6 +1318,7 @@ CALLBACK(auth_li, bool, { "groups", parse_group, auth->cfg }, { "certs", parse_certs, auth }, { "cacerts", parse_cacerts, auth }, + { "pubkeys", parse_pubkeys, auth }, }; return parse_rules(rules, countof(rules), name, value, @@ -1510,20 +1542,32 @@ CALLBACK(peer_sn, bool, .request = peer->request, .cfg = auth_cfg_create(), }; + certificate_t *cert; + identification_t *id; if (!message->parse(message, ctx, NULL, auth_kv, auth_li, &auth)) { auth.cfg->destroy(auth.cfg); return FALSE; } + cert = auth.cfg->get(auth.cfg, AUTH_RULE_SUBJECT_CERT); + id = auth.cfg->get(auth.cfg, AUTH_RULE_IDENTITY); - if (!auth.cfg->get(auth.cfg, AUTH_RULE_IDENTITY)) + if (cert) { - identification_t *id; - certificate_t *cert; + if (id) + { + if (cert->get_type(cert) == CERT_TRUSTED_PUBKEY && + id->get_type != ID_ANY) + { + pubkey_cert_t *pubkey_cert; - cert = auth.cfg->get(auth.cfg, AUTH_RULE_SUBJECT_CERT); - if (cert) + /* the id is set for informational purposes, only */ + pubkey_cert = (pubkey_cert_t*)cert; + pubkey_cert->set_subject(pubkey_cert, id); + } + } + else { id = cert->get_subject(cert); DBG1(DBG_CFG, " id not specified, defaulting to cert id '%Y'", @@ -2121,7 +2165,8 @@ METHOD(vici_config_t, destroy, void, * See header */ vici_config_t *vici_config_create(vici_dispatcher_t *dispatcher, - vici_authority_t *authority) + vici_authority_t *authority, + vici_cred_t *cred) { private_vici_config_t *this; @@ -2138,6 +2183,7 @@ vici_config_t *vici_config_create(vici_dispatcher_t *dispatcher, .conns = linked_list_create(), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), .authority = authority, + .cred = cred, ); manage_commands(this, TRUE); diff --git a/src/libcharon/plugins/vici/vici_config.h b/src/libcharon/plugins/vici/vici_config.h index c3245bf5ca..0c237e7ded 100644 --- a/src/libcharon/plugins/vici/vici_config.h +++ b/src/libcharon/plugins/vici/vici_config.h @@ -26,6 +26,7 @@ #include "vici_dispatcher.h" #include "vici_authority.h" +#include "vici_cred.h" #include @@ -51,9 +52,11 @@ struct vici_config_t { * * @param dispatcher dispatcher to receive requests from * @param authority Auxiliary certification authority information + * @param cred in-memory credential backend managed by VICI * @return config backend */ vici_config_t *vici_config_create(vici_dispatcher_t *dispatcher, - vici_authority_t *authority); + vici_authority_t *authority, + vici_cred_t *cred); #endif /** VICI_CONFIG_H_ @}*/ diff --git a/src/libcharon/plugins/vici/vici_cred.c b/src/libcharon/plugins/vici/vici_cred.c index fa3158fa9a..3411b7d6cc 100644 --- a/src/libcharon/plugins/vici/vici_cred.c +++ b/src/libcharon/plugins/vici/vici_cred.c @@ -308,7 +308,7 @@ static void manage_commands(private_vici_cred_t *this, bool reg) METHOD(vici_cred_t, add_cert, certificate_t*, private_vici_cred_t *this, certificate_t *cert) { - return this->creds->get_cert_ref(this->creds, cert); + return this->creds->add_cert_ref(this->creds, TRUE, cert); } METHOD(vici_cred_t, destroy, void, diff --git a/src/libcharon/plugins/vici/vici_plugin.c b/src/libcharon/plugins/vici/vici_plugin.c index 53ed8cdfb6..ed7c743c7a 100644 --- a/src/libcharon/plugins/vici/vici_plugin.c +++ b/src/libcharon/plugins/vici/vici_plugin.c @@ -131,7 +131,8 @@ static bool register_vici(private_vici_plugin_t *this, this->authority = vici_authority_create(this->dispatcher, this->cred); lib->credmgr->add_set(lib->credmgr, &this->authority->set); - this->config = vici_config_create(this->dispatcher, this->authority); + this->config = vici_config_create(this->dispatcher, this->authority, + this->cred); this->attrs = vici_attribute_create(this->dispatcher); this->logger = vici_logger_create(this->dispatcher); diff --git a/src/libstrongswan/plugins/pubkey/pubkey_cert.c b/src/libstrongswan/plugins/pubkey/pubkey_cert.c index b7ba5ad431..0631a68575 100644 --- a/src/libstrongswan/plugins/pubkey/pubkey_cert.c +++ b/src/libstrongswan/plugins/pubkey/pubkey_cert.c @@ -196,6 +196,13 @@ METHOD(certificate_t, destroy, void, } } +METHOD(pubkey_cert_t, set_subject, void, + private_pubkey_cert_t *this, identification_t *subject) +{ + DESTROY_IF(this->subject); + this->subject = subject->clone(subject); +} + /* * see header file */ @@ -222,6 +229,7 @@ static pubkey_cert_t *pubkey_cert_create(public_key_t *key, .get_ref = _get_ref, .destroy = _destroy, }, + .set_subject = _set_subject, }, .ref = 1, .key = key, diff --git a/src/libstrongswan/plugins/pubkey/pubkey_cert.h b/src/libstrongswan/plugins/pubkey/pubkey_cert.h index a2d7353429..06e4e0fa34 100644 --- a/src/libstrongswan/plugins/pubkey/pubkey_cert.h +++ b/src/libstrongswan/plugins/pubkey/pubkey_cert.h @@ -35,6 +35,13 @@ struct pubkey_cert_t { * Implements certificate_t. */ certificate_t interface; + + /** + * Set the subject of the trusted public key. + * + * @param subject subject to be set + */ + void (*set_subject)(pubkey_cert_t *this, identification_t *subject); }; /** diff --git a/src/swanctl/commands/load_conns.c b/src/swanctl/commands/load_conns.c index 6ee8b8785b..bbc700d5cd 100644 --- a/src/swanctl/commands/load_conns.c +++ b/src/swanctl/commands/load_conns.c @@ -59,6 +59,7 @@ static bool is_file_list_key(char *key) char *keys[] = { "certs", "cacerts", + "pubkeys" }; int i; @@ -112,12 +113,18 @@ static bool add_file_list_key(vici_req_t *req, char *key, char *value) SWANCTL_X509DIR, DIRECTORY_SEPARATOR, token); token = buf; } - if (streq(key, "cacerts")) + else if (streq(key, "cacerts")) { snprintf(buf, sizeof(buf), "%s%s%s", SWANCTL_X509CADIR, DIRECTORY_SEPARATOR, token); token = buf; } + else if (streq(key, "pubkeys")) + { + snprintf(buf, sizeof(buf), "%s%s%s", + SWANCTL_PUBKEYDIR, DIRECTORY_SEPARATOR, token); + token = buf; + } } map = chunk_map(token, FALSE); diff --git a/src/swanctl/swanctl.opt b/src/swanctl/swanctl.opt index 591204ef88..5f8a1867b8 100644 --- a/src/swanctl/swanctl.opt +++ b/src/swanctl/swanctl.opt @@ -273,12 +273,22 @@ connections..local.certs = Comma separated list of certificate candidates to use for authentication. The certificates may use a relative path from the **swanctl** _x509_ - directory, or an absolute path. + directory or an absolute path. The certificate used for authentication is selected based on the received certificate request payloads. If no appropriate CA can be located, the first certificate is used. +connections..local.pubkeys = + Comma separated list of raw public key candidates to use for authentication. + + Comma separated list of raw public key candidates to use for authentication. + The public keys may use a relative path from the **swanctl** _pubkey_ + directory or an absolute path. + + Even though multiple local public keys could be defined in principle, only + the first public key in the list is used for authentication. + connections..local.auth = pubkey Authentication to perform locally (_pubkey_, _psk_, _xauth[-backend]_ or _eap[-method]_). @@ -370,14 +380,21 @@ connections..remote.certs = Comma separated list of certificates to accept for authentication. The certificates may use a relative path from the **swanctl** _x509_ - directory, or an absolute path. + directory or an absolute path. connections..remote.cacerts = Comma separated list of CA certificates to accept for authentication. Comma separated list of CA certificates to accept for authentication. The certificates may use a relative path from the **swanctl** _x509ca_ - directory, or an absolute path. + directory or an absolute path. + +connections..remote.pubkeys = + Comma separated list of raw public keys to accept for authentication. + + Comma separated list of raw public keys to accept for authentication. + The public keys may use a relative path from the **swanctl** _x509_ + directory or an absolute path. connections..remote.revocation = relaxed Certificate revocation policy, (_strict_, _ifuri_ or _relaxed_). @@ -587,8 +604,8 @@ connections..children..mode = tunnel Both _transport_ and _beet_ modes are subject to mode negotiation; _tunnel_ mode is negotiated if the preferred mode is not available. - _pass_ and _drop_ are used to install shunt policies, which explicitly - bypass the defined traffic from IPsec processing, or drop it, respectively. + _pass_ and _drop_ are used to install shunt policies which explicitly + bypass the defined traffic from IPsec processing or drop it, respectively. connections..children..policies = yes Whether to install IPsec policies or not. @@ -704,7 +721,7 @@ secrets { # } It is not recommended to define any private key decryption passphrases, as then there is no real security benefit in having encrypted keys. Either - store the key unencrypted, or enter the keys manually when loading + store the key unencrypted or enter the keys manually when loading credentials. secrets.eap { # } @@ -725,7 +742,7 @@ secrets.eap.secret = Value of the EAP/XAuth secret. Value of the EAP/XAuth secret. It may either be an ASCII string, a hex - encoded string if it has a _0x_ prefix, or a Base64 encoded string if it + encoded string if it has a _0x_ prefix or a Base64 encoded string if it has a _0s_ prefix in its value. secrets.eap.id = @@ -745,7 +762,7 @@ secrets.ike.secret = Value of the IKE preshared secret. Value of the IKE preshared secret. It may either be an ASCII string, - a hex encoded string if it has a _0x_ prefix, or a Base64 encoded string if + a hex encoded string if it has a _0x_ prefix or a Base64 encoded string if it has a _0s_ prefix in its value. secrets.ike.id = @@ -805,7 +822,7 @@ pools..addrs = Addresses allocated in pool. Subnet or range defining addresses allocated in pool. Accepts a single CIDR - subnet defining the pool to allocate addresses from, or an address range + subnet defining the pool to allocate addresses from or an address range (-). Pools must be unique and non-overlapping. pools.. = @@ -828,7 +845,7 @@ authorities..cacert = CA certificate belonging to the certification authority. The certificates may use a relative path from the **swanctl** _x509ca_ - directory, or an absolute path. + directory or an absolute path. authorities..crl_uris = Comma-separated list of CRL distribution points