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.c257
1 files changed, 133 insertions, 124 deletions
diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c
index 5e423f1de..42928882a 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.c
+++ b/src/libcharon/plugins/stroke/stroke_cred.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2013 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -75,11 +75,6 @@ struct private_stroke_cred_t {
mem_cred_t *creds;
/**
- * CA certificates
- */
- mem_cred_t *cacerts;
-
- /**
* Attribute Authority certificates
*/
mem_cred_t *aacerts;
@@ -94,6 +89,11 @@ struct private_stroke_cred_t {
* cache CRLs to disk?
*/
bool cachecrl;
+
+ /**
+ * CA certificate store
+ */
+ stroke_ca_t *ca;
};
/** Length of smartcard specifier parts (module, keyid) */
@@ -182,70 +182,6 @@ static certificate_t *load_from_smartcard(smartcard_format_t format,
return cred;
}
-METHOD(stroke_cred_t, load_ca, certificate_t*,
- private_stroke_cred_t *this, char *filename)
-{
- certificate_t *cert = NULL;
- char path[PATH_MAX];
-
- if (strpfx(filename, "%smartcard"))
- {
- smartcard_format_t format;
- char module[SC_PART_LEN], keyid[SC_PART_LEN];
- u_int slot;
-
- format = parse_smartcard(filename, &slot, module, keyid);
- if (format != SC_FORMAT_INVALID)
- {
- cert = (certificate_t*)load_from_smartcard(format,
- slot, module, keyid, CRED_CERTIFICATE, CERT_X509);
- }
- }
- else
- {
- if (*filename == '/')
- {
- snprintf(path, sizeof(path), "%s", filename);
- }
- else
- {
- snprintf(path, sizeof(path), "%s/%s", CA_CERTIFICATE_DIR, filename);
- }
-
- if (this->force_ca_cert)
- { /* we treat this certificate as a CA certificate even if it has no
- * CA basic constraint */
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, path, BUILD_X509_FLAG, X509_CA,
- BUILD_END);
- }
- else
- {
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, path,
- BUILD_END);
- }
- }
- if (cert)
- {
- x509_t *x509 = (x509_t*)cert;
-
- if (!(x509->get_flags(x509) & X509_CA))
- {
- DBG1(DBG_CFG, " ca certificate \"%Y\" misses ca basic constraint, "
- "discarded", cert->get_subject(cert));
- cert->destroy(cert);
- return NULL;
- }
- DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
- cert->get_subject(cert), filename);
- return this->creds->get_cert_ref(this->creds, cert);
- }
- return NULL;
-}
-
METHOD(stroke_cred_t, load_peer, certificate_t*,
private_stroke_cred_t *this, char *filename)
{
@@ -384,22 +320,52 @@ METHOD(stroke_cred_t, load_pubkey, certificate_t*,
}
/**
- * Load a CA certificate from disk
+ * Load a CA certificate, optionally force it to be one
*/
-static void load_x509_ca(private_stroke_cred_t *this, char *file)
+static certificate_t *load_ca_cert(char *filename, bool force_ca_cert)
{
- certificate_t *cert;
+ certificate_t *cert = NULL;
+ char path[PATH_MAX];
+
+ if (strpfx(filename, "%smartcard"))
+ {
+ smartcard_format_t format;
+ char module[SC_PART_LEN], keyid[SC_PART_LEN];
+ u_int slot;
- 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);
+ format = parse_smartcard(filename, &slot, module, keyid);
+ if (format != SC_FORMAT_INVALID)
+ {
+ cert = (certificate_t*)load_from_smartcard(format,
+ slot, module, keyid, CRED_CERTIFICATE, CERT_X509);
+ }
}
else
{
- cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, file, BUILD_END);
+ if (*filename == '/')
+ {
+ snprintf(path, sizeof(path), "%s", filename);
+ }
+ else
+ {
+ snprintf(path, sizeof(path), "%s/%s", CA_CERTIFICATE_DIR, filename);
+ }
+
+ if (force_ca_cert)
+ { /* we treat this certificate as a CA certificate even if it has no
+ * CA basic constraint */
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, path, BUILD_X509_FLAG, X509_CA,
+ BUILD_END);
+ }
+ else
+ {
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, path,
+ BUILD_END);
+ }
}
if (cert)
{
@@ -410,13 +376,41 @@ static void load_x509_ca(private_stroke_cred_t *this, char *file)
DBG1(DBG_CFG, " ca certificate \"%Y\" lacks ca basic constraint, "
"discarded", cert->get_subject(cert));
cert->destroy(cert);
+ return NULL;
}
- else
- {
- DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
- cert->get_subject(cert), file);
- this->cacerts->add_cert(this->cacerts, TRUE, cert);
- }
+ DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
+ cert->get_subject(cert), filename);
+ return cert;
+ }
+ return NULL;
+}
+
+/**
+ * Used by stroke_ca.c
+ */
+certificate_t *stroke_load_ca_cert(char *filename)
+{
+ bool force_ca_cert;
+
+ force_ca_cert = lib->settings->get_bool(lib->settings,
+ "%s.plugins.stroke.ignore_missing_ca_basic_constraint",
+ FALSE, lib->ns);
+ return load_ca_cert(filename, force_ca_cert);
+}
+
+/**
+ * Load a CA certificate from disk
+ */
+static void load_x509_ca(private_stroke_cred_t *this, char *file,
+ mem_cred_t *creds)
+{
+ certificate_t *cert;
+
+ cert = load_ca_cert(file, this->force_ca_cert);
+ if (cert)
+ {
+ cert = this->ca->get_cert_ref(this->ca, cert);
+ creds->add_cert(creds, TRUE, cert);
}
else
{
@@ -427,7 +421,8 @@ static void load_x509_ca(private_stroke_cred_t *this, char *file)
/**
* Load AA certificate with flags from disk
*/
-static void load_x509_aa(private_stroke_cred_t *this, char *file)
+static void load_x509_aa(private_stroke_cred_t *this,char *file,
+ mem_cred_t *creds)
{
certificate_t *cert;
@@ -438,7 +433,7 @@ static void load_x509_aa(private_stroke_cred_t *this, char *file)
{
DBG1(DBG_CFG, " loaded AA certificate \"%Y\" from '%s'",
cert->get_subject(cert), file);
- this->aacerts->add_cert(this->aacerts, TRUE, cert);
+ creds->add_cert(creds, TRUE, cert);
}
else
{
@@ -449,7 +444,8 @@ static void load_x509_aa(private_stroke_cred_t *this, char *file)
/**
* Load a certificate with flags from disk
*/
-static void load_x509(private_stroke_cred_t *this, char *file, x509_flag_t flag)
+static void load_x509(private_stroke_cred_t *this, char *file, x509_flag_t flag,
+ mem_cred_t *creds)
{
certificate_t *cert;
@@ -461,7 +457,7 @@ static void load_x509(private_stroke_cred_t *this, char *file, x509_flag_t flag)
{
DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
cert->get_subject(cert), file);
- this->creds->add_cert(this->creds, TRUE, cert);
+ creds->add_cert(creds, TRUE, cert);
}
else
{
@@ -472,7 +468,8 @@ static void load_x509(private_stroke_cred_t *this, char *file, x509_flag_t flag)
/**
* Load a CRL from a file
*/
-static void load_x509_crl(private_stroke_cred_t *this, char *file)
+static void load_x509_crl(private_stroke_cred_t *this, char *file,
+ mem_cred_t *creds)
{
certificate_t *cert;
@@ -480,8 +477,8 @@ static void load_x509_crl(private_stroke_cred_t *this, char *file)
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);
+ creds->add_crl(creds, (crl_t*)cert);
}
else
{
@@ -492,7 +489,8 @@ static void load_x509_crl(private_stroke_cred_t *this, char *file)
/**
* Load an attribute certificate from a file
*/
-static void load_x509_ac(private_stroke_cred_t *this, char *file)
+static void load_x509_ac(private_stroke_cred_t *this, char *file,
+ mem_cred_t *creds)
{
certificate_t *cert;
@@ -501,7 +499,7 @@ static void load_x509_ac(private_stroke_cred_t *this, char *file)
if (cert)
{
DBG1(DBG_CFG, " loaded attribute certificate from '%s'", file);
- this->creds->add_cert(this->creds, FALSE, cert);
+ creds->add_cert(creds, FALSE, cert);
}
else
{
@@ -513,7 +511,8 @@ static void load_x509_ac(private_stroke_cred_t *this, char *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)
+ certificate_type_t type, x509_flag_t flag,
+ mem_cred_t *creds)
{
enumerator_t *enumerator;
struct stat st;
@@ -534,22 +533,22 @@ static void load_certdir(private_stroke_cred_t *this, char *path,
case CERT_X509:
if (flag & X509_CA)
{
- load_x509_ca(this, file);
+ load_x509_ca(this, file, creds);
}
else if (flag & X509_AA)
{
- load_x509_aa(this, file);
+ load_x509_aa(this, file, creds);
}
else
{
- load_x509(this, file, flag);
+ load_x509(this, file, flag, creds);
}
break;
case CERT_X509_CRL:
- load_x509_crl(this, file);
+ load_x509_crl(this, file, creds);
break;
case CERT_X509_AC:
- load_x509_ac(this, file);
+ load_x509_ac(this, file, creds);
break;
default:
break;
@@ -1348,30 +1347,38 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
*/
static void load_certs(private_stroke_cred_t *this)
{
+ mem_cred_t *creds;
+
DBG1(DBG_CFG, "loading ca certificates from '%s'",
CA_CERTIFICATE_DIR);
- load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
+ creds = mem_cred_create();
+ load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA, creds);
+ this->ca->replace_certs(this->ca, creds);
+ creds->destroy(creds);
DBG1(DBG_CFG, "loading aa certificates from '%s'",
AA_CERTIFICATE_DIR);
- load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
+ load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA, this->aacerts);
DBG1(DBG_CFG, "loading ocsp signer certificates from '%s'",
OCSP_CERTIFICATE_DIR);
- load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509, X509_OCSP_SIGNER);
+ load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509, X509_OCSP_SIGNER,
+ this->creds);
DBG1(DBG_CFG, "loading attribute certificates from '%s'",
ATTR_CERTIFICATE_DIR);
- load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0);
+ load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0, this->creds);
DBG1(DBG_CFG, "loading crls from '%s'",
CRL_DIR);
- load_certdir(this, CRL_DIR, CERT_X509_CRL, 0);
+ load_certdir(this, CRL_DIR, CERT_X509_CRL, 0, this->creds);
}
METHOD(stroke_cred_t, reread, void,
private_stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt)
{
+ mem_cred_t *creds;
+
if (msg->reread.flags & REREAD_SECRETS)
{
DBG1(DBG_CFG, "rereading secrets");
@@ -1379,38 +1386,44 @@ METHOD(stroke_cred_t, reread, void,
}
if (msg->reread.flags & REREAD_CACERTS)
{
+ /* first reload certificates in ca sections, so we can refer to them */
+ this->ca->reload_certs(this->ca);
+
DBG1(DBG_CFG, "rereading ca certificates from '%s'",
CA_CERTIFICATE_DIR);
- this->cacerts->clear(this->cacerts);
+ creds = mem_cred_create();
+ load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA, creds);
+ this->ca->replace_certs(this->ca, creds);
+ creds->destroy(creds);
+ }
+ if (msg->reread.flags & REREAD_AACERTS)
+ {
+ DBG1(DBG_CFG, "rereading aa certificates from '%s'",
+ AA_CERTIFICATE_DIR);
+ creds = mem_cred_create();
+ load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA, creds);
+ this->aacerts->replace_certs(this->aacerts, creds, FALSE);
+ creds->destroy(creds);
lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
- load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
}
if (msg->reread.flags & REREAD_OCSPCERTS)
{
DBG1(DBG_CFG, "rereading ocsp signer certificates from '%s'",
OCSP_CERTIFICATE_DIR);
load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509,
- X509_OCSP_SIGNER);
- }
- if (msg->reread.flags & REREAD_AACERTS)
- {
- 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);
+ X509_OCSP_SIGNER, this->creds);
}
if (msg->reread.flags & REREAD_ACERTS)
{
DBG1(DBG_CFG, "rereading attribute certificates from '%s'",
ATTR_CERTIFICATE_DIR);
- load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0);
+ load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0, this->creds);
}
if (msg->reread.flags & REREAD_CRLS)
{
DBG1(DBG_CFG, "rereading crls from '%s'",
CRL_DIR);
- load_certdir(this, CRL_DIR, CERT_X509_CRL, 0);
+ load_certdir(this, CRL_DIR, CERT_X509_CRL, 0, this->creds);
}
}
@@ -1424,10 +1437,8 @@ 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);
}
@@ -1435,7 +1446,7 @@ METHOD(stroke_cred_t, destroy, void,
/*
* see header file
*/
-stroke_cred_t *stroke_cred_create()
+stroke_cred_t *stroke_cred_create(stroke_ca_t *ca)
{
private_stroke_cred_t *this;
@@ -1449,7 +1460,6 @@ stroke_cred_t *stroke_cred_create()
.cache_cert = (void*)_cache_cert,
},
.reread = _reread,
- .load_ca = _load_ca,
.load_peer = _load_peer,
.load_pubkey = _load_pubkey,
.add_shared = _add_shared,
@@ -1460,12 +1470,11 @@ 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(),
+ .ca = ca,
);
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,