vici: Add support to load CA certificates from tokens and paths in authority sections
This commit is contained in:
parent
2f8354ca6c
commit
bd6ef6be7e
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Tobias Brunner
|
||||
* Copyright (C) 2015 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
|
@ -199,8 +200,27 @@ typedef struct {
|
|||
typedef struct {
|
||||
request_data_t *request;
|
||||
authority_t *authority;
|
||||
char *handle;
|
||||
uint32_t slot;
|
||||
char *module;
|
||||
char *file;
|
||||
} 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
|
||||
*/
|
||||
|
@ -216,6 +236,28 @@ CALLBACK(parse_string, bool,
|
|||
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
|
||||
*/
|
||||
|
@ -266,8 +308,12 @@ CALLBACK(authority_kv, bool,
|
|||
load_data_t *data, vici_message_t *message, char *name, chunk_t value)
|
||||
{
|
||||
parse_rule_t rules[] = {
|
||||
{ "cacert", parse_cacert, &data->authority->cert },
|
||||
{ "cert_uri_base", parse_string, &data->authority->cert_uri_base },
|
||||
{ "cacert", parse_cacert, &data->authority->cert },
|
||||
{ "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,
|
||||
|
@ -341,21 +387,60 @@ CALLBACK(authority_sn, bool,
|
|||
linked_list_t *authorities;
|
||||
authority_t *authority;
|
||||
vici_cred_t *cred;
|
||||
load_data_t *data;
|
||||
chunk_t handle;
|
||||
|
||||
load_data_t data = {
|
||||
INIT(data,
|
||||
.request = request,
|
||||
.authority = authority_create(name),
|
||||
};
|
||||
.slot = -1,
|
||||
);
|
||||
|
||||
DBG2(DBG_CFG, " authority %s:", name);
|
||||
|
||||
if (!message->parse(message, ctx, NULL, authority_kv, authority_li, &data) ||
|
||||
!data.authority->cert)
|
||||
if (!message->parse(message, ctx, NULL, authority_kv, authority_li, data))
|
||||
{
|
||||
authority_destroy(data.authority);
|
||||
free_load_data(data);
|
||||
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);
|
||||
|
||||
|
@ -372,12 +457,14 @@ CALLBACK(authority_sn, bool,
|
|||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
authorities->insert_last(authorities, data.authority);
|
||||
authorities->insert_last(authorities, data->authority);
|
||||
|
||||
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);
|
||||
free_load_data(data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
while (enumerator->enumerate(enumerator, &key, &value))
|
||||
{
|
||||
/* pool subnet is encoded as key/value, all other attributes as list */
|
||||
if (streq(key, "cacert"))
|
||||
{
|
||||
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
|
||||
{
|
||||
add_list_key(req, key, value);
|
||||
vici_add_key_valuef(req, key, "%s", value);
|
||||
}
|
||||
if (!ret)
|
||||
{
|
||||
|
|
|
@ -1054,18 +1054,40 @@ authorities.<name> { # }
|
|||
authorities.<name>.cacert =
|
||||
CA certificate belonging to the certification authority.
|
||||
|
||||
The certificates may use a relative path from the **swanctl** _x509ca_
|
||||
directory or an absolute path.
|
||||
CA certificate belonging to the certification authority. The certificates
|
||||
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 =
|
||||
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 =
|
||||
Comma-separated list of OCSP URIs
|
||||
|
||||
Comma-separated list of OCSP URIs
|
||||
Comma-separated list of OCSP URIs.
|
||||
|
||||
authorities.<name>.cert_uri_base =
|
||||
Defines the base URI for the Hash and URL feature supported by IKEv2.
|
||||
|
|
Loading…
Reference in New Issue