vici: Add support to load CA certificates from tokens and paths in authority sections
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user