diff options
author | Tobias Brunner <tobias@strongswan.org> | 2016-11-30 12:44:51 +0100 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2017-02-16 19:24:08 +0100 |
commit | 00bf6a2a492308874c86f909796c5871b94c0568 (patch) | |
tree | dc9b5151a090f581551e9e0af5152ef6e3e7f8f0 | |
parent | d2e3ff8e0c1a9e1382c9bd7424690c800958c112 (diff) | |
download | strongswan-00bf6a2a492308874c86f909796c5871b94c0568.tar.bz2 strongswan-00bf6a2a492308874c86f909796c5871b94c0568.tar.xz |
vici: Add support to load certificates from tokens
-rw-r--r-- | src/libcharon/plugins/vici/vici_config.c | 127 | ||||
-rw-r--r-- | src/swanctl/swanctl.opt | 48 |
2 files changed, 163 insertions, 12 deletions
diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c index 3b27bf7c3..0a8fc2905 100644 --- a/src/libcharon/plugins/vici/vici_config.c +++ b/src/libcharon/plugins/vici/vici_config.c @@ -247,6 +247,26 @@ typedef struct { } request_data_t; /** + * Certificate data + */ +typedef struct { + request_data_t *request; + char *handle; + uint32_t slot; + char *module; +} cert_data_t; + +/** + * Clean up certificate data + */ +static void free_cert_data(cert_data_t *data) +{ + free(data->handle); + free(data->module); + free(data); +} + +/** * Auth config data */ typedef struct { @@ -1161,27 +1181,36 @@ CALLBACK(parse_cert_policy, bool, } /** - * Parse a certificate; add as auth rule to config + * Add a certificate as auth rule to config */ -static bool parse_cert(auth_data_t *auth, auth_rule_t rule, chunk_t v) +static bool add_cert(auth_data_t *auth, auth_rule_t rule, certificate_t *cert) { vici_authority_t *authority; vici_cred_t *cred; + + if (rule == AUTH_RULE_SUBJECT_CERT) + { + 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; +} + +/** + * Parse a certificate; add as auth rule to config + */ +static bool parse_cert(auth_data_t *auth, auth_rule_t rule, chunk_t v) +{ certificate_t *cert; cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_BLOB_PEM, v, BUILD_END); if (cert) { - if (rule == AUTH_RULE_SUBJECT_CERT) - { - 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; + return add_cert(auth, rule, cert); } return FALSE; } @@ -1366,6 +1395,19 @@ CALLBACK(parse_hosts, bool, return TRUE; } +CALLBACK(cert_kv, bool, + cert_data_t *cert, vici_message_t *message, char *name, chunk_t value) +{ + parse_rule_t rules[] = { + { "handle", parse_string, &cert->handle }, + { "slot", parse_uint32, &cert->slot }, + { "module", parse_string, &cert->module }, + }; + + return parse_rules(rules, countof(rules), name, value, + &cert->request->reply); +} + CALLBACK(child_li, bool, child_data_t *child, vici_message_t *message, char *name, chunk_t value) { @@ -1492,6 +1534,67 @@ CALLBACK(peer_kv, bool, &peer->request->reply); } +CALLBACK(auth_sn, bool, + auth_data_t *auth, vici_message_t *message, vici_parse_context_t *ctx, + char *name) +{ + if (strcasepfx(name, "cert") || + strcasepfx(name, "cacert")) + { + cert_data_t *data; + auth_rule_t rule; + certificate_t *cert; + chunk_t handle; + + INIT(data, + .request = auth->request, + .slot = -1, + ); + + if (!message->parse(message, ctx, NULL, cert_kv, NULL, data)) + { + free_cert_data(data); + return FALSE; + } + if (!data->handle) + { + auth->request->reply = create_reply("CKA_ID missing: %s", name); + free_cert_data(data); + return FALSE; + } + + handle = chunk_from_hex(chunk_from_str(data->handle), NULL); + if (data->slot != -1) + { + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_PKCS11_KEYID, handle, + BUILD_PKCS11_SLOT, data->slot, + data->module ? BUILD_PKCS11_MODULE : BUILD_END, + data->module, BUILD_END); + } + else + { + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_PKCS11_KEYID, handle, + data->module ? BUILD_PKCS11_MODULE : BUILD_END, + data->module, BUILD_END); + } + chunk_free(&handle); + free_cert_data(data); + if (!cert) + { + auth->request->reply = create_reply("unable to load certificate: " + "%s", name); + return FALSE; + } + rule = strcasepfx(name, "cert") ? AUTH_RULE_SUBJECT_CERT + : AUTH_RULE_CA_CERT; + return add_cert(auth, rule, cert); + } + auth->request->reply = create_reply("invalid section: %s", name); + return FALSE; +} + /** * Check and update lifetimes */ @@ -1654,7 +1757,7 @@ CALLBACK(peer_sn, bool, .cfg = auth_cfg_create(), ); - if (!message->parse(message, ctx, NULL, auth_kv, auth_li, auth)) + if (!message->parse(message, ctx, auth_sn, auth_kv, auth_li, auth)) { free_auth_data(auth); return FALSE; diff --git a/src/swanctl/swanctl.opt b/src/swanctl/swanctl.opt index caae41e88..0bf1243d0 100644 --- a/src/swanctl/swanctl.opt +++ b/src/swanctl/swanctl.opt @@ -292,6 +292,22 @@ connections.<conn>.local<suffix>.certs = certificate request payloads. If no appropriate CA can be located, the first certificate is used. +connections.<conn>.local<suffix>.cert<suffix> = + Section for a certificate candidate to use for authentication. + + Section for a certificate candidate to use for authentication. Certificates + in _certs_ are transmitted as binary blobs, these sections offer more + flexibility. + +connections.<conn>.local<suffix>.cert<suffix>.handle = + Hex-encoded CKA_ID of the certificate on a token. + +connections.<conn>.local<suffix>.cert<suffix>.slot = + Optional slot number of the token that stores the certificate. + +connections.<conn>.local<suffix>.cert<suffix>.module = + Optional PKCS#11 module name. + connections.<conn>.local<suffix>.pubkeys = Comma separated list of raw public key candidates to use for authentication. @@ -419,6 +435,22 @@ connections.<conn>.remote<suffix>.certs = The certificates may use a relative path from the **swanctl** _x509_ directory or an absolute path. +connections.<conn>.remote<suffix>.cert<suffix> = + Section for a certificate to accept for authentication. + + Section for a certificate to accept for authentication. Certificates + in _certs_ are transmitted as binary blobs, these sections offer more + flexibility. + +connections.<conn>.remote<suffix>.cert<suffix>.handle = + Hex-encoded CKA_ID of the certificate on a token. + +connections.<conn>.remote<suffix>.cert<suffix>.slot = + Optional slot number of the token that stores the certificate. + +connections.<conn>.remote<suffix>.cert<suffix>.module = + Optional PKCS#11 module name. + connections.<conn>.remote<suffix>.cacerts = Comma separated list of CA certificates to accept for authentication. @@ -426,6 +458,22 @@ connections.<conn>.remote<suffix>.cacerts = The certificates may use a relative path from the **swanctl** _x509ca_ directory or an absolute path. +connections.<conn>.remote<suffix>.cacert<suffix> = + Section for a CA certificate to accept for authentication. + + Section for a CA certificate to accept for authentication. Certificates + in _cacerts_ are transmitted as binary blobs, these sections offer more + flexibility. + +connections.<conn>.remote<suffix>.cacert<suffix>.handle = + Hex-encoded CKA_ID of the CA certificate on a token. + +connections.<conn>.remote<suffix>.cacert<suffix>.slot = + Optional slot number of the token that stores the CA certificate. + +connections.<conn>.remote<suffix>.cacert<suffix>.module = + Optional PKCS#11 module name. + connections.<conn>.remote<suffix>.pubkeys = Comma separated list of raw public keys to accept for authentication. |