summaryrefslogtreecommitdiff
path: root/src/pluto/crl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pluto/crl.c')
-rw-r--r--src/pluto/crl.c541
1 files changed, 0 insertions, 541 deletions
diff --git a/src/pluto/crl.c b/src/pluto/crl.c
deleted file mode 100644
index c49b09e19..000000000
--- a/src/pluto/crl.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/* Support of X.509 certificate revocation lists (CRLs)
- * Copyright (C) 2000-2009 Andreas Steffen
- *
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <time.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "x509.h"
-#include "crl.h"
-#include "ca.h"
-#include "certs.h"
-#include "keys.h"
-#include "whack.h"
-#include "fetch.h"
-#include "builder.h"
-
-
-/* chained lists of X.509 crls */
-
-static x509crl_t *x509crls = NULL;
-
-/**
- * Get the X.509 CRL with a given issuer
- */
-static x509crl_t* get_x509crl(identification_t *issuer, chunk_t keyid)
-{
- x509crl_t *x509crl = x509crls;
- x509crl_t *prev_crl = NULL;
-
- while (x509crl != NULL)
- {
- certificate_t *cert_crl = x509crl->crl;
- crl_t *crl = (crl_t*)cert_crl;
- identification_t *crl_issuer = cert_crl->get_issuer(cert_crl);
- chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
-
- if ((keyid.ptr && authKeyID.ptr)? same_keyid(keyid, authKeyID) :
- issuer->equals(issuer, crl_issuer))
- {
- if (x509crl != x509crls)
- {
- /* bring the CRL up front */
- prev_crl->next = x509crl->next;
- x509crl->next = x509crls;
- x509crls = x509crl;
- }
- return x509crl;
- }
- prev_crl = x509crl;
- x509crl = x509crl->next;
- }
- return NULL;
-}
-
-/**
- * Free the dynamic memory used to store CRLs
- */
-void free_crl(x509crl_t *crl)
-{
- DESTROY_IF(crl->crl);
- crl->distributionPoints->destroy_function(crl->distributionPoints, free);
- free(crl);
-}
-
-static void free_first_crl(void)
-{
- x509crl_t *crl = x509crls;
-
- x509crls = crl->next;
- free_crl(crl);
-}
-
-void free_crls(void)
-{
- lock_crl_list("free_crls");
-
- while (x509crls != NULL)
- {
- free_first_crl();
- }
-
- unlock_crl_list("free_crls");
-}
-
-/**
- * Insert X.509 CRL into chained list
- */
-bool insert_crl(x509crl_t *x509crl, char *crl_uri, bool cache_crl)
-{
- certificate_t *cert_crl = x509crl->crl;
- crl_t *crl = (crl_t*)cert_crl;
- identification_t *issuer = cert_crl->get_issuer(cert_crl);
- chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
- cert_t *issuer_cert;
- x509crl_t *oldcrl;
- time_t now, nextUpdate;
- bool valid_sig;
-
- /* add distribution point */
- add_distribution_point(x509crl->distributionPoints, crl_uri);
-
- lock_authcert_list("insert_crl");
-
- /* get the issuer cacert */
- issuer_cert = get_authcert(issuer, authKeyID, X509_CA);
- if (issuer_cert == NULL)
- {
- plog("crl issuer cacert not found");
- free_crl(x509crl);
- unlock_authcert_list("insert_crl");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("crl issuer cacert found")
- )
-
- /* check the issuer's signature of the crl */
- valid_sig = cert_crl->issued_by(cert_crl, issuer_cert->cert);
- unlock_authcert_list("insert_crl");
-
- if (!valid_sig)
- {
- free_crl(x509crl);
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("crl signature is valid")
- )
-
- /* note the current time */
- time(&now);
-
- lock_crl_list("insert_crl");
- oldcrl = get_x509crl(issuer, authKeyID);
-
- if (oldcrl != NULL)
- {
- certificate_t *old_cert_crl = oldcrl->crl;
-
- if (crl_is_newer((crl_t*)cert_crl, (crl_t*)old_cert_crl))
- {
- /* keep any known CRL distribution points */
- add_distribution_points(x509crl->distributionPoints,
- oldcrl->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(x509crl);
- old_cert_crl->get_validity(old_cert_crl, &now, NULL, &nextUpdate);
- return nextUpdate - now > 2*crl_check_interval;
- }
- }
-
- /* insert new CRL */
- x509crl->next = x509crls;
- x509crls = x509crl;
-
- 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 CRL's authorityKeyIdentifier is used as a unique filename
- */
- if (cache_crl && strncasecmp(crl_uri, "file", 4) != 0)
- {
- char buf[BUF_LEN];
- chunk_t hex, encoding;
-
- hex = chunk_to_hex(crl->get_authKeyIdentifier(crl), NULL, FALSE);
- snprintf(buf, sizeof(buf), "%s/%s.crl", CRL_PATH, hex.ptr);
- free(hex.ptr);
-
- if (cert_crl->get_encoding(cert_crl, CERT_ASN1_DER, &encoding))
- {
- chunk_write(encoding, buf, "crl", 022, TRUE);
- free(encoding.ptr);
- }
- }
-
- /* is the fetched crl valid? */
- cert_crl->get_validity(cert_crl, &now, NULL, &nextUpdate);
- return nextUpdate - now > 2*crl_check_interval;
-}
-
-/**
- * Loads CRLs
- */
-void load_crls(void)
-{
- struct dirent **filelist;
- u_char buf[BUF_LEN];
- u_char *save_dir;
- int n;
-
- /* change directory to specified path */
- save_dir = getcwd(buf, BUF_LEN);
- if (chdir(CRL_PATH))
- {
- plog("Could not change to directory '%s'", CRL_PATH);
- }
- else
- {
- plog("Changing to directory '%s'", CRL_PATH);
- n = scandir(CRL_PATH, &filelist, file_select, alphasort);
-
- if (n < 0)
- plog(" scandir() error");
- else
- {
- while (n--)
- {
- char *filename = filelist[n]->d_name;
- x509crl_t *x509crl;
-
- x509crl = lib->creds->create(lib->creds, CRED_CERTIFICATE,
- CERT_PLUTO_CRL,
- BUILD_FROM_FILE, filename, BUILD_END);
- if (x509crl)
- {
- char crl_uri[BUF_LEN];
-
- plog(" loaded crl from '%s'", filename);
- snprintf(crl_uri, BUF_LEN, "file://%s/%s", CRL_PATH, filename);
- insert_crl(x509crl, crl_uri, FALSE);
- }
- free(filelist[n]);
- }
- free(filelist);
- }
- }
- /* restore directory path */
- ignore_result(chdir(save_dir));
-}
-
-
-/* Checks if the current certificate is revoked. It goes through the
- * list of revoked certificates of the corresponding crl. Either the
- * status CERT_GOOD or CERT_REVOKED is returned
- */
-static cert_status_t check_revocation(crl_t *crl, chunk_t cert_serial,
- time_t *revocationDate,
- crl_reason_t *revocationReason)
-{
- enumerator_t *enumerator;
- cert_status_t status;
- chunk_t serial;
-
- DBG(DBG_CONTROL,
- DBG_log("serial number: %#B", &cert_serial)
- )
- *revocationDate = UNDEFINED_TIME;
- *revocationReason = CRL_REASON_UNSPECIFIED;
- status = CERT_GOOD;
-
- enumerator = crl->create_enumerator(crl);
- while (enumerator->enumerate(enumerator, &serial,
- revocationDate, revocationReason))
- {
- if (chunk_equals(serial, cert_serial))
- {
- status = CERT_REVOKED;
- break;
- }
- }
- enumerator->destroy(enumerator);
- return status;
-}
-
-/*
- * check if any crls are about to expire
- */
-void check_crls(void)
-{
- x509crl_t *x509crl;
- time_t now, nextUpdate, time_left;
-
- lock_crl_list("check_crls");
- time(&now);
- x509crl = x509crls;
-
- while (x509crl != NULL)
- {
- certificate_t *cert_crl = x509crl->crl;
- crl_t *crl = (crl_t*)cert_crl;
- identification_t *issuer = cert_crl->get_issuer(cert_crl);
- chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
-
- cert_crl->get_validity(cert_crl, &now, NULL, &nextUpdate);
- time_left = nextUpdate - now;
-
- DBG(DBG_CONTROL,
- DBG_log("issuer: '%Y'", issuer);
- if (authKeyID.ptr)
- {
- DBG_log("authkey: %#B", &authKeyID);
- }
- DBG_log("%ld seconds left", time_left)
- )
- if (time_left < 2*crl_check_interval)
- {
- fetch_req_t *req = build_crl_fetch_request(issuer, authKeyID,
- x509crl->distributionPoints);
- add_crl_fetch_request(req);
- }
- x509crl = x509crl->next;
- }
- unlock_crl_list("check_crls");
-}
-
-/*
- * verify if a cert hasn't been revoked by a crl
- */
-cert_status_t verify_by_crl(cert_t *cert, time_t *until, time_t *revocationDate,
- crl_reason_t *revocationReason)
-{
- certificate_t *certificate = cert->cert;
- x509_t *x509 = (x509_t*)certificate;
- identification_t *issuer = certificate->get_issuer(certificate);
- chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
- x509crl_t *x509crl;
- ca_info_t *ca;
- enumerator_t *enumerator;
- x509_cdp_t *cdp;
-
- ca = get_ca_info(issuer, authKeyID);
-
- *revocationDate = UNDEFINED_TIME;
- *revocationReason = CRL_REASON_UNSPECIFIED;
-
- lock_crl_list("verify_by_crl");
- x509crl = get_x509crl(issuer, authKeyID);
-
- if (x509crl == NULL)
- {
- linked_list_t *crluris;
-
- unlock_crl_list("verify_by_crl");
- plog("crl not found");
-
- crluris = linked_list_create();
- if (ca)
- {
- add_distribution_points(crluris, ca->crluris);
- }
-
- enumerator = x509->create_crl_uri_enumerator(x509);
- while (enumerator->enumerate(enumerator, &cdp))
- {
- add_distribution_point(crluris, cdp->uri);
- }
- enumerator->destroy(enumerator);
-
- if (crluris->get_count(crluris) > 0)
- {
- fetch_req_t *req;
-
- req = build_crl_fetch_request(issuer, authKeyID, crluris);
- crluris->destroy_function(crluris, free);
- add_crl_fetch_request(req);
- wake_fetch_thread("verify_by_crl");
- return CERT_UNKNOWN;
- }
- else
- {
- crluris->destroy(crluris);
- return CERT_UNDEFINED;
- }
- }
- else
- {
- certificate_t *cert_crl = x509crl->crl;
- crl_t *crl = (crl_t*)cert_crl;
- chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
- cert_t *issuer_cert;
- bool trusted, valid;
-
- DBG(DBG_CONTROL,
- DBG_log("crl found")
- )
-
- if (ca)
- {
- add_distribution_points(x509crl->distributionPoints, ca->crluris);
- }
-
- enumerator = x509->create_crl_uri_enumerator(x509);
- while (enumerator->enumerate(enumerator, &cdp))
- {
- add_distribution_point(x509crl->distributionPoints, cdp->uri);
- }
- enumerator->destroy(enumerator);
-
- lock_authcert_list("verify_by_crl");
-
- issuer_cert = get_authcert(issuer, authKeyID, X509_CA);
- trusted = issuer_cert ? cert_crl->issued_by(cert_crl, issuer_cert->cert)
- : FALSE;
-
- unlock_authcert_list("verify_by_crl");
-
- if (trusted)
- {
- cert_status_t status;
-
- DBG(DBG_CONTROL,
- DBG_log("crl signature is valid")
- )
-
- /* return the expiration date */
- valid = cert_crl->get_validity(cert_crl, NULL, NULL, until);
-
- /* has the certificate been revoked? */
- status = check_revocation(crl, x509->get_serial(x509), revocationDate
- , revocationReason);
-
- if (valid)
- {
- unlock_crl_list("verify_by_crl");
- DBG(DBG_CONTROL,
- DBG_log("crl is valid: until %T", until, FALSE)
- )
- }
- else
- {
- fetch_req_t *req;
-
- DBG(DBG_CONTROL,
- DBG_log("crl is stale: since %T", until, FALSE)
- )
-
- /* try to fetch a crl update */
- req = build_crl_fetch_request(issuer, authKeyID,
- x509crl->distributionPoints);
- unlock_crl_list("verify_by_crl");
-
- add_crl_fetch_request(req);
- wake_fetch_thread("verify_by_crl");
- }
- return status;
- }
- else
- {
- unlock_crl_list("verify_by_crl");
- plog("crl signature is invalid");
- return CERT_UNKNOWN;
- }
- }
-}
-
-/*
- * list all X.509 crls in the chained list
- */
-void list_crls(bool utc, bool strict)
-{
- x509crl_t *x509crl;
-
- lock_crl_list("list_crls");
- x509crl = x509crls;
-
- if (x509crl)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of X.509 CRLs:");
- }
-
- while (x509crl)
- {
- certificate_t *cert_crl = x509crl->crl;
- crl_t *crl = (crl_t*)cert_crl;
- chunk_t serial, authKeyID;
- time_t thisUpdate, nextUpdate;
- u_int revoked = 0;
- enumerator_t *enumerator;
-
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, " issuer: \"%Y\"",
- cert_crl->get_issuer(cert_crl));
- serial = chunk_skip_zero(crl->get_serial(crl));
- if (serial.ptr)
- {
- whack_log(RC_COMMENT, " serial: %#B", &serial);
- }
-
- /* count number of revoked certificates in CRL */
- enumerator = crl->create_enumerator(crl);
- while (enumerator->enumerate(enumerator, NULL, NULL, NULL))
- {
- revoked++;
- }
- enumerator->destroy(enumerator);
- whack_log(RC_COMMENT, " revoked: %d certificates", revoked);
-
- list_distribution_points(x509crl->distributionPoints);
-
- cert_crl->get_validity(cert_crl, NULL, &thisUpdate, &nextUpdate);
- whack_log(RC_COMMENT, " updates: this %T", &thisUpdate, utc);
- whack_log(RC_COMMENT, " next %T %s", &nextUpdate, utc,
- check_expiry(nextUpdate, CRL_WARNING_INTERVAL, strict));
- authKeyID = crl->get_authKeyIdentifier(crl);
- if (authKeyID.ptr)
- {
- whack_log(RC_COMMENT, " authkey: %#B", &authKeyID);
- }
-
- x509crl = x509crl->next;
- }
- unlock_crl_list("list_crls");
-}
-