diff options
Diffstat (limited to 'src/libcharon/plugins/stroke/stroke_cred.c')
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_cred.c | 257 |
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, |