/* crypto/x509/x509_cmp.c */
/* 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/buf.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>


int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
	{
	int i;
	X509_CINF *ai,*bi;

	ai=a->cert_info;
	bi=b->cert_info;
	i=M_ASN1_INTEGER_cmp(ai->serialNumber,bi->serialNumber);
	if (i) return(i);
	return(X509_NAME_cmp(ai->issuer,bi->issuer));
	}

#ifndef OPENSSL_NO_MD5
unsigned long X509_issuer_and_serial_hash(X509 *a)
	{
	unsigned long ret=0;
	EVP_MD_CTX ctx;
	unsigned char md[16];
	char *f;

	EVP_MD_CTX_init(&ctx);
	f=X509_NAME_oneline(a->cert_info->issuer,NULL,0);
	if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
		goto err;
	if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,strlen(f)))
		goto err;
	OPENSSL_free(f);
	if(!EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data,
		(unsigned long)a->cert_info->serialNumber->length))
		goto err;
	if (!EVP_DigestFinal_ex(&ctx,&(md[0]),NULL))
		goto err;
	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
		)&0xffffffffL;
	err:
	EVP_MD_CTX_cleanup(&ctx);
	return(ret);
	}
#endif
	
int X509_issuer_name_cmp(const X509 *a, const X509 *b)
	{
	return(X509_NAME_cmp(a->cert_info->issuer,b->cert_info->issuer));
	}

int X509_subject_name_cmp(const X509 *a, const X509 *b)
	{
	return(X509_NAME_cmp(a->cert_info->subject,b->cert_info->subject));
	}

int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
	{
	return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer));
	}

#ifndef OPENSSL_NO_SHA
int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
	{
	return memcmp(a->sha1_hash, b->sha1_hash, 20);
	}
#endif

X509_NAME *X509_get_issuer_name(X509 *a)
	{
	return(a->cert_info->issuer);
	}

unsigned long X509_issuer_name_hash(X509 *x)
	{
	return(X509_NAME_hash(x->cert_info->issuer));
	}

#ifndef OPENSSL_NO_MD5
unsigned long X509_issuer_name_hash_old(X509 *x)
	{
	return(X509_NAME_hash_old(x->cert_info->issuer));
	}
#endif

X509_NAME *X509_get_subject_name(X509 *a)
	{
	return(a->cert_info->subject);
	}

ASN1_INTEGER *X509_get_serialNumber(X509 *a)
	{
	return(a->cert_info->serialNumber);
	}

unsigned long X509_subject_name_hash(X509 *x)
	{
	return(X509_NAME_hash(x->cert_info->subject));
	}

#ifndef OPENSSL_NO_MD5
unsigned long X509_subject_name_hash_old(X509 *x)
	{
	return(X509_NAME_hash_old(x->cert_info->subject));
	}
#endif

#ifndef OPENSSL_NO_SHA
/* Compare two certificates: they must be identical for
 * this to work. NB: Although "cmp" operations are generally
 * prototyped to take "const" arguments (eg. for use in
 * STACKs), the way X509 handling is - these operations may
 * involve ensuring the hashes are up-to-date and ensuring
 * certain cert information is cached. So this is the point
 * where the "depth-first" constification tree has to halt
 * with an evil cast.
 */
int X509_cmp(const X509 *a, const X509 *b)
{
	int rv;
	/* ensure hash is valid */
	X509_check_purpose((X509 *)a, -1, 0);
	X509_check_purpose((X509 *)b, -1, 0);

	rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
	if (rv)
		return rv;
	/* Check for match against stored encoding too */
	if (!a->cert_info->enc.modified && !b->cert_info->enc.modified)
		{
		rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len);
		if (rv)
			return rv;
		return memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc,
				a->cert_info->enc.len);
		}
	return rv;
}
#endif


int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
	{
	int ret;

	/* Ensure canonical encoding is present and up to date */

	if (!a->canon_enc || a->modified)
		{
		ret = i2d_X509_NAME((X509_NAME *)a, NULL);
		if (ret < 0)
			return -2;
		}

	if (!b->canon_enc || b->modified)
		{
		ret = i2d_X509_NAME((X509_NAME *)b, NULL);
		if (ret < 0)
			return -2;
		}

	ret = a->canon_enclen - b->canon_enclen;

	if (ret)
		return ret;

	return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);

	}

unsigned long X509_NAME_hash(X509_NAME *x)
	{
	unsigned long ret=0;
	unsigned char md[SHA_DIGEST_LENGTH];

	/* Make sure X509_NAME structure contains valid cached encoding */
	i2d_X509_NAME(x,NULL);
	if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
		NULL))
		return 0;

	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
		)&0xffffffffL;
	return(ret);
	}


#ifndef OPENSSL_NO_MD5
/* I now DER encode the name and hash it.  Since I cache the DER encoding,
 * this is reasonably efficient. */

unsigned long X509_NAME_hash_old(X509_NAME *x)
	{
	EVP_MD_CTX md_ctx;
	unsigned long ret=0;
	unsigned char md[16];

	/* Make sure X509_NAME structure contains valid cached encoding */
	i2d_X509_NAME(x,NULL);
	EVP_MD_CTX_init(&md_ctx);
	/* EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); */
	if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
	    && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
	    && EVP_DigestFinal_ex(&md_ctx,md,NULL))
		ret=(((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
		     ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
		     )&0xffffffffL;
	EVP_MD_CTX_cleanup(&md_ctx);

	return(ret);
	}
#endif

/* Search a stack of X509 for a match */
X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
		ASN1_INTEGER *serial)
	{
	size_t i;
	X509_CINF cinf;
	X509 x,*x509=NULL;

	if(!sk) return NULL;

	x.cert_info= &cinf;
	cinf.serialNumber=serial;
	cinf.issuer=name;

	for (i=0; i<sk_X509_num(sk); i++)
		{
		x509=sk_X509_value(sk,i);
		if (X509_issuer_and_serial_cmp(x509,&x) == 0)
			return(x509);
		}
	return(NULL);
	}

X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
	{
	X509 *x509;
	size_t i;

	for (i=0; i<sk_X509_num(sk); i++)
		{
		x509=sk_X509_value(sk,i);
		if (X509_NAME_cmp(X509_get_subject_name(x509),name) == 0)
			return(x509);
		}
	return(NULL);
	}

EVP_PKEY *X509_get_pubkey(X509 *x)
	{
	if ((x == NULL) || (x->cert_info == NULL))
		return(NULL);
	return(X509_PUBKEY_get(x->cert_info->key));
	}

ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
	{
	if(!x) return NULL;
	return x->cert_info->key->public_key;
	}


int X509_check_private_key(X509 *x, EVP_PKEY *k)
	{
	EVP_PKEY *xk;
	int ret;

	xk=X509_get_pubkey(x);

	if (xk)
		ret = EVP_PKEY_cmp(xk, k);
	else
		ret = -2;

	switch (ret)
		{
	case 1:
		break;
	case 0:
		OPENSSL_PUT_ERROR(X509, X509_check_private_key, X509_R_KEY_VALUES_MISMATCH);
		break;
	case -1:
		OPENSSL_PUT_ERROR(X509, X509_check_private_key, X509_R_KEY_TYPE_MISMATCH);
		break;
	case -2:
	        OPENSSL_PUT_ERROR(X509, X509_check_private_key, X509_R_UNKNOWN_KEY_TYPE);
		}
	if (xk)
		EVP_PKEY_free(xk);
	if (ret > 0)
		return 1;
	return 0;
	}

/* Check a suite B algorithm is permitted: pass in a public key and
 * the NID of its signature (or 0 if no signature). The pflags is
 * a pointer to a flags field which must contain the suite B verification
 * flags.
 */

#ifndef OPENSSL_NO_EC

static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags)
	{
	const EC_GROUP *grp = NULL;
	int curve_nid;
	if (pkey && pkey->type == EVP_PKEY_EC)
		grp = EC_KEY_get0_group(pkey->pkey.ec);
	if (!grp)
		return X509_V_ERR_SUITE_B_INVALID_ALGORITHM;
	curve_nid = EC_GROUP_get_curve_name(grp);
	/* Check curve is consistent with LOS */
	if (curve_nid == NID_secp384r1) /* P-384 */
		{
		/* Check signature algorithm is consistent with
		 * curve.
		 */
		if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384)
			return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
		if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS))
			return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
		/* If we encounter P-384 we cannot use P-256 later */
		*pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY;
		}
	else if (curve_nid == NID_X9_62_prime256v1) /* P-256 */
		{
		if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256)
			return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
		if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY))
			return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
		}
	else
		return X509_V_ERR_SUITE_B_INVALID_CURVE;

	return X509_V_OK;
	}

int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
							unsigned long flags)
	{
	int rv, sign_nid;
	size_t i;
	EVP_PKEY *pk = NULL;
	unsigned long tflags;
	if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
		return X509_V_OK;
	tflags = flags;
	/* If no EE certificate passed in must be first in chain */
	if (x == NULL)
		{
		x = sk_X509_value(chain, 0);
		i = 1;
		}
	else
		i = 0;

	if (X509_get_version(x) != 2)
		{
		rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
		/* Correct error depth */
		i = 0;
		goto end;
		}

	pk = X509_get_pubkey(x);
	/* Check EE key only */
	rv = check_suite_b(pk, -1, &tflags);
	if (rv != X509_V_OK)
		{
		/* Correct error depth */
		i = 0;
		goto end;
		}
	for(; i < sk_X509_num(chain); i++)
		{
		sign_nid = X509_get_signature_nid(x);
		x = sk_X509_value(chain, i);
		if (X509_get_version(x) != 2)
			{
			rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
			goto end;
			}
		EVP_PKEY_free(pk);
		pk = X509_get_pubkey(x);
		rv = check_suite_b(pk, sign_nid, &tflags);
		if (rv != X509_V_OK)
			goto end;
		}

	/* Final check: root CA signature */
	rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags);
	end:
	if (pk)
		EVP_PKEY_free(pk);
	if (rv != X509_V_OK)
		{
		/* Invalid signature or LOS errors are for previous cert */
		if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM
		    || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i)
			i--;
		/* If we have LOS error and flags changed then we are signing
		 * P-384 with P-256. Use more meaninggul error.
		 */
		if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags)
			rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256;
		if (perror_depth)
			*perror_depth = i;
		}
	return rv;
	}

int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
	{
	int sign_nid;
	if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
		return X509_V_OK;
	sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm);
	return check_suite_b(pk, sign_nid, &flags);
	}

#else
int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
							unsigned long flags)
	{
	return 0;
	}

int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
	{
	return 0;
	}

#endif
/* Not strictly speaking an "up_ref" as a STACK doesn't have a reference
 * count but it has the same effect by duping the STACK and upping the ref
 * of each X509 structure.
 */
STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain)
	{
	STACK_OF(X509) *ret;
	size_t i;
	ret = sk_X509_dup(chain);
	for (i = 0; i < sk_X509_num(ret); i++)
		{
		X509 *x = sk_X509_value(ret, i);
		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
		}
	return ret;
	}
