Home | History | Annotate | Download | only in evp
      1 /* crypto/evp/p_lib.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 
     59 #include <stdio.h>
     60 #include "cryptlib.h"
     61 #include <openssl/bn.h>
     62 #include <openssl/err.h>
     63 #include <openssl/objects.h>
     64 #include <openssl/evp.h>
     65 #include <openssl/asn1_mac.h>
     66 #include <openssl/x509.h>
     67 #ifndef OPENSSL_NO_RSA
     68 #include <openssl/rsa.h>
     69 #endif
     70 #ifndef OPENSSL_NO_DSA
     71 #include <openssl/dsa.h>
     72 #endif
     73 #ifndef OPENSSL_NO_DH
     74 #include <openssl/dh.h>
     75 #endif
     76 
     77 static void EVP_PKEY_free_it(EVP_PKEY *x);
     78 
     79 int EVP_PKEY_bits(EVP_PKEY *pkey)
     80 	{
     81 	if (0)
     82 		return 0;
     83 #ifndef OPENSSL_NO_RSA
     84 	else if (pkey->type == EVP_PKEY_RSA)
     85 		return(BN_num_bits(pkey->pkey.rsa->n));
     86 #endif
     87 #ifndef OPENSSL_NO_DSA
     88 	else if (pkey->type == EVP_PKEY_DSA)
     89 		return(BN_num_bits(pkey->pkey.dsa->p));
     90 #endif
     91 #ifndef OPENSSL_NO_EC
     92 	else if (pkey->type == EVP_PKEY_EC)
     93 		{
     94 		BIGNUM *order = BN_new();
     95 		const EC_GROUP *group;
     96 		int ret;
     97 
     98 		if (!order)
     99 			{
    100 			ERR_clear_error();
    101 			return 0;
    102 			}
    103 		group = EC_KEY_get0_group(pkey->pkey.ec);
    104 		if (!EC_GROUP_get_order(group, order, NULL))
    105 			{
    106 			ERR_clear_error();
    107 			return 0;
    108 			}
    109 
    110 		ret = BN_num_bits(order);
    111 		BN_free(order);
    112 		return ret;
    113 		}
    114 #endif
    115 	return(0);
    116 	}
    117 
    118 int EVP_PKEY_size(EVP_PKEY *pkey)
    119 	{
    120 	if (pkey == NULL)
    121 		return(0);
    122 #ifndef OPENSSL_NO_RSA
    123 	if (pkey->type == EVP_PKEY_RSA)
    124 		return(RSA_size(pkey->pkey.rsa));
    125 	else
    126 #endif
    127 #ifndef OPENSSL_NO_DSA
    128 		if (pkey->type == EVP_PKEY_DSA)
    129 		return(DSA_size(pkey->pkey.dsa));
    130 #endif
    131 #ifndef OPENSSL_NO_ECDSA
    132 		if (pkey->type == EVP_PKEY_EC)
    133 		return(ECDSA_size(pkey->pkey.ec));
    134 #endif
    135 
    136 	return(0);
    137 	}
    138 
    139 int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
    140 	{
    141 #ifndef OPENSSL_NO_DSA
    142 	if (pkey->type == EVP_PKEY_DSA)
    143 		{
    144 		int ret=pkey->save_parameters;
    145 
    146 		if (mode >= 0)
    147 			pkey->save_parameters=mode;
    148 		return(ret);
    149 		}
    150 #endif
    151 #ifndef OPENSSL_NO_EC
    152 	if (pkey->type == EVP_PKEY_EC)
    153 		{
    154 		int ret = pkey->save_parameters;
    155 
    156 		if (mode >= 0)
    157 			pkey->save_parameters = mode;
    158 		return(ret);
    159 		}
    160 #endif
    161 	return(0);
    162 	}
    163 
    164 int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
    165 	{
    166 	if (to->type != from->type)
    167 		{
    168 		EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_DIFFERENT_KEY_TYPES);
    169 		goto err;
    170 		}
    171 
    172 	if (EVP_PKEY_missing_parameters(from))
    173 		{
    174 		EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS);
    175 		goto err;
    176 		}
    177 #ifndef OPENSSL_NO_DSA
    178 	if (to->type == EVP_PKEY_DSA)
    179 		{
    180 		BIGNUM *a;
    181 
    182 		if ((a=BN_dup(from->pkey.dsa->p)) == NULL) goto err;
    183 		if (to->pkey.dsa->p != NULL) BN_free(to->pkey.dsa->p);
    184 		to->pkey.dsa->p=a;
    185 
    186 		if ((a=BN_dup(from->pkey.dsa->q)) == NULL) goto err;
    187 		if (to->pkey.dsa->q != NULL) BN_free(to->pkey.dsa->q);
    188 		to->pkey.dsa->q=a;
    189 
    190 		if ((a=BN_dup(from->pkey.dsa->g)) == NULL) goto err;
    191 		if (to->pkey.dsa->g != NULL) BN_free(to->pkey.dsa->g);
    192 		to->pkey.dsa->g=a;
    193 		}
    194 #endif
    195 #ifndef OPENSSL_NO_EC
    196 	if (to->type == EVP_PKEY_EC)
    197 		{
    198 		EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
    199 		if (group == NULL)
    200 			goto err;
    201 		if (EC_KEY_set_group(to->pkey.ec, group) == 0)
    202 			goto err;
    203 		EC_GROUP_free(group);
    204 		}
    205 #endif
    206 	return(1);
    207 err:
    208 	return(0);
    209 	}
    210 
    211 int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
    212 	{
    213 #ifndef OPENSSL_NO_DSA
    214 	if (pkey->type == EVP_PKEY_DSA)
    215 		{
    216 		DSA *dsa;
    217 
    218 		dsa=pkey->pkey.dsa;
    219 		if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
    220 			return(1);
    221 		}
    222 #endif
    223 #ifndef OPENSSL_NO_EC
    224 	if (pkey->type == EVP_PKEY_EC)
    225 		{
    226 		if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
    227 			return(1);
    228 		}
    229 #endif
    230 
    231 	return(0);
    232 	}
    233 
    234 int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
    235 	{
    236 #ifndef OPENSSL_NO_DSA
    237 	if ((a->type == EVP_PKEY_DSA) && (b->type == EVP_PKEY_DSA))
    238 		{
    239 		if (	BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) ||
    240 			BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) ||
    241 			BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g))
    242 			return(0);
    243 		else
    244 			return(1);
    245 		}
    246 #endif
    247 #ifndef OPENSSL_NO_EC
    248 	if (a->type == EVP_PKEY_EC && b->type == EVP_PKEY_EC)
    249 		{
    250 		const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
    251 		               *group_b = EC_KEY_get0_group(b->pkey.ec);
    252 		if (EC_GROUP_cmp(group_a, group_b, NULL))
    253 			return 0;
    254 		else
    255 			return 1;
    256 		}
    257 #endif
    258 	return(-1);
    259 	}
    260 
    261 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
    262 	{
    263 	if (a->type != b->type)
    264 		return -1;
    265 
    266 	if (EVP_PKEY_cmp_parameters(a, b) == 0)
    267 		return 0;
    268 
    269 	switch (a->type)
    270 		{
    271 #ifndef OPENSSL_NO_RSA
    272 	case EVP_PKEY_RSA:
    273 		if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0
    274 			|| BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0)
    275 			return 0;
    276 		break;
    277 #endif
    278 #ifndef OPENSSL_NO_DSA
    279 	case EVP_PKEY_DSA:
    280 		if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0)
    281 			return 0;
    282 		break;
    283 #endif
    284 #ifndef OPENSSL_NO_EC
    285 	case EVP_PKEY_EC:
    286 		{
    287 		int  r;
    288 		const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
    289 		const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
    290 		               *pb = EC_KEY_get0_public_key(b->pkey.ec);
    291 		r = EC_POINT_cmp(group, pa, pb, NULL);
    292 		if (r != 0)
    293 			{
    294 			if (r == 1)
    295 				return 0;
    296 			else
    297 				return -2;
    298 			}
    299 		}
    300  		break;
    301 #endif
    302 #ifndef OPENSSL_NO_DH
    303 	case EVP_PKEY_DH:
    304 		return -2;
    305 #endif
    306 	default:
    307 		return -2;
    308 		}
    309 
    310 	return 1;
    311 	}
    312 
    313 EVP_PKEY *EVP_PKEY_new(void)
    314 	{
    315 	EVP_PKEY *ret;
    316 
    317 	ret=(EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY));
    318 	if (ret == NULL)
    319 		{
    320 		EVPerr(EVP_F_EVP_PKEY_NEW,ERR_R_MALLOC_FAILURE);
    321 		return(NULL);
    322 		}
    323 	ret->type=EVP_PKEY_NONE;
    324 	ret->references=1;
    325 	ret->pkey.ptr=NULL;
    326 	ret->attributes=NULL;
    327 	ret->save_parameters=1;
    328 	return(ret);
    329 	}
    330 
    331 int EVP_PKEY_assign(EVP_PKEY *pkey, int type, char *key)
    332 	{
    333 	if (pkey == NULL) return(0);
    334 	if (pkey->pkey.ptr != NULL)
    335 		EVP_PKEY_free_it(pkey);
    336 	pkey->type=EVP_PKEY_type(type);
    337 	pkey->save_type=type;
    338 	pkey->pkey.ptr=key;
    339 	return(key != NULL);
    340 	}
    341 
    342 #ifndef OPENSSL_NO_RSA
    343 int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
    344 {
    345 	int ret = EVP_PKEY_assign_RSA(pkey, key);
    346 	if(ret)
    347 		RSA_up_ref(key);
    348 	return ret;
    349 }
    350 
    351 RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
    352 	{
    353 	if(pkey->type != EVP_PKEY_RSA) {
    354 		EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
    355 		return NULL;
    356 	}
    357 	RSA_up_ref(pkey->pkey.rsa);
    358 	return pkey->pkey.rsa;
    359 }
    360 #endif
    361 
    362 #ifndef OPENSSL_NO_DSA
    363 int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
    364 {
    365 	int ret = EVP_PKEY_assign_DSA(pkey, key);
    366 	if(ret)
    367 		DSA_up_ref(key);
    368 	return ret;
    369 }
    370 
    371 DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
    372 	{
    373 	if(pkey->type != EVP_PKEY_DSA) {
    374 		EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY);
    375 		return NULL;
    376 	}
    377 	DSA_up_ref(pkey->pkey.dsa);
    378 	return pkey->pkey.dsa;
    379 }
    380 #endif
    381 
    382 #ifndef OPENSSL_NO_EC
    383 
    384 int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
    385 {
    386 	int ret = EVP_PKEY_assign_EC_KEY(pkey,key);
    387 	if (ret)
    388 		EC_KEY_up_ref(key);
    389 	return ret;
    390 }
    391 
    392 EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
    393 {
    394 	if (pkey->type != EVP_PKEY_EC)
    395 	{
    396 		EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
    397 		return NULL;
    398 	}
    399 	EC_KEY_up_ref(pkey->pkey.ec);
    400 	return pkey->pkey.ec;
    401 }
    402 #endif
    403 
    404 
    405 #ifndef OPENSSL_NO_DH
    406 
    407 int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
    408 {
    409 	int ret = EVP_PKEY_assign_DH(pkey, key);
    410 	if(ret)
    411 		DH_up_ref(key);
    412 	return ret;
    413 }
    414 
    415 DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
    416 	{
    417 	if(pkey->type != EVP_PKEY_DH) {
    418 		EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY);
    419 		return NULL;
    420 	}
    421 	DH_up_ref(pkey->pkey.dh);
    422 	return pkey->pkey.dh;
    423 }
    424 #endif
    425 
    426 int EVP_PKEY_type(int type)
    427 	{
    428 	switch (type)
    429 		{
    430 	case EVP_PKEY_RSA:
    431 	case EVP_PKEY_RSA2:
    432 		return(EVP_PKEY_RSA);
    433 	case EVP_PKEY_DSA:
    434 	case EVP_PKEY_DSA1:
    435 	case EVP_PKEY_DSA2:
    436 	case EVP_PKEY_DSA3:
    437 	case EVP_PKEY_DSA4:
    438 		return(EVP_PKEY_DSA);
    439 	case EVP_PKEY_DH:
    440 		return(EVP_PKEY_DH);
    441 	case EVP_PKEY_EC:
    442 		return(EVP_PKEY_EC);
    443 	default:
    444 		return(NID_undef);
    445 		}
    446 	}
    447 
    448 void EVP_PKEY_free(EVP_PKEY *x)
    449 	{
    450 	int i;
    451 
    452 	if (x == NULL) return;
    453 
    454 	i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_EVP_PKEY);
    455 #ifdef REF_PRINT
    456 	REF_PRINT("EVP_PKEY",x);
    457 #endif
    458 	if (i > 0) return;
    459 #ifdef REF_CHECK
    460 	if (i < 0)
    461 		{
    462 		fprintf(stderr,"EVP_PKEY_free, bad reference count\n");
    463 		abort();
    464 		}
    465 #endif
    466 	EVP_PKEY_free_it(x);
    467 	if (x->attributes)
    468 		sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
    469 	OPENSSL_free(x);
    470 	}
    471 
    472 static void EVP_PKEY_free_it(EVP_PKEY *x)
    473 	{
    474 	switch (x->type)
    475 		{
    476 #ifndef OPENSSL_NO_RSA
    477 	case EVP_PKEY_RSA:
    478 	case EVP_PKEY_RSA2:
    479 		RSA_free(x->pkey.rsa);
    480 		break;
    481 #endif
    482 #ifndef OPENSSL_NO_DSA
    483 	case EVP_PKEY_DSA:
    484 	case EVP_PKEY_DSA2:
    485 	case EVP_PKEY_DSA3:
    486 	case EVP_PKEY_DSA4:
    487 		DSA_free(x->pkey.dsa);
    488 		break;
    489 #endif
    490 #ifndef OPENSSL_NO_EC
    491 	case EVP_PKEY_EC:
    492 		EC_KEY_free(x->pkey.ec);
    493 		break;
    494 #endif
    495 #ifndef OPENSSL_NO_DH
    496 	case EVP_PKEY_DH:
    497 		DH_free(x->pkey.dh);
    498 		break;
    499 #endif
    500 		}
    501 	}
    502 
    503