Home | History | Annotate | Download | only in x509
      1 /* crypto/x509/x509_cmp.c */
      2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      3  * All rights reserved.
      4  *
      5  * This package is an SSL implementation written
      6  * by Eric Young (eay (at) cryptsoft.com).
      7  * The implementation was written so as to conform with Netscapes SSL.
      8  *
      9  * This library is free for commercial and non-commercial use as long as
     10  * the following conditions are aheared to.  The following conditions
     11  * apply to all code found in this distribution, be it the RC4, RSA,
     12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
     13  * included with this distribution is covered by the same copyright terms
     14  * except that the holder is Tim Hudson (tjh (at) cryptsoft.com).
     15  *
     16  * Copyright remains Eric Young's, and as such any Copyright notices in
     17  * the code are not to be removed.
     18  * If this package is used in a product, Eric Young should be given attribution
     19  * as the author of the parts of the library used.
     20  * This can be in the form of a textual message at program startup or
     21  * in documentation (online or textual) provided with the package.
     22  *
     23  * Redistribution and use in source and binary forms, with or without
     24  * modification, are permitted provided that the following conditions
     25  * are met:
     26  * 1. Redistributions of source code must retain the copyright
     27  *    notice, this list of conditions and the following disclaimer.
     28  * 2. Redistributions in binary form must reproduce the above copyright
     29  *    notice, this list of conditions and the following disclaimer in the
     30  *    documentation and/or other materials provided with the distribution.
     31  * 3. All advertising materials mentioning features or use of this software
     32  *    must display the following acknowledgement:
     33  *    "This product includes cryptographic software written by
     34  *     Eric Young (eay (at) cryptsoft.com)"
     35  *    The word 'cryptographic' can be left out if the rouines from the library
     36  *    being used are not cryptographic related :-).
     37  * 4. If you include any Windows specific code (or a derivative thereof) from
     38  *    the apps directory (application code) you must include an acknowledgement:
     39  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     40  *
     41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     51  * SUCH DAMAGE.
     52  *
     53  * The licence and distribution terms for any publically available version or
     54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
     55  * copied and put under another distribution licence
     56  * [including the GNU Public Licence.] */
     57 
     58 #include <openssl/asn1.h>
     59 #include <openssl/buf.h>
     60 #include <openssl/digest.h>
     61 #include <openssl/err.h>
     62 #include <openssl/mem.h>
     63 #include <openssl/obj.h>
     64 #include <openssl/stack.h>
     65 #include <openssl/x509.h>
     66 #include <openssl/x509v3.h>
     67 
     68 
     69 int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
     70 	{
     71 	int i;
     72 	X509_CINF *ai,*bi;
     73 
     74 	ai=a->cert_info;
     75 	bi=b->cert_info;
     76 	i=M_ASN1_INTEGER_cmp(ai->serialNumber,bi->serialNumber);
     77 	if (i) return(i);
     78 	return(X509_NAME_cmp(ai->issuer,bi->issuer));
     79 	}
     80 
     81 unsigned long X509_issuer_and_serial_hash(X509 *a)
     82 	{
     83 	unsigned long ret=0;
     84 	EVP_MD_CTX ctx;
     85 	unsigned char md[16];
     86 	char *f;
     87 
     88 	EVP_MD_CTX_init(&ctx);
     89 	f=X509_NAME_oneline(a->cert_info->issuer,NULL,0);
     90 	if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
     91 		goto err;
     92 	if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,strlen(f)))
     93 		goto err;
     94 	OPENSSL_free(f);
     95 	if(!EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data,
     96 		(unsigned long)a->cert_info->serialNumber->length))
     97 		goto err;
     98 	if (!EVP_DigestFinal_ex(&ctx,&(md[0]),NULL))
     99 		goto err;
    100 	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
    101 		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
    102 		)&0xffffffffL;
    103 	err:
    104 	EVP_MD_CTX_cleanup(&ctx);
    105 	return(ret);
    106 	}
    107 
    108 int X509_issuer_name_cmp(const X509 *a, const X509 *b)
    109 	{
    110 	return(X509_NAME_cmp(a->cert_info->issuer,b->cert_info->issuer));
    111 	}
    112 
    113 int X509_subject_name_cmp(const X509 *a, const X509 *b)
    114 	{
    115 	return(X509_NAME_cmp(a->cert_info->subject,b->cert_info->subject));
    116 	}
    117 
    118 int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
    119 	{
    120 	return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer));
    121 	}
    122 
    123 int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
    124 	{
    125 	return memcmp(a->sha1_hash, b->sha1_hash, 20);
    126 	}
    127 
    128 X509_NAME *X509_get_issuer_name(X509 *a)
    129 	{
    130 	return(a->cert_info->issuer);
    131 	}
    132 
    133 unsigned long X509_issuer_name_hash(X509 *x)
    134 	{
    135 	return(X509_NAME_hash(x->cert_info->issuer));
    136 	}
    137 
    138 unsigned long X509_issuer_name_hash_old(X509 *x)
    139 	{
    140 	return(X509_NAME_hash_old(x->cert_info->issuer));
    141 	}
    142 
    143 X509_NAME *X509_get_subject_name(X509 *a)
    144 	{
    145 	return(a->cert_info->subject);
    146 	}
    147 
    148 ASN1_INTEGER *X509_get_serialNumber(X509 *a)
    149 	{
    150 	return(a->cert_info->serialNumber);
    151 	}
    152 
    153 unsigned long X509_subject_name_hash(X509 *x)
    154 	{
    155 	return(X509_NAME_hash(x->cert_info->subject));
    156 	}
    157 
    158 unsigned long X509_subject_name_hash_old(X509 *x)
    159 	{
    160 	return(X509_NAME_hash_old(x->cert_info->subject));
    161 	}
    162 
    163 /* Compare two certificates: they must be identical for
    164  * this to work. NB: Although "cmp" operations are generally
    165  * prototyped to take "const" arguments (eg. for use in
    166  * STACKs), the way X509 handling is - these operations may
    167  * involve ensuring the hashes are up-to-date and ensuring
    168  * certain cert information is cached. So this is the point
    169  * where the "depth-first" constification tree has to halt
    170  * with an evil cast.
    171  */
    172 int X509_cmp(const X509 *a, const X509 *b)
    173 {
    174 	int rv;
    175 	/* ensure hash is valid */
    176 	X509_check_purpose((X509 *)a, -1, 0);
    177 	X509_check_purpose((X509 *)b, -1, 0);
    178 
    179 	rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
    180 	if (rv)
    181 		return rv;
    182 	/* Check for match against stored encoding too */
    183 	if (!a->cert_info->enc.modified && !b->cert_info->enc.modified)
    184 		{
    185 		rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len);
    186 		if (rv)
    187 			return rv;
    188 		return memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc,
    189 				a->cert_info->enc.len);
    190 		}
    191 	return rv;
    192 }
    193 
    194 
    195 int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
    196 	{
    197 	int ret;
    198 
    199 	/* Ensure canonical encoding is present and up to date */
    200 
    201 	if (!a->canon_enc || a->modified)
    202 		{
    203 		ret = i2d_X509_NAME((X509_NAME *)a, NULL);
    204 		if (ret < 0)
    205 			return -2;
    206 		}
    207 
    208 	if (!b->canon_enc || b->modified)
    209 		{
    210 		ret = i2d_X509_NAME((X509_NAME *)b, NULL);
    211 		if (ret < 0)
    212 			return -2;
    213 		}
    214 
    215 	ret = a->canon_enclen - b->canon_enclen;
    216 
    217 	if (ret)
    218 		return ret;
    219 
    220 	return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
    221 
    222 	}
    223 
    224 unsigned long X509_NAME_hash(X509_NAME *x)
    225 	{
    226 	unsigned long ret=0;
    227 	unsigned char md[SHA_DIGEST_LENGTH];
    228 
    229 	/* Make sure X509_NAME structure contains valid cached encoding */
    230 	i2d_X509_NAME(x,NULL);
    231 	if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
    232 		NULL))
    233 		return 0;
    234 
    235 	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
    236 		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
    237 		)&0xffffffffL;
    238 	return(ret);
    239 	}
    240 
    241 
    242 /* I now DER encode the name and hash it.  Since I cache the DER encoding,
    243  * this is reasonably efficient. */
    244 
    245 unsigned long X509_NAME_hash_old(X509_NAME *x)
    246 	{
    247 	EVP_MD_CTX md_ctx;
    248 	unsigned long ret=0;
    249 	unsigned char md[16];
    250 
    251 	/* Make sure X509_NAME structure contains valid cached encoding */
    252 	i2d_X509_NAME(x,NULL);
    253 	EVP_MD_CTX_init(&md_ctx);
    254 	/* EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); */
    255 	if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
    256 	    && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
    257 	    && EVP_DigestFinal_ex(&md_ctx,md,NULL))
    258 		ret=(((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
    259 		     ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
    260 		     )&0xffffffffL;
    261 	EVP_MD_CTX_cleanup(&md_ctx);
    262 
    263 	return(ret);
    264 	}
    265 
    266 /* Search a stack of X509 for a match */
    267 X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
    268 		ASN1_INTEGER *serial)
    269 	{
    270 	size_t i;
    271 	X509_CINF cinf;
    272 	X509 x,*x509=NULL;
    273 
    274 	if(!sk) return NULL;
    275 
    276 	x.cert_info= &cinf;
    277 	cinf.serialNumber=serial;
    278 	cinf.issuer=name;
    279 
    280 	for (i=0; i<sk_X509_num(sk); i++)
    281 		{
    282 		x509=sk_X509_value(sk,i);
    283 		if (X509_issuer_and_serial_cmp(x509,&x) == 0)
    284 			return(x509);
    285 		}
    286 	return(NULL);
    287 	}
    288 
    289 X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
    290 	{
    291 	X509 *x509;
    292 	size_t i;
    293 
    294 	for (i=0; i<sk_X509_num(sk); i++)
    295 		{
    296 		x509=sk_X509_value(sk,i);
    297 		if (X509_NAME_cmp(X509_get_subject_name(x509),name) == 0)
    298 			return(x509);
    299 		}
    300 	return(NULL);
    301 	}
    302 
    303 EVP_PKEY *X509_get_pubkey(X509 *x)
    304 	{
    305 	if ((x == NULL) || (x->cert_info == NULL))
    306 		return(NULL);
    307 	return(X509_PUBKEY_get(x->cert_info->key));
    308 	}
    309 
    310 ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
    311 	{
    312 	if(!x) return NULL;
    313 	return x->cert_info->key->public_key;
    314 	}
    315 
    316 
    317 int X509_check_private_key(X509 *x, EVP_PKEY *k)
    318 	{
    319 	EVP_PKEY *xk;
    320 	int ret;
    321 
    322 	xk=X509_get_pubkey(x);
    323 
    324 	if (xk)
    325 		ret = EVP_PKEY_cmp(xk, k);
    326 	else
    327 		ret = -2;
    328 
    329 	switch (ret)
    330 		{
    331 	case 1:
    332 		break;
    333 	case 0:
    334 		OPENSSL_PUT_ERROR(X509, X509_check_private_key, X509_R_KEY_VALUES_MISMATCH);
    335 		break;
    336 	case -1:
    337 		OPENSSL_PUT_ERROR(X509, X509_check_private_key, X509_R_KEY_TYPE_MISMATCH);
    338 		break;
    339 	case -2:
    340 	        OPENSSL_PUT_ERROR(X509, X509_check_private_key, X509_R_UNKNOWN_KEY_TYPE);
    341 		}
    342 	if (xk)
    343 		EVP_PKEY_free(xk);
    344 	if (ret > 0)
    345 		return 1;
    346 	return 0;
    347 	}
    348 
    349 /* Check a suite B algorithm is permitted: pass in a public key and
    350  * the NID of its signature (or 0 if no signature). The pflags is
    351  * a pointer to a flags field which must contain the suite B verification
    352  * flags.
    353  */
    354 
    355 
    356 static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags)
    357 	{
    358 	const EC_GROUP *grp = NULL;
    359 	int curve_nid;
    360 	if (pkey && pkey->type == EVP_PKEY_EC)
    361 		grp = EC_KEY_get0_group(pkey->pkey.ec);
    362 	if (!grp)
    363 		return X509_V_ERR_SUITE_B_INVALID_ALGORITHM;
    364 	curve_nid = EC_GROUP_get_curve_name(grp);
    365 	/* Check curve is consistent with LOS */
    366 	if (curve_nid == NID_secp384r1) /* P-384 */
    367 		{
    368 		/* Check signature algorithm is consistent with
    369 		 * curve.
    370 		 */
    371 		if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384)
    372 			return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
    373 		if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS))
    374 			return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
    375 		/* If we encounter P-384 we cannot use P-256 later */
    376 		*pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY;
    377 		}
    378 	else if (curve_nid == NID_X9_62_prime256v1) /* P-256 */
    379 		{
    380 		if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256)
    381 			return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
    382 		if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY))
    383 			return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
    384 		}
    385 	else
    386 		return X509_V_ERR_SUITE_B_INVALID_CURVE;
    387 
    388 	return X509_V_OK;
    389 	}
    390 
    391 int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
    392 							unsigned long flags)
    393 	{
    394 	int rv, sign_nid;
    395 	size_t i;
    396 	EVP_PKEY *pk = NULL;
    397 	unsigned long tflags;
    398 	if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
    399 		return X509_V_OK;
    400 	tflags = flags;
    401 	/* If no EE certificate passed in must be first in chain */
    402 	if (x == NULL)
    403 		{
    404 		x = sk_X509_value(chain, 0);
    405 		i = 1;
    406 		}
    407 	else
    408 		i = 0;
    409 
    410 	if (X509_get_version(x) != 2)
    411 		{
    412 		rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
    413 		/* Correct error depth */
    414 		i = 0;
    415 		goto end;
    416 		}
    417 
    418 	pk = X509_get_pubkey(x);
    419 	/* Check EE key only */
    420 	rv = check_suite_b(pk, -1, &tflags);
    421 	if (rv != X509_V_OK)
    422 		{
    423 		/* Correct error depth */
    424 		i = 0;
    425 		goto end;
    426 		}
    427 	for(; i < sk_X509_num(chain); i++)
    428 		{
    429 		sign_nid = X509_get_signature_nid(x);
    430 		x = sk_X509_value(chain, i);
    431 		if (X509_get_version(x) != 2)
    432 			{
    433 			rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
    434 			goto end;
    435 			}
    436 		EVP_PKEY_free(pk);
    437 		pk = X509_get_pubkey(x);
    438 		rv = check_suite_b(pk, sign_nid, &tflags);
    439 		if (rv != X509_V_OK)
    440 			goto end;
    441 		}
    442 
    443 	/* Final check: root CA signature */
    444 	rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags);
    445 	end:
    446 	if (pk)
    447 		EVP_PKEY_free(pk);
    448 	if (rv != X509_V_OK)
    449 		{
    450 		/* Invalid signature or LOS errors are for previous cert */
    451 		if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM
    452 		    || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i)
    453 			i--;
    454 		/* If we have LOS error and flags changed then we are signing
    455 		 * P-384 with P-256. Use more meaninggul error.
    456 		 */
    457 		if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags)
    458 			rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256;
    459 		if (perror_depth)
    460 			*perror_depth = i;
    461 		}
    462 	return rv;
    463 	}
    464 
    465 int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
    466 	{
    467 	int sign_nid;
    468 	if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
    469 		return X509_V_OK;
    470 	sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm);
    471 	return check_suite_b(pk, sign_nid, &flags);
    472 	}
    473 
    474 /* Not strictly speaking an "up_ref" as a STACK doesn't have a reference
    475  * count but it has the same effect by duping the STACK and upping the ref
    476  * of each X509 structure.
    477  */
    478 STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain)
    479 	{
    480 	STACK_OF(X509) *ret;
    481 	size_t i;
    482 	ret = sk_X509_dup(chain);
    483 	for (i = 0; i < sk_X509_num(ret); i++)
    484 		{
    485 		X509_up_ref(sk_X509_value(ret, i));
    486 		}
    487 	return ret;
    488 	}
    489