stroke: Load credentials from PKCS#12 files (P12 token)
This commit is contained in:
parent
904390e887
commit
7971278c92
|
@ -91,6 +91,9 @@ defines an RSA private key
|
|||
.B ECDSA
|
||||
defines an ECDSA private key
|
||||
.TP
|
||||
.B P12
|
||||
defines a PKCS#12 container
|
||||
.TP
|
||||
.B EAP
|
||||
defines EAP credentials
|
||||
.TP
|
||||
|
@ -133,16 +136,26 @@ Similarly, a character sequence beginning with
|
|||
.B 0s
|
||||
is interpreted as Base64 encoded binary data.
|
||||
.TP
|
||||
.B [ <selectors> ] : RSA <private key file> [ <passphrase> | %prompt ]
|
||||
.B : RSA <private key file> [ <passphrase> | %prompt ]
|
||||
.TQ
|
||||
.B [ <selectors> ] : ECDSA <private key file> [ <passphrase> | %prompt ]
|
||||
.B : ECDSA <private key file> [ <passphrase> | %prompt ]
|
||||
For the private key file both absolute paths or paths relative to
|
||||
\fI/etc/ipsec.d/private\fP are accepted. If the private key file is
|
||||
encrypted, the \fIpassphrase\fP must be defined. Instead of a passphrase
|
||||
.B %prompt
|
||||
can be used which then causes the daemons to ask the user for the password
|
||||
can be used which then causes the daemon to ask the user for the password
|
||||
whenever it is required to decrypt the key.
|
||||
.TP
|
||||
.B : P12 <PKCS#12 file> [ <passphrase> | %prompt ]
|
||||
For the PKCS#12 file both absolute paths or paths relative to
|
||||
\fI/etc/ipsec.d/private\fP are accepted. If the container is
|
||||
encrypted, the \fIpassphrase\fP must be defined. Instead of a passphrase
|
||||
.B %prompt
|
||||
can be used which then causes the daemon to ask the user for the password
|
||||
whenever it is required to decrypt the container. Private keys, client and CA
|
||||
certificates are extracted from the container. To use such a client certificate
|
||||
in a connection set leftid to one of the subjects of the certificate.
|
||||
.TP
|
||||
.B <user id> : EAP <secret>
|
||||
The format of \fIsecret\fP is the same as that of \fBPSK\fP secrets.
|
||||
.br
|
||||
|
@ -165,7 +178,7 @@ key. The slot number defines the slot on the token, the module name refers to
|
|||
the module name defined in strongswan.conf(5).
|
||||
Instead of specifying the pin code statically,
|
||||
.B %prompt
|
||||
can be specified, which causes the daemons to ask the user for the pin code.
|
||||
can be specified, which causes the daemon to ask the user for the pin code.
|
||||
.LP
|
||||
|
||||
.SH FILES
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2012 Tobias Brunner
|
||||
* Copyright (C) 2008-2013 Tobias Brunner
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
|
@ -32,6 +32,7 @@
|
|||
#include <credentials/certificates/x509.h>
|
||||
#include <credentials/certificates/crl.h>
|
||||
#include <credentials/certificates/ac.h>
|
||||
#include <credentials/containers/pkcs12.h>
|
||||
#include <credentials/sets/mem_cred.h>
|
||||
#include <credentials/sets/callback_cred.h>
|
||||
#include <collections/linked_list.h>
|
||||
|
@ -72,7 +73,7 @@ struct private_stroke_cred_t {
|
|||
|
||||
/**
|
||||
* ignore missing CA basic constraint (i.e. treat all certificates in
|
||||
* ipsec.conf ca sections and ipsec.d/cacert as CA certificates)
|
||||
* ipsec.conf ca sections and ipsec.d/cacerts as CA certificates)
|
||||
*/
|
||||
bool force_ca_cert;
|
||||
|
||||
|
@ -225,7 +226,7 @@ METHOD(stroke_cred_t, load_ca, certificate_t*,
|
|||
cert->destroy(cert);
|
||||
return NULL;
|
||||
}
|
||||
DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s",
|
||||
DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
|
||||
cert->get_subject(cert), filename);
|
||||
return this->creds->add_cert_ref(this->creds, TRUE, cert);
|
||||
}
|
||||
|
@ -821,15 +822,14 @@ static bool load_pin(mem_cred_t *secrets, chunk_t line, int line_nr,
|
|||
}
|
||||
|
||||
/**
|
||||
* Load a private key
|
||||
* Load a private key or PKCS#12 container from a file
|
||||
*/
|
||||
static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
|
||||
FILE *prompt, key_type_t key_type)
|
||||
static bool load_from_file(chunk_t line, int line_nr, FILE *prompt,
|
||||
char *path, int type, int subtype,
|
||||
void **result)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
chunk_t filename;
|
||||
chunk_t secret = chunk_empty;
|
||||
private_key_t *key;
|
||||
|
||||
err_t ugh = extract_value(&filename, &line);
|
||||
|
||||
|
@ -846,12 +846,12 @@ static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
|
|||
if (*filename.ptr == '/')
|
||||
{
|
||||
/* absolute path name */
|
||||
snprintf(path, sizeof(path), "%.*s", (int)filename.len, filename.ptr);
|
||||
snprintf(path, PATH_MAX, "%.*s", (int)filename.len, filename.ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* relative path name */
|
||||
snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR,
|
||||
snprintf(path, PATH_MAX, "%s/%.*s", PRIVATE_KEY_DIR,
|
||||
(int)filename.len, filename.ptr);
|
||||
}
|
||||
|
||||
|
@ -877,6 +877,7 @@ static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
|
|||
free(secret.ptr);
|
||||
if (!prompt)
|
||||
{
|
||||
*result = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
/* use callback credential set to prompt for the passphrase */
|
||||
|
@ -886,8 +887,8 @@ static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
|
|||
cb = callback_cred_create_shared((void*)passphrase_cb, &pp_data);
|
||||
lib->credmgr->add_local_set(lib->credmgr, &cb->set, FALSE);
|
||||
|
||||
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type,
|
||||
BUILD_FROM_FILE, path, BUILD_END);
|
||||
*result = lib->creds->create(lib->creds, type, subtype,
|
||||
BUILD_FROM_FILE, path, BUILD_END);
|
||||
|
||||
lib->credmgr->remove_local_set(lib->credmgr, &cb->set);
|
||||
cb->destroy(cb);
|
||||
|
@ -903,12 +904,29 @@ static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
|
|||
mem->add_shared(mem, shared, NULL);
|
||||
lib->credmgr->add_local_set(lib->credmgr, &mem->set, FALSE);
|
||||
|
||||
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type,
|
||||
BUILD_FROM_FILE, path, BUILD_END);
|
||||
*result = lib->creds->create(lib->creds, type, subtype,
|
||||
BUILD_FROM_FILE, path, BUILD_END);
|
||||
|
||||
lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
|
||||
mem->destroy(mem);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a private key
|
||||
*/
|
||||
static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
|
||||
FILE *prompt, key_type_t key_type)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
private_key_t *key;
|
||||
|
||||
if (!load_from_file(line, line_nr, prompt, path, CRED_PRIVATE_KEY,
|
||||
key_type, (void**)&key))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (key)
|
||||
{
|
||||
DBG1(DBG_CFG, " loaded %N private key from '%s'",
|
||||
|
@ -922,6 +940,58 @@ static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a PKCS#12 container
|
||||
*/
|
||||
static bool load_pkcs12(mem_cred_t *secrets, chunk_t line, int line_nr,
|
||||
FILE *prompt)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
char path[PATH_MAX];
|
||||
certificate_t *cert;
|
||||
private_key_t *key;
|
||||
pkcs12_t *pkcs12;
|
||||
|
||||
if (!load_from_file(line, line_nr, prompt, path, CRED_CONTAINER,
|
||||
CONTAINER_PKCS12, (void**)&pkcs12))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!pkcs12)
|
||||
{
|
||||
DBG1(DBG_CFG, " loading credentials from '%s' failed", path);
|
||||
return TRUE;
|
||||
}
|
||||
enumerator = pkcs12->create_cert_enumerator(pkcs12);
|
||||
while (enumerator->enumerate(enumerator, &cert))
|
||||
{
|
||||
x509_t *x509 = (x509_t*)cert;
|
||||
|
||||
if (x509->get_flags(x509) & X509_CA)
|
||||
{
|
||||
DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
|
||||
cert->get_subject(cert), path);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
|
||||
cert->get_subject(cert), path);
|
||||
}
|
||||
secrets->add_cert(secrets, TRUE, cert->get_ref(cert));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
enumerator = pkcs12->create_key_enumerator(pkcs12);
|
||||
while (enumerator->enumerate(enumerator, &key))
|
||||
{
|
||||
DBG1(DBG_CFG, " loaded %N private key from '%s'",
|
||||
key_type_names, key->get_type(key), path);
|
||||
secrets->add_key(secrets, key->get_ref(key));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
pkcs12->container.destroy(&pkcs12->container);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a shared key
|
||||
*/
|
||||
|
@ -1140,6 +1210,13 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (match("P12", &token))
|
||||
{
|
||||
if (!load_pkcs12(secrets, line, line_nr, prompt))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (match("PIN", &token))
|
||||
{
|
||||
if (!load_pin(secrets, line, line_nr, prompt))
|
||||
|
@ -1160,7 +1237,7 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
|
|||
else
|
||||
{
|
||||
DBG1(DBG_CFG, "line %d: token must be either "
|
||||
"RSA, ECDSA, PSK, EAP, XAUTH or PIN", line_nr);
|
||||
"RSA, ECDSA, P12, PIN, PSK, EAP, XAUTH or NTLM", line_nr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue