1 /* $OpenBSD: p_lib.c,v 1.28 2022/01/20 11:06:24 inoguchi Exp $ */ 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 61 #include <openssl/opensslconf.h> 62 63 #include <openssl/bn.h> 64 #include <openssl/cmac.h> 65 #include <openssl/err.h> 66 #include <openssl/evp.h> 67 #include <openssl/objects.h> 68 #include <openssl/x509.h> 69 70 #ifndef OPENSSL_NO_DH 71 #include <openssl/dh.h> 72 #endif 73 #ifndef OPENSSL_NO_DSA 74 #include <openssl/dsa.h> 75 #endif 76 #ifndef OPENSSL_NO_RSA 77 #include <openssl/rsa.h> 78 #endif 79 80 #ifndef OPENSSL_NO_ENGINE 81 #include <openssl/engine.h> 82 #endif 83 84 #include "asn1_locl.h" 85 #include "evp_locl.h" 86 87 static void EVP_PKEY_free_it(EVP_PKEY *x); 88 89 int 90 EVP_PKEY_bits(const EVP_PKEY *pkey) 91 { 92 if (pkey && pkey->ameth && pkey->ameth->pkey_bits) 93 return pkey->ameth->pkey_bits(pkey); 94 return 0; 95 } 96 97 int 98 EVP_PKEY_size(const EVP_PKEY *pkey) 99 { 100 if (pkey && pkey->ameth && pkey->ameth->pkey_size) 101 return pkey->ameth->pkey_size(pkey); 102 return 0; 103 } 104 105 int 106 EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) 107 { 108 #ifndef OPENSSL_NO_DSA 109 if (pkey->type == EVP_PKEY_DSA) { 110 int ret = pkey->save_parameters; 111 112 if (mode >= 0) 113 pkey->save_parameters = mode; 114 return (ret); 115 } 116 #endif 117 #ifndef OPENSSL_NO_EC 118 if (pkey->type == EVP_PKEY_EC) { 119 int ret = pkey->save_parameters; 120 121 if (mode >= 0) 122 pkey->save_parameters = mode; 123 return (ret); 124 } 125 #endif 126 return (0); 127 } 128 129 int 130 EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) 131 { 132 if (to->type != from->type) { 133 EVPerror(EVP_R_DIFFERENT_KEY_TYPES); 134 goto err; 135 } 136 137 if (EVP_PKEY_missing_parameters(from)) { 138 EVPerror(EVP_R_MISSING_PARAMETERS); 139 goto err; 140 } 141 if (from->ameth && from->ameth->param_copy) 142 return from->ameth->param_copy(to, from); 143 144 err: 145 return 0; 146 } 147 148 int 149 EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) 150 { 151 if (pkey->ameth && pkey->ameth->param_missing) 152 return pkey->ameth->param_missing(pkey); 153 return 0; 154 } 155 156 int 157 EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 158 { 159 if (a->type != b->type) 160 return -1; 161 if (a->ameth && a->ameth->param_cmp) 162 return a->ameth->param_cmp(a, b); 163 return -2; 164 } 165 166 int 167 EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 168 { 169 if (a->type != b->type) 170 return -1; 171 172 if (a->ameth) { 173 int ret; 174 /* Compare parameters if the algorithm has them */ 175 if (a->ameth->param_cmp) { 176 ret = a->ameth->param_cmp(a, b); 177 if (ret <= 0) 178 return ret; 179 } 180 181 if (a->ameth->pub_cmp) 182 return a->ameth->pub_cmp(a, b); 183 } 184 185 return -2; 186 } 187 188 EVP_PKEY * 189 EVP_PKEY_new(void) 190 { 191 EVP_PKEY *ret; 192 193 ret = malloc(sizeof(EVP_PKEY)); 194 if (ret == NULL) { 195 EVPerror(ERR_R_MALLOC_FAILURE); 196 return (NULL); 197 } 198 ret->type = EVP_PKEY_NONE; 199 ret->save_type = EVP_PKEY_NONE; 200 ret->references = 1; 201 ret->ameth = NULL; 202 ret->engine = NULL; 203 ret->pkey.ptr = NULL; 204 ret->attributes = NULL; 205 ret->save_parameters = 1; 206 return (ret); 207 } 208 209 int 210 EVP_PKEY_up_ref(EVP_PKEY *pkey) 211 { 212 int refs = CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); 213 return ((refs > 1) ? 1 : 0); 214 } 215 216 /* Setup a public key ASN1 method and ENGINE from a NID or a string. 217 * If pkey is NULL just return 1 or 0 if the algorithm exists. 218 */ 219 220 static int 221 pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, int len) 222 { 223 const EVP_PKEY_ASN1_METHOD *ameth; 224 ENGINE **eptr = NULL; 225 226 if (e == NULL) 227 eptr = &e; 228 229 if (pkey) { 230 if (pkey->pkey.ptr) 231 EVP_PKEY_free_it(pkey); 232 /* If key type matches and a method exists then this 233 * lookup has succeeded once so just indicate success. 234 */ 235 if ((type == pkey->save_type) && pkey->ameth) 236 return 1; 237 #ifndef OPENSSL_NO_ENGINE 238 ENGINE_finish(pkey->engine); 239 pkey->engine = NULL; 240 #endif 241 } 242 if (str) 243 ameth = EVP_PKEY_asn1_find_str(eptr, str, len); 244 else 245 ameth = EVP_PKEY_asn1_find(eptr, type); 246 #ifndef OPENSSL_NO_ENGINE 247 if (pkey == NULL && eptr != NULL) 248 ENGINE_finish(e); 249 #endif 250 if (!ameth) { 251 EVPerror(EVP_R_UNSUPPORTED_ALGORITHM); 252 return 0; 253 } 254 if (pkey) { 255 pkey->ameth = ameth; 256 pkey->engine = e; 257 258 pkey->type = pkey->ameth->pkey_id; 259 pkey->save_type = type; 260 } 261 return 1; 262 } 263 264 int 265 EVP_PKEY_set_type(EVP_PKEY *pkey, int type) 266 { 267 return pkey_set_type(pkey, NULL, type, NULL, -1); 268 } 269 270 EVP_PKEY * 271 EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len, 272 const EVP_CIPHER *cipher) 273 { 274 EVP_PKEY *ret = NULL; 275 CMAC_CTX *cmctx = NULL; 276 277 if ((ret = EVP_PKEY_new()) == NULL) 278 goto err; 279 if ((cmctx = CMAC_CTX_new()) == NULL) 280 goto err; 281 282 if (!pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1)) 283 goto err; 284 285 if (!CMAC_Init(cmctx, priv, len, cipher, e)) { 286 EVPerror(EVP_R_KEY_SETUP_FAILED); 287 goto err; 288 } 289 290 ret->pkey.ptr = (char *)cmctx; 291 292 return ret; 293 294 err: 295 EVP_PKEY_free(ret); 296 CMAC_CTX_free(cmctx); 297 return NULL; 298 } 299 300 int 301 EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) 302 { 303 return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len); 304 } 305 306 int 307 EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) 308 { 309 if (!EVP_PKEY_set_type(pkey, type)) 310 return 0; 311 pkey->pkey.ptr = key; 312 return (key != NULL); 313 } 314 315 void * 316 EVP_PKEY_get0(const EVP_PKEY *pkey) 317 { 318 return pkey->pkey.ptr; 319 } 320 321 const unsigned char * 322 EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len) 323 { 324 ASN1_OCTET_STRING *os; 325 326 if (pkey->type != EVP_PKEY_HMAC) { 327 EVPerror(EVP_R_EXPECTING_AN_HMAC_KEY); 328 return NULL; 329 } 330 331 os = EVP_PKEY_get0(pkey); 332 *len = os->length; 333 334 return os->data; 335 } 336 337 #ifndef OPENSSL_NO_RSA 338 RSA * 339 EVP_PKEY_get0_RSA(EVP_PKEY *pkey) 340 { 341 if (pkey->type != EVP_PKEY_RSA) { 342 EVPerror(EVP_R_EXPECTING_AN_RSA_KEY); 343 return NULL; 344 } 345 return pkey->pkey.rsa; 346 } 347 348 RSA * 349 EVP_PKEY_get1_RSA(EVP_PKEY *pkey) 350 { 351 if (pkey->type != EVP_PKEY_RSA) { 352 EVPerror(EVP_R_EXPECTING_AN_RSA_KEY); 353 return NULL; 354 } 355 RSA_up_ref(pkey->pkey.rsa); 356 return pkey->pkey.rsa; 357 } 358 359 int 360 EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) 361 { 362 int ret = EVP_PKEY_assign_RSA(pkey, key); 363 if (ret != 0) 364 RSA_up_ref(key); 365 return ret; 366 } 367 #endif 368 369 #ifndef OPENSSL_NO_DSA 370 DSA * 371 EVP_PKEY_get0_DSA(EVP_PKEY *pkey) 372 { 373 if (pkey->type != EVP_PKEY_DSA) { 374 EVPerror(EVP_R_EXPECTING_A_DSA_KEY); 375 return NULL; 376 } 377 return pkey->pkey.dsa; 378 } 379 380 DSA * 381 EVP_PKEY_get1_DSA(EVP_PKEY *pkey) 382 { 383 if (pkey->type != EVP_PKEY_DSA) { 384 EVPerror(EVP_R_EXPECTING_A_DSA_KEY); 385 return NULL; 386 } 387 DSA_up_ref(pkey->pkey.dsa); 388 return pkey->pkey.dsa; 389 } 390 391 int 392 EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) 393 { 394 int ret = EVP_PKEY_assign_DSA(pkey, key); 395 if (ret != 0) 396 DSA_up_ref(key); 397 return ret; 398 } 399 #endif 400 401 #ifndef OPENSSL_NO_EC 402 EC_KEY * 403 EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) 404 { 405 if (pkey->type != EVP_PKEY_EC) { 406 EVPerror(EVP_R_EXPECTING_A_EC_KEY); 407 return NULL; 408 } 409 return pkey->pkey.ec; 410 } 411 412 EC_KEY * 413 EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) 414 { 415 if (pkey->type != EVP_PKEY_EC) { 416 EVPerror(EVP_R_EXPECTING_A_EC_KEY); 417 return NULL; 418 } 419 EC_KEY_up_ref(pkey->pkey.ec); 420 return pkey->pkey.ec; 421 } 422 423 int 424 EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) 425 { 426 int ret = EVP_PKEY_assign_EC_KEY(pkey, key); 427 if (ret != 0) 428 EC_KEY_up_ref(key); 429 return ret; 430 } 431 #endif 432 433 434 #ifndef OPENSSL_NO_DH 435 DH * 436 EVP_PKEY_get0_DH(EVP_PKEY *pkey) 437 { 438 if (pkey->type != EVP_PKEY_DH) { 439 EVPerror(EVP_R_EXPECTING_A_DH_KEY); 440 return NULL; 441 } 442 return pkey->pkey.dh; 443 } 444 445 DH * 446 EVP_PKEY_get1_DH(EVP_PKEY *pkey) 447 { 448 if (pkey->type != EVP_PKEY_DH) { 449 EVPerror(EVP_R_EXPECTING_A_DH_KEY); 450 return NULL; 451 } 452 DH_up_ref(pkey->pkey.dh); 453 return pkey->pkey.dh; 454 } 455 456 int 457 EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) 458 { 459 int ret = EVP_PKEY_assign_DH(pkey, key); 460 if (ret != 0) 461 DH_up_ref(key); 462 return ret; 463 } 464 #endif 465 466 int 467 EVP_PKEY_type(int type) 468 { 469 int ret; 470 const EVP_PKEY_ASN1_METHOD *ameth; 471 ENGINE *e; 472 ameth = EVP_PKEY_asn1_find(&e, type); 473 if (ameth) 474 ret = ameth->pkey_id; 475 else 476 ret = NID_undef; 477 #ifndef OPENSSL_NO_ENGINE 478 ENGINE_finish(e); 479 #endif 480 return ret; 481 } 482 483 int 484 EVP_PKEY_id(const EVP_PKEY *pkey) 485 { 486 return pkey->type; 487 } 488 489 int 490 EVP_PKEY_base_id(const EVP_PKEY *pkey) 491 { 492 return EVP_PKEY_type(pkey->type); 493 } 494 495 void 496 EVP_PKEY_free(EVP_PKEY *x) 497 { 498 int i; 499 500 if (x == NULL) 501 return; 502 503 i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY); 504 if (i > 0) 505 return; 506 507 EVP_PKEY_free_it(x); 508 if (x->attributes) 509 sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free); 510 free(x); 511 } 512 513 static void 514 EVP_PKEY_free_it(EVP_PKEY *x) 515 { 516 if (x->ameth && x->ameth->pkey_free) { 517 x->ameth->pkey_free(x); 518 x->pkey.ptr = NULL; 519 } 520 #ifndef OPENSSL_NO_ENGINE 521 ENGINE_finish(x->engine); 522 x->engine = NULL; 523 #endif 524 } 525 526 static int 527 unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, const char *kstr) 528 { 529 if (!BIO_indent(out, indent, 128)) 530 return 0; 531 BIO_printf(out, "%s algorithm \"%s\" unsupported\n", 532 kstr, OBJ_nid2ln(pkey->type)); 533 return 1; 534 } 535 536 int 537 EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, 538 ASN1_PCTX *pctx) 539 { 540 if (pkey->ameth && pkey->ameth->pub_print) 541 return pkey->ameth->pub_print(out, pkey, indent, pctx); 542 543 return unsup_alg(out, pkey, indent, "Public Key"); 544 } 545 546 int 547 EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, 548 ASN1_PCTX *pctx) 549 { 550 if (pkey->ameth && pkey->ameth->priv_print) 551 return pkey->ameth->priv_print(out, pkey, indent, pctx); 552 553 return unsup_alg(out, pkey, indent, "Private Key"); 554 } 555 556 int 557 EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, 558 ASN1_PCTX *pctx) 559 { 560 if (pkey->ameth && pkey->ameth->param_print) 561 return pkey->ameth->param_print(out, pkey, indent, pctx); 562 return unsup_alg(out, pkey, indent, "Parameters"); 563 } 564 565 int 566 EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid) 567 { 568 if (!pkey->ameth || !pkey->ameth->pkey_ctrl) 569 return -2; 570 return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 571 0, pnid); 572 } 573 574