Example #1
0
/*
 * check if any crls are about to expire
 */
void
check_crls(void)
{
#ifdef HAVE_THREADS
    x509crl_t *crl;
    time_t current_time = time(NULL);

    lock_crl_list("check_crls");
    crl = x509crls;

    while (crl != NULL)
    {
	time_t time_left = crl->nextUpdate - current_time;
	u_char buf[ASN1_BUF_LEN];

	DBG(DBG_X509,
	    dntoa(buf, ASN1_BUF_LEN, crl->issuer);
	    DBG_log("issuer: '%s'",buf);
	    if (crl->authKeyID.ptr != NULL)
	    {
		datatot(crl->authKeyID.ptr, crl->authKeyID.len, ':'
		    , buf, ASN1_BUF_LEN);
		DBG_log("authkey: %s", buf);
	    }
	    DBG_log("%ld seconds left", time_left)
	)
	if (time_left < 2*crl_check_interval)
	    add_crl_fetch_request(crl->issuer, crl->distributionPoints);
	crl = crl->next;
    }
    unlock_crl_list("check_crls");
#endif
}
Example #2
0
File: x509.c Project: mkj/libreswan
void free_crls(void)
{
	lock_crl_list("free_crls");

	while (x509crls != NULL)
		free_first_crl();

	unlock_crl_list("free_crls");
}
Example #3
0
File: x509.c Project: mkj/libreswan
/*
 * verify if a cert hasn't been revoked by a crl
 */
static bool verify_by_crl(/*const*/ x509cert_t *cert, bool strict,
				    realtime_t *until)
{
	x509crl_t *crl;
	char ibuf[ASN1_BUF_LEN], cbuf[ASN1_BUF_LEN];

	lock_crl_list("verify_by_crl");
	crl = get_x509crl(cert->issuer, cert->authKeySerialNumber,
			  cert->authKeyID);

	dntoa(ibuf, ASN1_BUF_LEN, cert->issuer);

	if (crl == NULL) {
		unlock_crl_list("verify_by_crl");
		libreswan_log("no crl from issuer \"%s\" found (strict=%s)",
			      ibuf,
			      strict ? "yes" : "no");

#if defined(LIBCURL) || defined(LDAP_VER)
		if (cert->crlDistributionPoints != NULL) {
			add_crl_fetch_request(cert->issuer,
					      cert->crlDistributionPoints);
			wake_fetch_thread("verify_by_crl");
		}
#endif
		if (strict)
			return FALSE;
	} else {
		x509cert_t *issuer_cert;
		bool valid;

		DBG(DBG_X509,
		    DBG_log("issuer crl \"%s\" found", ibuf));

#if defined(LIBCURL) || defined(LDAP_VER)
		add_distribution_points(cert->crlDistributionPoints,
					&crl->distributionPoints);
#endif

		lock_authcert_list("verify_by_crl");

		issuer_cert = get_authcert(crl->issuer,
					   crl->authKeySerialNumber,
					   crl->authKeyID, AUTH_CA);
		dntoa(cbuf, ASN1_BUF_LEN, crl->issuer);
		valid = check_signature(crl->tbsCertList, crl->signature,
					crl->algorithm, issuer_cert);

		unlock_authcert_list("verify_by_crl");

		if (valid) {
			bool revoked_crl, expired_crl;

			DBG(DBG_X509,
			    DBG_log("valid crl signature on \"%s\"", cbuf));

			/* with strict crl policy the public key must have the same
			 * lifetime as the crl
			 */
			if (strict && realbefore(crl->nextUpdate, *until))
				*until = crl->nextUpdate;

			/* has the certificate been revoked? */
			revoked_crl = x509_check_revocation(crl,
							    cert->serialNumber);

			/* is the crl still valid? */
			expired_crl = realbefore(crl->nextUpdate, realnow());

			unlock_crl_list("verify_by_crl");

			if (expired_crl) {
				char tbuf[REALTIMETOA_BUF];

				libreswan_log(
					"crl update for \"%s\" is overdue since %s",
					cbuf,
					realtimetoa(crl->nextUpdate, TRUE,
						tbuf, sizeof(tbuf)));

#if defined(LIBCURL) || defined(LDAP_VER)
				/* try to fetch a crl update */
				if (cert->crlDistributionPoints != NULL) {
					add_crl_fetch_request(cert->issuer,
							      cert->crlDistributionPoints);
					wake_fetch_thread("verify_by_crl");
				}
#endif
			} else {
				DBG(DBG_X509,
				    DBG_log("crl is \"%s\" valid", cbuf));
			}

			if (revoked_crl || (strict && expired_crl)) {
				/* remove any cached public keys */
				remove_x509_public_key(cert);
				return FALSE;
			}
		} else {
			unlock_crl_list("verify_by_crl");
			libreswan_log("invalid crl signature on \"%s\"", cbuf);
			if (strict)
				return FALSE;
		}
	}
	return TRUE;
}
Example #4
0
File: x509.c Project: mkj/libreswan
/*
 * Insert X.509 CRL into chained list
 */
bool insert_crl(chunk_t blob, chunk_t crl_uri)
{
	x509crl_t *crl = alloc_thing(x509crl_t, "x509crl");

	*crl = empty_x509crl;

	if (parse_x509crl(blob, 0, crl)) {
		x509cert_t *issuer_cert;
		x509crl_t *oldcrl;
		bool valid_sig;
		generalName_t *gn;

		/* add distribution point */
		gn = alloc_thing(generalName_t, "generalName");
		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) {
			chunk_t *n = &crl->distributionPoints->name;

			loglog(RC_LOG_SERIOUS,
			       "CRL rejected: crl issuer cacert not found for %.*s",
			       (int)n->len, (char *)n->ptr);

			free_crl(crl);
			unlock_authcert_list("insert_crl");
			return FALSE;
		}
		DBG(DBG_X509,
		    DBG_log("crl issuer cacert found"));

		/* check the issuer's signature of the crl */
		valid_sig = check_signature(crl->tbsCertList, crl->signature,
					    crl->algorithm, issuer_cert);
		unlock_authcert_list("insert_crl");

		if (!valid_sig) {
			free_crl(crl);
			return FALSE;
		}
		DBG(DBG_X509,
		    DBG_log("valid crl signature"));

		lock_crl_list("insert_crl");
		oldcrl = get_x509crl(crl->issuer, crl->authKeySerialNumber,
				     crl->authKeyID);

		if (oldcrl != NULL) {
			if (realbefore(oldcrl->thisUpdate, crl->thisUpdate)) {
				/* old CRL is older than new CRL: replace */
#if defined(LIBCURL) || defined(LDAP_VER)
				/* keep any known CRL distribution points */
				add_distribution_points(
					oldcrl->distributionPoints,
					&crl->distributionPoints);
#endif

				/* now delete the old CRL */
				free_first_crl();
				DBG(DBG_X509,
				    DBG_log("thisUpdate is newer - existing crl deleted"));
			} else {
				/* old CRL is not older than new CRL: keep old one */
				unlock_crl_list("insert_crls");
				DBG(DBG_X509,
				    DBG_log("thisUpdate is not newer - existing crl not replaced"));
				free_crl(crl);
				/*
				 * is the fetched crl valid?
				 * now + 2 * crl_check_interval < oldcrl->nextUpdate
				 */
				return realbefore(realtimesum(realnow(), deltatimescale(2, 1, crl_check_interval)), oldcrl->nextUpdate);
			}
		}

		/* insert new CRL */
		crl->next = x509crls;
		x509crls = crl;

		unlock_crl_list("insert_crl");

		/*
		 * is the new crl valid?
		 * now + 2 * crl_check_interval < crl->nextUpdate
		 */
		return realbefore(realtimesum(realnow(), deltatimescale(2, 1, crl_check_interval)), crl->nextUpdate);
	} else {
		loglog(RC_LOG_SERIOUS, "  error in X.509 crl %s",
		       (char *)crl_uri.ptr);
		free_crl(crl);
		return FALSE;
	}
}