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