/* 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/thread.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>

#include "../internal.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) = {
	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 struct CRYPTO_STATIC_MUTEX g_crl_sort_lock = CRYPTO_STATIC_MUTEX_INIT;

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.
	 */

	CRYPTO_STATIC_MUTEX_lock_read(&g_crl_sort_lock);
	const int is_sorted = sk_X509_REVOKED_is_sorted(crl->crl->revoked);
	CRYPTO_STATIC_MUTEX_unlock(&g_crl_sort_lock);

	if (!is_sorted)
		{
		CRYPTO_STATIC_MUTEX_lock_write(&g_crl_sort_lock);
		if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
			{
			sk_X509_REVOKED_sort(crl->crl->revoked);
			}
		CRYPTO_STATIC_MUTEX_unlock(&g_crl_sort_lock);
		}

	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)
