vici: Add support to load CA certificates from tokens and paths in authority sections

This commit is contained in:
Tobias Brunner
2017-02-16 19:24:08 +01:00
parent 2f8354ca6c
commit bd6ef6be7e
3 changed files with 130 additions and 21 deletions
+97 -10
View File
@@ -1,4 +1,5 @@
/* /*
* Copyright (C) 2016 Tobias Brunner
* Copyright (C) 2015 Andreas Steffen * Copyright (C) 2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil * HSR Hochschule fuer Technik Rapperswil
* *
@@ -199,8 +200,27 @@ typedef struct {
typedef struct { typedef struct {
request_data_t *request; request_data_t *request;
authority_t *authority; authority_t *authority;
char *handle;
uint32_t slot;
char *module;
char *file;
} load_data_t; } load_data_t;
/**
* Clean up data associated with an authority load
*/
static void free_load_data(load_data_t *data)
{
if (data->authority)
{
authority_destroy(data->authority);
}
free(data->handle);
free(data->module);
free(data->file);
free(data);
}
/** /**
* Parse a string * Parse a string
*/ */
@@ -216,6 +236,28 @@ CALLBACK(parse_string, bool,
return TRUE; return TRUE;
} }
/**
* Parse a uint32_t
*/
CALLBACK(parse_uint32, bool,
uint32_t *out, chunk_t v)
{
char buf[16], *end;
u_long l;
if (!vici_stringify(v, buf, sizeof(buf)))
{
return FALSE;
}
l = strtoul(buf, &end, 0);
if (*end == 0)
{
*out = l;
return TRUE;
}
return FALSE;
}
/** /**
* Parse list of URIs * Parse list of URIs
*/ */
@@ -266,8 +308,12 @@ CALLBACK(authority_kv, bool,
load_data_t *data, vici_message_t *message, char *name, chunk_t value) load_data_t *data, vici_message_t *message, char *name, chunk_t value)
{ {
parse_rule_t rules[] = { parse_rule_t rules[] = {
{ "cacert", parse_cacert, &data->authority->cert }, { "cacert", parse_cacert, &data->authority->cert },
{ "cert_uri_base", parse_string, &data->authority->cert_uri_base }, { "file", parse_string, &data->file },
{ "handle", parse_string, &data->handle },
{ "slot", parse_uint32, &data->slot },
{ "module", parse_string, &data->module },
{ "cert_uri_base", parse_string, &data->authority->cert_uri_base },
}; };
return parse_rules(rules, countof(rules), name, value, return parse_rules(rules, countof(rules), name, value,
@@ -341,21 +387,60 @@ CALLBACK(authority_sn, bool,
linked_list_t *authorities; linked_list_t *authorities;
authority_t *authority; authority_t *authority;
vici_cred_t *cred; vici_cred_t *cred;
load_data_t *data;
chunk_t handle;
load_data_t data = { INIT(data,
.request = request, .request = request,
.authority = authority_create(name), .authority = authority_create(name),
}; .slot = -1,
);
DBG2(DBG_CFG, " authority %s:", name); DBG2(DBG_CFG, " authority %s:", name);
if (!message->parse(message, ctx, NULL, authority_kv, authority_li, &data) || if (!message->parse(message, ctx, NULL, authority_kv, authority_li, data))
!data.authority->cert)
{ {
authority_destroy(data.authority); free_load_data(data);
return FALSE; return FALSE;
} }
log_authority_data(data.authority); if (!data->authority->cert)
{
if (data->file)
{
data->authority->cert = lib->creds->create(lib->creds,
CRED_CERTIFICATE, CERT_X509,
BUILD_FROM_FILE, data->file, BUILD_END);
}
else if (data->handle)
{
handle = chunk_from_hex(chunk_from_str(data->handle), NULL);
if (data->slot != -1)
{
data->authority->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
{
data->authority->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);
}
}
if (!data->authority->cert)
{
request->reply = create_reply("CA certificate missing: %s", name);
free_load_data(data);
return FALSE;
}
log_authority_data(data->authority);
request->this->lock->write_lock(request->this->lock); request->this->lock->write_lock(request->this->lock);
@@ -372,12 +457,14 @@ CALLBACK(authority_sn, bool,
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
authorities->insert_last(authorities, data.authority); authorities->insert_last(authorities, data->authority);
cred = request->this->cred; cred = request->this->cred;
data.authority->cert = cred->add_cert(cred, data.authority->cert); data->authority->cert = cred->add_cert(cred, data->authority->cert);
data->authority = NULL;
request->this->lock->unlock(request->this->lock); request->this->lock->unlock(request->this->lock);
free_load_data(data);
return TRUE; return TRUE;
} }
+4 -4
View File
@@ -86,18 +86,18 @@ static bool add_key_values(vici_req_t *req, settings_t *cfg, char *section)
enumerator = cfg->create_key_value_enumerator(cfg, section); enumerator = cfg->create_key_value_enumerator(cfg, section);
while (enumerator->enumerate(enumerator, &key, &value)) while (enumerator->enumerate(enumerator, &key, &value))
{ {
/* pool subnet is encoded as key/value, all other attributes as list */
if (streq(key, "cacert")) if (streq(key, "cacert"))
{ {
ret = add_file_key_value(req, key, value); ret = add_file_key_value(req, key, value);
} }
else if (streq(key, "cert_uri_base")) else if (streq(key, "crl_uris") ||
streq(key, "ocsp_uris"))
{ {
vici_add_key_valuef(req, key, "%s", value); add_list_key(req, key, value);
} }
else else
{ {
add_list_key(req, key, value); vici_add_key_valuef(req, key, "%s", value);
} }
if (!ret) if (!ret)
{ {
+29 -7
View File
@@ -1054,18 +1054,40 @@ authorities.<name> { # }
authorities.<name>.cacert = authorities.<name>.cacert =
CA certificate belonging to the certification authority. CA certificate belonging to the certification authority.
The certificates may use a relative path from the **swanctl** _x509ca_ CA certificate belonging to the certification authority. The certificates
directory or an absolute path. may use a relative path from the **swanctl** _x509ca_ directory or an
absolute path.
Configure one of _cacert_, _file_, or _handle_ per section.
authorities.<name>.file =
Absolute path to the certificate to load.
Absolute path to the certificate to load. Passed as-is to the daemon, so it
must be readable by it.
Configure one of _cacert_, _file_, or _handle_ per section.
authorities.<name>.handle =
Hex-encoded CKA_ID of the CA certificate on a token.
Hex-encoded CKA_ID of the CA certificate on a token.
Configure one of _cacert_, _file_, or _handle_ per section.
authorities.<name>.slot =
Optional slot number of the token that stores the CA certificate.
authorities.<name>.module =
Optional PKCS#11 module name.
authorities.<name>.crl_uris = authorities.<name>.crl_uris =
Comma-separated list of CRL distribution points Comma-separated list of CRL distribution points.
Comma-separated list of CRL distribution points (ldap, http, or file URI) Comma-separated list of CRL distribution points (ldap, http, or file URI).
authorities.<name>.ocsp_uris = authorities.<name>.ocsp_uris =
Comma-separated list of OCSP URIs Comma-separated list of OCSP URIs.
Comma-separated list of OCSP URIs
authorities.<name>.cert_uri_base = authorities.<name>.cert_uri_base =
Defines the base URI for the Hash and URL feature supported by IKEv2. Defines the base URI for the Hash and URL feature supported by IKEv2.