vici: Add support to load certificates from tokens
This commit is contained in:
@@ -246,6 +246,26 @@ typedef struct {
|
|||||||
vici_message_t *reply;
|
vici_message_t *reply;
|
||||||
} request_data_t;
|
} 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
|
* Auth config data
|
||||||
*/
|
*/
|
||||||
@@ -1160,28 +1180,37 @@ CALLBACK(parse_cert_policy, bool,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a certificate as auth rule to config
|
||||||
|
*/
|
||||||
|
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
|
* Parse a certificate; add as auth rule to config
|
||||||
*/
|
*/
|
||||||
static bool parse_cert(auth_data_t *auth, auth_rule_t rule, chunk_t v)
|
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;
|
certificate_t *cert;
|
||||||
|
|
||||||
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||||
BUILD_BLOB_PEM, v, BUILD_END);
|
BUILD_BLOB_PEM, v, BUILD_END);
|
||||||
if (cert)
|
if (cert)
|
||||||
{
|
{
|
||||||
if (rule == AUTH_RULE_SUBJECT_CERT)
|
return add_cert(auth, rule, 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 FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1366,6 +1395,19 @@ CALLBACK(parse_hosts, bool,
|
|||||||
return TRUE;
|
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,
|
CALLBACK(child_li, bool,
|
||||||
child_data_t *child, vici_message_t *message, char *name, chunk_t value)
|
child_data_t *child, vici_message_t *message, char *name, chunk_t value)
|
||||||
{
|
{
|
||||||
@@ -1492,6 +1534,67 @@ CALLBACK(peer_kv, bool,
|
|||||||
&peer->request->reply);
|
&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
|
* Check and update lifetimes
|
||||||
*/
|
*/
|
||||||
@@ -1654,7 +1757,7 @@ CALLBACK(peer_sn, bool,
|
|||||||
.cfg = auth_cfg_create(),
|
.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);
|
free_auth_data(auth);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|||||||
@@ -292,6 +292,22 @@ connections.<conn>.local<suffix>.certs =
|
|||||||
certificate request payloads. If no appropriate CA can be located, the
|
certificate request payloads. If no appropriate CA can be located, the
|
||||||
first certificate is used.
|
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 =
|
connections.<conn>.local<suffix>.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.
|
||||||
|
|
||||||
@@ -419,6 +435,22 @@ connections.<conn>.remote<suffix>.certs =
|
|||||||
The certificates may use a relative path from the **swanctl** _x509_
|
The certificates may use a relative path from the **swanctl** _x509_
|
||||||
directory or an absolute path.
|
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 =
|
connections.<conn>.remote<suffix>.cacerts =
|
||||||
Comma separated list of CA certificates to accept for authentication.
|
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_
|
The certificates may use a relative path from the **swanctl** _x509ca_
|
||||||
directory or an absolute path.
|
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 =
|
connections.<conn>.remote<suffix>.pubkeys =
|
||||||
Comma separated list of raw public keys to accept for authentication.
|
Comma separated list of raw public keys to accept for authentication.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user