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