diff options
author | Martin Willi <martin@strongswan.org> | 2009-08-13 13:37:14 +0200 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2009-08-26 11:23:49 +0200 |
commit | ccd0a624b69ef200730ba2c055a16ff4d7de0f5f (patch) | |
tree | 03b24c6468f1ce8ccc2f5db89e8a8f043da33d19 /src | |
parent | 37f5a0da2ca7cd12ae5119414c9e4005369c372a (diff) | |
download | strongswan-ccd0a624b69ef200730ba2c055a16ff4d7de0f5f.tar.bz2 strongswan-ccd0a624b69ef200730ba2c055a16ff4d7de0f5f.tar.xz |
use credential builder to build crls
Diffstat (limited to 'src')
-rw-r--r-- | src/pluto/builder.c | 72 | ||||
-rw-r--r-- | src/pluto/crl.c | 209 | ||||
-rw-r--r-- | src/pluto/crl.h | 2 | ||||
-rw-r--r-- | src/pluto/fetch.c | 47 |
4 files changed, 189 insertions, 141 deletions
diff --git a/src/pluto/builder.c b/src/pluto/builder.c index 854c8c69b..eaa23c4cd 100644 --- a/src/pluto/builder.c +++ b/src/pluto/builder.c @@ -31,6 +31,7 @@ #include "id.h" #include "certs.h" #include "ac.h" +#include "crl.h" /** * currently building cert_t @@ -191,17 +192,88 @@ static builder_t *ac_builder(credential_type_t type, int subtype) return this; } +/** + * currently building x509crl_t + */ +static x509crl_t *crl; + +/** + * builder add function + */ +static void crl_add(builder_t *this, builder_part_t part, ...) +{ + chunk_t blob; + va_list args; + + switch (part) + { + case BUILD_BLOB_ASN1_DER: + { + va_start(args, part); + blob = va_arg(args, chunk_t); + va_end(args); + + crl = malloc_thing(x509crl_t); + *crl = empty_x509crl; + + if (!parse_x509crl(blob, 0, crl)) + { + plog(" error in X.509 crl"); + free_crl(crl); + crl = NULL; + } + break; + } + default: + builder_cancel(this); + break; + } +} + +/** + * builder build function + */ +static void *crl_build(builder_t *this) +{ + free(this); + return crl; +} + +/** + * CRL builder in x509crl_t format. + */ +static builder_t *crl_builder(credential_type_t type, int subtype) +{ + builder_t *this; + + if (subtype != CRED_TYPE_CRL) + { + return NULL; + } + this = malloc_thing(builder_t); + this->add = crl_add; + this->build = crl_build; + + crl = NULL; + + return this; +} + + void init_builder(void) { lib->creds->add_builder(lib->creds, CRED_PLUTO_CERT, CRED_TYPE_CERTIFICATE, (builder_constructor_t)cert_builder); lib->creds->add_builder(lib->creds, CRED_PLUTO_CERT, CRED_TYPE_AC, (builder_constructor_t)ac_builder); + lib->creds->add_builder(lib->creds, CRED_PLUTO_CERT, CRED_TYPE_CRL, + (builder_constructor_t)crl_builder); } void free_builder(void) { lib->creds->remove_builder(lib->creds, (builder_constructor_t)cert_builder); lib->creds->remove_builder(lib->creds, (builder_constructor_t)ac_builder); + lib->creds->remove_builder(lib->creds, (builder_constructor_t)crl_builder); } diff --git a/src/pluto/crl.c b/src/pluto/crl.c index c800f2acc..aeb49884a 100644 --- a/src/pluto/crl.c +++ b/src/pluto/crl.c @@ -39,6 +39,7 @@ #include "keys.h" #include "whack.h" #include "fetch.h" +#include "builder.h" /* chained lists of X.509 crls */ @@ -202,127 +203,114 @@ void free_crls(void) /** * Insert X.509 CRL into chained list */ -bool insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl) +bool insert_crl(x509crl_t *crl, chunk_t crl_uri, bool cache_crl) { - x509crl_t *crl = malloc_thing(x509crl_t); + x509cert_t *issuer_cert; + x509crl_t *oldcrl; + bool valid_sig; + generalName_t *gn; + + /* add distribution point */ + gn = malloc_thing(generalName_t); + gn->kind = GN_URI; + gn->name = crl_uri; + gn->next = crl->distributionPoints; + crl->distributionPoints = gn; + + lock_authcert_list("insert_crl"); + /* get the issuer cacert */ + issuer_cert = get_authcert(crl->issuer, crl->authKeySerialNumber, + crl->authKeyID, AUTH_CA); + if (issuer_cert == NULL) + { + plog("crl issuer cacert not found"); + free_crl(crl); + unlock_authcert_list("insert_crl"); + return FALSE; + } + DBG(DBG_CONTROL, + DBG_log("crl issuer cacert found") + ) - *crl = empty_x509crl; + /* check the issuer's signature of the crl */ + valid_sig = x509_check_signature(crl->tbsCertList, crl->signature, + crl->algorithm, issuer_cert); + unlock_authcert_list("insert_crl"); - if (parse_x509crl(blob, 0, crl)) + if (!valid_sig) { - x509cert_t *issuer_cert; - x509crl_t *oldcrl; - bool valid_sig; - generalName_t *gn; - - /* add distribution point */ - gn = malloc_thing(generalName_t); - gn->kind = GN_URI; - gn->name = crl_uri; - gn->next = crl->distributionPoints; - crl->distributionPoints = gn; - - lock_authcert_list("insert_crl"); - /* get the issuer cacert */ - issuer_cert = get_authcert(crl->issuer, crl->authKeySerialNumber, - crl->authKeyID, AUTH_CA); - if (issuer_cert == NULL) - { - plog("crl issuer cacert not found"); - free_crl(crl); - unlock_authcert_list("insert_crl"); - return FALSE; - } - DBG(DBG_CONTROL, - DBG_log("crl issuer cacert found") - ) + free_crl(crl); + return FALSE; + } + DBG(DBG_CONTROL, + DBG_log("crl signature is valid") + ) - /* check the issuer's signature of the crl */ - valid_sig = x509_check_signature(crl->tbsCertList, crl->signature, - crl->algorithm, issuer_cert); - unlock_authcert_list("insert_crl"); + lock_crl_list("insert_crl"); + oldcrl = get_x509crl(crl->issuer, crl->authKeySerialNumber + , crl->authKeyID); - if (!valid_sig) + if (oldcrl != NULL) + { + if (crl->thisUpdate > oldcrl->thisUpdate) { - free_crl(crl); - return FALSE; - } - DBG(DBG_CONTROL, - DBG_log("crl signature is valid") - ) - - lock_crl_list("insert_crl"); - oldcrl = get_x509crl(crl->issuer, crl->authKeySerialNumber - , crl->authKeyID); + /* keep any known CRL distribution points */ + add_distribution_points(oldcrl->distributionPoints + , &crl->distributionPoints); - if (oldcrl != NULL) + /* now delete the old CRL */ + free_first_crl(); + DBG(DBG_CONTROL, + DBG_log("thisUpdate is newer - existing crl deleted") + ) + } + else { - if (crl->thisUpdate > oldcrl->thisUpdate) - { - /* keep any known CRL distribution points */ - add_distribution_points(oldcrl->distributionPoints - , &crl->distributionPoints); - - /* now delete the old CRL */ - free_first_crl(); - DBG(DBG_CONTROL, - DBG_log("thisUpdate is newer - existing crl deleted") - ) - } - else - { - unlock_crl_list("insert_crls"); - DBG(DBG_CONTROL, - DBG_log("thisUpdate is not newer - existing crl not replaced"); - ) - free_crl(crl); - return oldcrl->nextUpdate - time(NULL) > 2*crl_check_interval; - } + unlock_crl_list("insert_crls"); + DBG(DBG_CONTROL, + DBG_log("thisUpdate is not newer - existing crl not replaced"); + ) + free_crl(crl); + return oldcrl->nextUpdate - time(NULL) > 2*crl_check_interval; } + } - /* insert new CRL */ - crl->next = x509crls; - x509crls = crl; + /* insert new CRL */ + crl->next = x509crls; + x509crls = crl; - unlock_crl_list("insert_crl"); + unlock_crl_list("insert_crl"); - /* If crl caching is enabled then the crl is saved locally. - * Only http or ldap URIs are cached but not local file URIs. - * The issuer's subjectKeyID is used as a unique filename - */ - if (cache_crl && strncasecmp(crl_uri.ptr, "file", 4) != 0) + /* If crl caching is enabled then the crl is saved locally. + * Only http or ldap URIs are cached but not local file URIs. + * The issuer's subjectKeyID is used as a unique filename + */ + if (cache_crl && strncasecmp(crl_uri.ptr, "file", 4) != 0) + { + char path[BUF_LEN], buf[BUF_LEN]; + char digest_buf[HASH_SIZE_SHA1]; + chunk_t subjectKeyID = chunk_from_buf(digest_buf); + bool has_keyID; + + if (issuer_cert->subjectKeyID.ptr == NULL) { - char path[BUF_LEN], buf[BUF_LEN]; - char digest_buf[HASH_SIZE_SHA1]; - chunk_t subjectKeyID = chunk_from_buf(digest_buf); - bool has_keyID; - - if (issuer_cert->subjectKeyID.ptr == NULL) - { - has_keyID = compute_subjectKeyID(issuer_cert, subjectKeyID); - } - else - { - subjectKeyID = issuer_cert->subjectKeyID; - has_keyID = TRUE; - } - if (has_keyID) - { - datatot(subjectKeyID.ptr, subjectKeyID.len, 16, buf, BUF_LEN); - snprintf(path, BUF_LEN, "%s/%s.crl", CRL_PATH, buf); - chunk_write(crl->certificateList, path, "crl", 0022, TRUE); - } + has_keyID = compute_subjectKeyID(issuer_cert, subjectKeyID); + } + else + { + subjectKeyID = issuer_cert->subjectKeyID; + has_keyID = TRUE; + } + if (has_keyID) + { + datatot(subjectKeyID.ptr, subjectKeyID.len, 16, buf, BUF_LEN); + snprintf(path, BUF_LEN, "%s/%s.crl", CRL_PATH, buf); + chunk_write(crl->certificateList, path, "crl", 0022, TRUE); } - - /* is the fetched crl valid? */ - return crl->nextUpdate - time(NULL) > 2*crl_check_interval; - } - else - { - plog(" error in X.509 crl"); - free_crl(crl); - return FALSE; } + + /* is the fetched crl valid? */ + return crl->nextUpdate - time(NULL) > 2*crl_check_interval; } /** @@ -352,11 +340,12 @@ void load_crls(void) { while (n--) { - bool pgp = FALSE; - chunk_t blob = chunk_empty; char *filename = filelist[n]->d_name; - - if (load_coded_file(filename, NULL, "crl", &blob, &pgp)) + x509crl_t *crl; + + crl = lib->creds->create(lib->creds, CRED_PLUTO_CERT, + CRED_TYPE_CRL, BUILD_FROM_FILE, filename, BUILD_END); + if (crl) { chunk_t crl_uri; @@ -367,7 +356,7 @@ void load_crls(void) snprintf(crl_uri.ptr, crl_uri.len + 1, "file://%s/%s" , CRL_PATH, filename); - insert_crl(blob, crl_uri, FALSE); + insert_crl(crl, crl_uri, FALSE); } free(filelist[n]); } diff --git a/src/pluto/crl.h b/src/pluto/crl.h index 7c110ad5a..90a6586db 100644 --- a/src/pluto/crl.h +++ b/src/pluto/crl.h @@ -78,7 +78,7 @@ extern const x509crl_t empty_x509crl; extern bool parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl); extern void load_crls(void); extern void check_crls(void); -extern bool insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl); +extern bool insert_crl(x509crl_t *crl, chunk_t crl_uri, bool cache_crl); extern cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until , time_t *revocationDate, crl_reason_t *revocationReason); extern void list_crls(bool utc, bool strict); diff --git a/src/pluto/fetch.c b/src/pluto/fetch.c index 6f7f1215f..c636266de 100644 --- a/src/pluto/fetch.c +++ b/src/pluto/fetch.c @@ -41,6 +41,7 @@ #include "ocsp.h" #include "crl.h" #include "fetch.h" +#include "builder.h" fetch_req_t empty_fetch_req = { NULL , /* next */ @@ -262,40 +263,25 @@ static void free_fetch_request(fetch_req_t *req) /** * Fetch an ASN.1 blob coded in PEM or DER format from a URL */ -bool fetch_asn1_blob(char *url, chunk_t *blob) +x509crl_t* fetch_crl(char *url) { + x509crl_t *crl; + chunk_t blob; + DBG1(" fetching crl from '%s' ...", url); - if (lib->fetcher->fetch(lib->fetcher, url, blob, FETCH_END) != SUCCESS) + if (lib->fetcher->fetch(lib->fetcher, url, &blob, FETCH_END) != SUCCESS) { DBG1("crl fetching failed"); return FALSE; } - - if (is_asn1(*blob)) + crl = lib->creds->create(lib->creds, CRED_PLUTO_CERT, CRED_TYPE_CRL, + BUILD_BLOB_PEM, blob, BUILD_END); + free(blob.ptr); + if (!crl) { - DBG2(" fetched blob coded in DER format"); - } - else - { - bool pgp = FALSE; - - if (pem_to_bin(blob, chunk_empty, &pgp) != SUCCESS) - { - free(blob->ptr); - return FALSE; - } - if (is_asn1(*blob)) - { - DBG2(" fetched blob coded in PEM format"); - } - else - { - DBG1("crl fetched successfully but data coded in unknown format"); - free(blob->ptr); - return FALSE; - } + DBG1("crl fetched successfully but data coded in unknown format"); } - return TRUE; + return crl; } /** @@ -359,7 +345,6 @@ static void fetch_crls(bool cache_crls) while (req != NULL) { bool valid_crl = FALSE; - chunk_t blob = chunk_empty; generalName_t *gn = req->distributionPoints; const char *ldaphost; ca_info_t *ca; @@ -372,12 +357,14 @@ static void fetch_crls(bool cache_crls) while (gn != NULL) { char *uri = complete_uri(gn->name, ldaphost); - - if (fetch_asn1_blob(uri, &blob)) + x509crl_t *crl; + + crl = fetch_crl(uri); + if (crl) { chunk_t crl_uri = chunk_clone(gn->name); - if (insert_crl(blob, crl_uri, cache_crls)) + if (insert_crl(crl, crl_uri, cache_crls)) { DBG(DBG_CONTROL, DBG_log("we have a valid crl") |