summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/stroke/stroke_cred.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/stroke/stroke_cred.c')
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.c315
1 files changed, 200 insertions, 115 deletions
diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c
index 83431d17c..5e423f1de 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.c
+++ b/src/libcharon/plugins/stroke/stroke_cred.c
@@ -70,11 +70,21 @@ struct private_stroke_cred_t {
char *secrets_file;
/**
- * credentials
+ * credentials: end entity certs, attribute certs, CRLs, etc.
*/
mem_cred_t *creds;
/**
+ * CA certificates
+ */
+ mem_cred_t *cacerts;
+
+ /**
+ * Attribute Authority certificates
+ */
+ mem_cred_t *aacerts;
+
+ /**
* ignore missing CA basic constraint (i.e. treat all certificates in
* ipsec.conf ca sections and ipsec.d/cacerts as CA certificates)
*/
@@ -231,7 +241,7 @@ METHOD(stroke_cred_t, load_ca, certificate_t*,
}
DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
cert->get_subject(cert), filename);
- return this->creds->add_cert_ref(this->creds, TRUE, cert);
+ return this->creds->get_cert_ref(this->creds, cert);
}
return NULL;
}
@@ -374,133 +384,183 @@ METHOD(stroke_cred_t, load_pubkey, certificate_t*,
}
/**
- * load trusted certificates from a directory
+ * Load a CA certificate from disk
*/
-static void load_certdir(private_stroke_cred_t *this, char *path,
- certificate_type_t type, x509_flag_t flag)
+static void load_x509_ca(private_stroke_cred_t *this, char *file)
{
- struct stat st;
- char *file;
-
- enumerator_t *enumerator = enumerator_create_directory(path);
+ certificate_t *cert;
- if (!enumerator)
+ if (this->force_ca_cert)
+ { /* treat certificate as CA cert even it has no CA basic constraint */
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file,
+ BUILD_X509_FLAG, X509_CA, BUILD_END);
+ }
+ else
{
- DBG1(DBG_CFG, " reading directory failed");
- return;
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file, BUILD_END);
}
-
- while (enumerator->enumerate(enumerator, NULL, &file, &st))
+ if (cert)
{
- certificate_t *cert;
+ x509_t *x509 = (x509_t*)cert;
- if (!S_ISREG(st.st_mode))
+ if (!(x509->get_flags(x509) & X509_CA))
{
- /* skip special file */
- continue;
+ DBG1(DBG_CFG, " ca certificate \"%Y\" lacks ca basic constraint, "
+ "discarded", cert->get_subject(cert));
+ cert->destroy(cert);
}
- switch (type)
+ else
{
- case CERT_X509:
- if (flag & X509_CA)
- {
- if (this->force_ca_cert)
- { /* treat this certificate as CA cert even it has no
- * CA basic constraint */
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, file, BUILD_X509_FLAG,
- X509_CA, BUILD_END);
- }
- else
- {
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, file, BUILD_END);
- }
- if (cert)
- {
- x509_t *x509 = (x509_t*)cert;
-
- if (!(x509->get_flags(x509) & X509_CA))
- {
- DBG1(DBG_CFG, " ca certificate \"%Y\" lacks "
- "ca basic constraint, discarded",
- cert->get_subject(cert));
- cert->destroy(cert);
- cert = NULL;
- }
- else
- {
- DBG1(DBG_CFG, " loaded ca certificate \"%Y\" "
- "from '%s'", cert->get_subject(cert), file);
- }
- }
- else
+ DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
+ cert->get_subject(cert), file);
+ this->cacerts->add_cert(this->cacerts, TRUE, cert);
+ }
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loading ca certificate from '%s' failed", file);
+ }
+}
+
+/**
+ * Load AA certificate with flags from disk
+ */
+static void load_x509_aa(private_stroke_cred_t *this, char *file)
+{
+ certificate_t *cert;
+
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file,
+ BUILD_X509_FLAG, X509_AA, BUILD_END);
+ if (cert)
+ {
+ DBG1(DBG_CFG, " loaded AA certificate \"%Y\" from '%s'",
+ cert->get_subject(cert), file);
+ this->aacerts->add_cert(this->aacerts, TRUE, cert);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loading AA certificate from '%s' failed", file);
+ }
+}
+
+/**
+ * Load a certificate with flags from disk
+ */
+static void load_x509(private_stroke_cred_t *this, char *file, x509_flag_t flag)
+{
+ certificate_t *cert;
+
+ /* for all other flags, we add them to the certificate. */
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file,
+ BUILD_X509_FLAG, flag, BUILD_END);
+ if (cert)
+ {
+ DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
+ cert->get_subject(cert), file);
+ this->creds->add_cert(this->creds, TRUE, cert);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loading certificate from '%s' failed", file);
+ }
+}
+
+/**
+ * Load a CRL from a file
+ */
+static void load_x509_crl(private_stroke_cred_t *this, char *file)
+{
+ certificate_t *cert;
+
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
+ BUILD_FROM_FILE, file, BUILD_END);
+ if (cert)
+ {
+ this->creds->add_crl(this->creds, (crl_t*)cert);
+ DBG1(DBG_CFG, " loaded crl from '%s'", file);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loading crl from '%s' failed", file);
+ }
+}
+
+/**
+ * Load an attribute certificate from a file
+ */
+static void load_x509_ac(private_stroke_cred_t *this, char *file)
+{
+ certificate_t *cert;
+
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
+ BUILD_FROM_FILE, file, BUILD_END);
+ if (cert)
+ {
+ DBG1(DBG_CFG, " loaded attribute certificate from '%s'", file);
+ this->creds->add_cert(this->creds, FALSE, cert);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loading attribute certificate from '%s' failed", file);
+ }
+}
+
+/**
+ * load trusted certificates from a directory
+ */
+static void load_certdir(private_stroke_cred_t *this, char *path,
+ certificate_type_t type, x509_flag_t flag)
+{
+ enumerator_t *enumerator;
+ struct stat st;
+ char *file;
+
+ enumerator = enumerator_create_directory(path);
+ if (enumerator)
+ {
+ while (enumerator->enumerate(enumerator, NULL, &file, &st))
+ {
+ if (!S_ISREG(st.st_mode))
+ {
+ /* skip special file */
+ continue;
+ }
+ switch (type)
+ {
+ case CERT_X509:
+ if (flag & X509_CA)
{
- DBG1(DBG_CFG, " loading ca certificate from '%s' "
- "failed", file);
+ load_x509_ca(this, file);
}
- }
- else
- { /* for all other flags, we add them to the certificate. */
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, file,
- BUILD_X509_FLAG, flag, BUILD_END);
- if (cert)
+ else if (flag & X509_AA)
{
- DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
- cert->get_subject(cert), file);
+ load_x509_aa(this, file);
}
else
{
- DBG1(DBG_CFG, " loading certificate from '%s' "
- "failed", file);
+ load_x509(this, file, flag);
}
- }
- if (cert)
- {
- this->creds->add_cert(this->creds, TRUE, cert);
- }
- break;
- case CERT_X509_CRL:
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509_CRL,
- BUILD_FROM_FILE, file,
- BUILD_END);
- if (cert)
- {
- this->creds->add_crl(this->creds, (crl_t*)cert);
- DBG1(DBG_CFG, " loaded crl from '%s'", file);
- }
- else
- {
- DBG1(DBG_CFG, " loading crl from '%s' failed", file);
- }
- break;
- case CERT_X509_AC:
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509_AC,
- BUILD_FROM_FILE, file,
- BUILD_END);
- if (cert)
- {
- this->creds->add_cert(this->creds, FALSE, cert);
- DBG1(DBG_CFG, " loaded attribute certificate from '%s'",
- file);
- }
- else
- {
- DBG1(DBG_CFG, " loading attribute certificate from '%s' "
- "failed", file);
- }
- break;
- default:
- break;
+ break;
+ case CERT_X509_CRL:
+ load_x509_crl(this, file);
+ break;
+ case CERT_X509_AC:
+ load_x509_ac(this, file);
+ break;
+ default:
+ break;
+ }
}
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " reading directory failed");
}
- enumerator->destroy(enumerator);
}
METHOD(stroke_cred_t, cache_cert, void,
@@ -1124,6 +1184,7 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
while (fetchline(src, &line))
{
chunk_t ids, token;
+ key_type_t key_type;
shared_key_type_t type;
line_nr++;
@@ -1222,10 +1283,22 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
DBG1(DBG_CFG, "line %d: missing token", line_nr);
break;
}
- if (match("RSA", &token) || match("ECDSA", &token))
+ if (match("RSA", &token) || match("ECDSA", &token) ||
+ match("BLISS", &token))
{
- if (!load_private(secrets, line, line_nr, prompt,
- match("RSA", &token) ? KEY_RSA : KEY_ECDSA))
+ if (match("RSA", &token))
+ {
+ key_type = KEY_RSA;
+ }
+ else if (match("ECDSA", &token))
+ {
+ key_type = KEY_ECDSA;
+ }
+ else
+ {
+ key_type = KEY_BLISS;
+ }
+ if (!load_private(secrets, line, line_nr, prompt, key_type))
{
break;
}
@@ -1256,8 +1329,8 @@ 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, P12, PIN, PSK, EAP, XAUTH or NTLM", line_nr);
+ DBG1(DBG_CFG, "line %d: token must be either RSA, ECDSA, BLISS, "
+ "P12, PIN, PSK, EAP, XAUTH or NTLM", line_nr);
break;
}
}
@@ -1308,6 +1381,8 @@ METHOD(stroke_cred_t, reread, void,
{
DBG1(DBG_CFG, "rereading ca certificates from '%s'",
CA_CERTIFICATE_DIR);
+ this->cacerts->clear(this->cacerts);
+ lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
}
if (msg->reread.flags & REREAD_OCSPCERTS)
@@ -1321,6 +1396,8 @@ METHOD(stroke_cred_t, reread, void,
{
DBG1(DBG_CFG, "rereading aa certificates from '%s'",
AA_CERTIFICATE_DIR);
+ this->aacerts->clear(this->aacerts);
+ lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
}
if (msg->reread.flags & REREAD_ACERTS)
@@ -1346,7 +1423,11 @@ METHOD(stroke_cred_t, add_shared, void,
METHOD(stroke_cred_t, destroy, void,
private_stroke_cred_t *this)
{
+ lib->credmgr->remove_set(lib->credmgr, &this->aacerts->set);
+ lib->credmgr->remove_set(lib->credmgr, &this->cacerts->set);
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
+ this->aacerts->destroy(this->aacerts);
+ this->cacerts->destroy(this->cacerts);
this->creds->destroy(this->creds);
free(this);
}
@@ -1379,9 +1460,13 @@ stroke_cred_t *stroke_cred_create()
"%s.plugins.stroke.secrets_file", SECRETS_FILE,
lib->ns),
.creds = mem_cred_create(),
+ .cacerts = mem_cred_create(),
+ .aacerts = mem_cred_create(),
);
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
+ lib->credmgr->add_set(lib->credmgr, &this->cacerts->set);
+ lib->credmgr->add_set(lib->credmgr, &this->aacerts->set);
this->force_ca_cert = lib->settings->get_bool(lib->settings,
"%s.plugins.stroke.ignore_missing_ca_basic_constraint",