/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.] */

#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>

/* Method to handle CRL access.
 * In general a CRL could be very large (several Mb) and can consume large
 * amounts of resources if stored in memory by multiple processes.
 * This method allows general CRL operations to be redirected to more
 * efficient callbacks: for example a CRL entry database.
 */

#define X509_CRL_METHOD_DYNAMIC		1

struct x509_crl_method_st
	{
	int flags;
	int (*crl_init)(X509_CRL *crl);
	int (*crl_free)(X509_CRL *crl);
	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
				ASN1_INTEGER *ser, X509_NAME *issuer);
	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
	};

static int X509_REVOKED_cmp(const X509_REVOKED **a,
				const X509_REVOKED **b);
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);

ASN1_SEQUENCE(X509_REVOKED) = {
	ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
	ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
	ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
} ASN1_SEQUENCE_END(X509_REVOKED)

static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
static int def_crl_lookup(X509_CRL *crl,
		X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer);

static const X509_CRL_METHOD int_crl_meth =
	{
	0,
	0,0,
	def_crl_lookup,
	def_crl_verify
	};

static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;

/* The X509_CRL_INFO structure needs a bit of customisation.
 * Since we cache the original encoding the signature wont be affected by
 * reordering of the revoked field.
 */
static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
								void *exarg)
{
	X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;

	if(!a || !a->revoked) return 1;
	switch(operation) {
		/* Just set cmp function here. We don't sort because that
		 * would affect the output of X509_CRL_print().
		 */
		case ASN1_OP_D2I_POST:
		(void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp);
		break;
	}
	return 1;
}


ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
	ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
	ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
	ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
	ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
	ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
	ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
	ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)

/* Set CRL entry issuer according to CRL certificate issuer extension.
 * Check for unhandled critical CRL entry extensions.
 */

static int crl_set_issuers(X509_CRL *crl)
	{

	size_t i, k;
	int j;
	GENERAL_NAMES *gens, *gtmp;
	STACK_OF(X509_REVOKED) *revoked;

	revoked = X509_CRL_get_REVOKED(crl);

	gens = NULL;
	for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
		{
		X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
		STACK_OF(X509_EXTENSION) *exts;
		ASN1_ENUMERATED *reason;
		X509_EXTENSION *ext;
		gtmp = X509_REVOKED_get_ext_d2i(rev, 
						NID_certificate_issuer,
						&j, NULL);
		if (!gtmp && (j != -1))
			{
			crl->flags |= EXFLAG_INVALID;
			return 1;
			}

		if (gtmp)
			{
			gens = gtmp;
			if (!crl->issuers)
				{
				crl->issuers = sk_GENERAL_NAMES_new_null();
				if (!crl->issuers)
					return 0;
				}
			if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
				return 0;
			}
		rev->issuer = gens;

		reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
								&j, NULL);
		if (!reason && (j != -1))
			{
			crl->flags |= EXFLAG_INVALID;
			return 1;
			}

		if (reason)
			{
			rev->reason = ASN1_ENUMERATED_get(reason);
			ASN1_ENUMERATED_free(reason);
			}
		else
			rev->reason = CRL_REASON_NONE;	

		/* Check for critical CRL entry extensions */

		exts = rev->extensions;

		for (k = 0; k < sk_X509_EXTENSION_num(exts); k++)
			{
			ext = sk_X509_EXTENSION_value(exts, k);
			if (ext->critical > 0)
				{
				if (OBJ_obj2nid(ext->object) ==
					NID_certificate_issuer)
					continue;
				crl->flags |= EXFLAG_CRITICAL;
				break;
				}
			}


		}

	return 1;

	}

/* The X509_CRL structure needs a bit of customisation. Cache some extensions
 * and hash of the whole CRL.
 */
static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
								void *exarg)
	{
	X509_CRL *crl = (X509_CRL *)*pval;
	STACK_OF(X509_EXTENSION) *exts;
	X509_EXTENSION *ext;
	size_t idx;

	switch(operation)
		{
		case ASN1_OP_NEW_POST:
		crl->idp = NULL;
		crl->akid = NULL;
		crl->flags = 0;
		crl->idp_flags = 0;
		crl->idp_reasons = CRLDP_ALL_REASONS;
		crl->meth = default_crl_method;
		crl->meth_data = NULL;
		crl->issuers = NULL;
		crl->crl_number = NULL;
		crl->base_crl_number = NULL;
		break;

		case ASN1_OP_D2I_POST:
		X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
		crl->idp = X509_CRL_get_ext_d2i(crl,
				NID_issuing_distribution_point, NULL, NULL);
		if (crl->idp)
			setup_idp(crl, crl->idp);

		crl->akid = X509_CRL_get_ext_d2i(crl,
				NID_authority_key_identifier, NULL, NULL);	

		crl->crl_number = X509_CRL_get_ext_d2i(crl,
				NID_crl_number, NULL, NULL);	

		crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
				NID_delta_crl, NULL, NULL);	
		/* Delta CRLs must have CRL number */
		if (crl->base_crl_number && !crl->crl_number)
			crl->flags |= EXFLAG_INVALID;

		/* See if we have any unhandled critical CRL extensions and 
		 * indicate this in a flag. We only currently handle IDP so
		 * anything else critical sets the flag.
		 *
		 * This code accesses the X509_CRL structure directly:
		 * applications shouldn't do this.
		 */

		exts = crl->crl->extensions;

		for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
			{
			int nid;
			ext = sk_X509_EXTENSION_value(exts, idx);
			nid = OBJ_obj2nid(ext->object);
			if (nid == NID_freshest_crl)
				crl->flags |= EXFLAG_FRESHEST;
			if (ext->critical > 0)
				{
				/* We handle IDP and deltas */
				if ((nid == NID_issuing_distribution_point)
					|| (nid == NID_authority_key_identifier)
					|| (nid == NID_delta_crl))
					break;;
				crl->flags |= EXFLAG_CRITICAL;
				break;
				}
			}


		if (!crl_set_issuers(crl))
			return 0;

		if (crl->meth->crl_init)
			{
			if (crl->meth->crl_init(crl) == 0)
				return 0;
			}
		break;

		case ASN1_OP_FREE_POST:
		if (crl->meth->crl_free)
			{
			if (!crl->meth->crl_free(crl))
				return 0;
			}
		if (crl->akid)
			AUTHORITY_KEYID_free(crl->akid);
		if (crl->idp)
			ISSUING_DIST_POINT_free(crl->idp);
		ASN1_INTEGER_free(crl->crl_number);
		ASN1_INTEGER_free(crl->base_crl_number);
		sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
		break;
		}
	return 1;
	}

/* Convert IDP into a more convenient form */

static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
	{
	int idp_only = 0;
	/* Set various flags according to IDP */
	crl->idp_flags |= IDP_PRESENT;
	if (idp->onlyuser > 0)
		{
		idp_only++;
		crl->idp_flags |= IDP_ONLYUSER;
		}
	if (idp->onlyCA > 0)
		{
		idp_only++;
		crl->idp_flags |= IDP_ONLYCA;
		}
	if (idp->onlyattr > 0)
		{
		idp_only++;
		crl->idp_flags |= IDP_ONLYATTR;
		}

	if (idp_only > 1)
		crl->idp_flags |= IDP_INVALID;

	if (idp->indirectCRL > 0)
		crl->idp_flags |= IDP_INDIRECT;

	if (idp->onlysomereasons)
		{
		crl->idp_flags |= IDP_REASONS;
		if (idp->onlysomereasons->length > 0)
			crl->idp_reasons = idp->onlysomereasons->data[0];
		if (idp->onlysomereasons->length > 1)
			crl->idp_reasons |=
				(idp->onlysomereasons->data[1] << 8);
		crl->idp_reasons &= CRLDP_ALL_REASONS;
		}

	DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
	}

ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
	ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
	ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
	ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)

IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED)
IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)

static int X509_REVOKED_cmp(const X509_REVOKED **a,
			const X509_REVOKED **b)
	{
	return(ASN1_STRING_cmp(
		(ASN1_STRING *)(*a)->serialNumber,
		(ASN1_STRING *)(*b)->serialNumber));
	}

int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
{
	X509_CRL_INFO *inf;
	inf = crl->crl;
	if(!inf->revoked)
		inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
	if(!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
		OPENSSL_PUT_ERROR(X509, X509_CRL_add0_revoked, ERR_R_MALLOC_FAILURE);
		return 0;
	}
	inf->enc.modified = 1;
	return 1;
}

int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
	{
	if (crl->meth->crl_verify)
		return crl->meth->crl_verify(crl, r);
	return 0;
	}

int X509_CRL_get0_by_serial(X509_CRL *crl,
		X509_REVOKED **ret, ASN1_INTEGER *serial)
	{
	if (crl->meth->crl_lookup)
		return crl->meth->crl_lookup(crl, ret, serial, NULL);
	return 0;
	}

int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
	{
	if (crl->meth->crl_lookup)
		return crl->meth->crl_lookup(crl, ret,
						X509_get_serialNumber(x),
						X509_get_issuer_name(x));
	return 0;
	}

static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
	{
	return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
		crl->sig_alg, crl->signature,crl->crl,r));
	}

static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
						X509_REVOKED *rev)
	{
	size_t i;

	if (!rev->issuer)
		{
		if (!nm)
			return 1;
		if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
			return 1;
		return 0;
		}

	if (!nm)
		nm = X509_CRL_get_issuer(crl);

	for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++)
		{
		GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
		if (gen->type != GEN_DIRNAME)
			continue;
		if (!X509_NAME_cmp(nm, gen->d.directoryName))
			return 1;
		}
	return 0;

	}

static int def_crl_lookup(X509_CRL *crl,
		X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer)
	{
	X509_REVOKED rtmp, *rev;
	size_t idx;
	rtmp.serialNumber = serial;
	/* Sort revoked into serial number order if not already sorted.
	 * Do this under a lock to avoid race condition.
 	 */
	if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
		{
		CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
		sk_X509_REVOKED_sort(crl->crl->revoked);
		CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
		}
	if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp))
		return 0;
	/* Need to look for matching name */
	for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++)
		{
		rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
		if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
			return 0;
		if (crl_revoked_issuer_match(crl, issuer, rev))
			{
			if (ret)
				*ret = rev;
			if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
				return 2;
			return 1;
			}
		}
	return 0;
	}

void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
	{
	if (meth == NULL)
		default_crl_method = &int_crl_meth;
	else 
		default_crl_method = meth;
	}

X509_CRL_METHOD *X509_CRL_METHOD_new(
	int (*crl_init)(X509_CRL *crl),
	int (*crl_free)(X509_CRL *crl),
	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
				ASN1_INTEGER *ser, X509_NAME *issuer),
	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
	{
	X509_CRL_METHOD *m;
	m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
	if (!m)
		return NULL;
	m->crl_init = crl_init;
	m->crl_free = crl_free;
	m->crl_lookup = crl_lookup;
	m->crl_verify = crl_verify;
	m->flags = X509_CRL_METHOD_DYNAMIC;
	return m;
	}

void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
	{
	if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
		return;
	OPENSSL_free(m);
	}

void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
	{
	crl->meth_data = dat;
	}

void *X509_CRL_get_meth_data(X509_CRL *crl)
	{
	return crl->meth_data;
	}

IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
IMPLEMENT_ASN1_SET_OF(X509_CRL)
