1 /* $OpenBSD: ssl_rsa.c,v 1.34 2021/06/11 11:13:53 jsing 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/bio.h> 62 #include <openssl/evp.h> 63 #include <openssl/objects.h> 64 #include <openssl/pem.h> 65 #include <openssl/x509.h> 66 67 #include "ssl_locl.h" 68 69 static int ssl_set_cert(CERT *c, X509 *x509); 70 static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); 71 static int use_certificate_chain_bio(BIO *in, CERT *cert, 72 pem_password_cb *passwd_cb, void *passwd_arg); 73 static int use_certificate_chain_file(const char *file, CERT *cert, 74 pem_password_cb *passwd_cb, void *passwd_arg); 75 76 int 77 SSL_use_certificate(SSL *ssl, X509 *x) 78 { 79 if (x == NULL) { 80 SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER); 81 return (0); 82 } 83 return (ssl_set_cert(ssl->cert, x)); 84 } 85 86 int 87 SSL_use_certificate_file(SSL *ssl, const char *file, int type) 88 { 89 int j; 90 BIO *in; 91 int ret = 0; 92 X509 *x = NULL; 93 94 in = BIO_new(BIO_s_file_internal()); 95 if (in == NULL) { 96 SSLerror(ssl, ERR_R_BUF_LIB); 97 goto end; 98 } 99 100 if (BIO_read_filename(in, file) <= 0) { 101 SSLerror(ssl, ERR_R_SYS_LIB); 102 goto end; 103 } 104 if (type == SSL_FILETYPE_ASN1) { 105 j = ERR_R_ASN1_LIB; 106 x = d2i_X509_bio(in, NULL); 107 } else if (type == SSL_FILETYPE_PEM) { 108 j = ERR_R_PEM_LIB; 109 x = PEM_read_bio_X509(in, NULL, 110 ssl->ctx->default_passwd_callback, 111 ssl->ctx->default_passwd_callback_userdata); 112 } else { 113 SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE); 114 goto end; 115 } 116 117 if (x == NULL) { 118 SSLerror(ssl, j); 119 goto end; 120 } 121 122 ret = SSL_use_certificate(ssl, x); 123 end: 124 X509_free(x); 125 BIO_free(in); 126 return (ret); 127 } 128 129 int 130 SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) 131 { 132 X509 *x; 133 int ret; 134 135 x = d2i_X509(NULL, &d, (long)len); 136 if (x == NULL) { 137 SSLerror(ssl, ERR_R_ASN1_LIB); 138 return (0); 139 } 140 141 ret = SSL_use_certificate(ssl, x); 142 X509_free(x); 143 return (ret); 144 } 145 146 int 147 SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) 148 { 149 EVP_PKEY *pkey; 150 int ret; 151 152 if (rsa == NULL) { 153 SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER); 154 return (0); 155 } 156 if ((pkey = EVP_PKEY_new()) == NULL) { 157 SSLerror(ssl, ERR_R_EVP_LIB); 158 return (0); 159 } 160 161 RSA_up_ref(rsa); 162 EVP_PKEY_assign_RSA(pkey, rsa); 163 164 ret = ssl_set_pkey(ssl->cert, pkey); 165 EVP_PKEY_free(pkey); 166 return (ret); 167 } 168 169 static int 170 ssl_set_pkey(CERT *c, EVP_PKEY *pkey) 171 { 172 int i; 173 174 i = ssl_cert_type(NULL, pkey); 175 if (i < 0) { 176 SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE); 177 return (0); 178 } 179 180 if (c->pkeys[i].x509 != NULL) { 181 EVP_PKEY *pktmp; 182 pktmp = X509_get_pubkey(c->pkeys[i].x509); 183 EVP_PKEY_copy_parameters(pktmp, pkey); 184 EVP_PKEY_free(pktmp); 185 ERR_clear_error(); 186 187 /* 188 * Don't check the public/private key, this is mostly 189 * for smart cards. 190 */ 191 if ((pkey->type == EVP_PKEY_RSA) && 192 (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) 193 ; 194 else 195 if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { 196 X509_free(c->pkeys[i].x509); 197 c->pkeys[i].x509 = NULL; 198 return 0; 199 } 200 } 201 202 EVP_PKEY_free(c->pkeys[i].privatekey); 203 CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); 204 c->pkeys[i].privatekey = pkey; 205 c->key = &(c->pkeys[i]); 206 207 c->valid = 0; 208 return (1); 209 } 210 211 int 212 SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) 213 { 214 int j, ret = 0; 215 BIO *in; 216 RSA *rsa = NULL; 217 218 in = BIO_new(BIO_s_file_internal()); 219 if (in == NULL) { 220 SSLerror(ssl, ERR_R_BUF_LIB); 221 goto end; 222 } 223 224 if (BIO_read_filename(in, file) <= 0) { 225 SSLerror(ssl, ERR_R_SYS_LIB); 226 goto end; 227 } 228 if (type == SSL_FILETYPE_ASN1) { 229 j = ERR_R_ASN1_LIB; 230 rsa = d2i_RSAPrivateKey_bio(in, NULL); 231 } else if (type == SSL_FILETYPE_PEM) { 232 j = ERR_R_PEM_LIB; 233 rsa = PEM_read_bio_RSAPrivateKey(in, NULL, 234 ssl->ctx->default_passwd_callback, 235 ssl->ctx->default_passwd_callback_userdata); 236 } else { 237 SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE); 238 goto end; 239 } 240 if (rsa == NULL) { 241 SSLerror(ssl, j); 242 goto end; 243 } 244 ret = SSL_use_RSAPrivateKey(ssl, rsa); 245 RSA_free(rsa); 246 end: 247 BIO_free(in); 248 return (ret); 249 } 250 251 int 252 SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len) 253 { 254 int ret; 255 RSA *rsa; 256 257 if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) { 258 SSLerror(ssl, ERR_R_ASN1_LIB); 259 return (0); 260 } 261 262 ret = SSL_use_RSAPrivateKey(ssl, rsa); 263 RSA_free(rsa); 264 return (ret); 265 } 266 267 int 268 SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) 269 { 270 int ret; 271 272 if (pkey == NULL) { 273 SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER); 274 return (0); 275 } 276 ret = ssl_set_pkey(ssl->cert, pkey); 277 return (ret); 278 } 279 280 int 281 SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) 282 { 283 int j, ret = 0; 284 BIO *in; 285 EVP_PKEY *pkey = NULL; 286 287 in = BIO_new(BIO_s_file_internal()); 288 if (in == NULL) { 289 SSLerror(ssl, ERR_R_BUF_LIB); 290 goto end; 291 } 292 293 if (BIO_read_filename(in, file) <= 0) { 294 SSLerror(ssl, ERR_R_SYS_LIB); 295 goto end; 296 } 297 if (type == SSL_FILETYPE_PEM) { 298 j = ERR_R_PEM_LIB; 299 pkey = PEM_read_bio_PrivateKey(in, NULL, 300 ssl->ctx->default_passwd_callback, 301 ssl->ctx->default_passwd_callback_userdata); 302 } else if (type == SSL_FILETYPE_ASN1) { 303 j = ERR_R_ASN1_LIB; 304 pkey = d2i_PrivateKey_bio(in, NULL); 305 } else { 306 SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE); 307 goto end; 308 } 309 if (pkey == NULL) { 310 SSLerror(ssl, j); 311 goto end; 312 } 313 ret = SSL_use_PrivateKey(ssl, pkey); 314 EVP_PKEY_free(pkey); 315 end: 316 BIO_free(in); 317 return (ret); 318 } 319 320 int 321 SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len) 322 { 323 int ret; 324 EVP_PKEY *pkey; 325 326 if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) { 327 SSLerror(ssl, ERR_R_ASN1_LIB); 328 return (0); 329 } 330 331 ret = SSL_use_PrivateKey(ssl, pkey); 332 EVP_PKEY_free(pkey); 333 return (ret); 334 } 335 336 int 337 SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) 338 { 339 if (x == NULL) { 340 SSLerrorx(ERR_R_PASSED_NULL_PARAMETER); 341 return (0); 342 } 343 return (ssl_set_cert(ctx->internal->cert, x)); 344 } 345 346 static int 347 ssl_set_cert(CERT *c, X509 *x) 348 { 349 EVP_PKEY *pkey; 350 int i; 351 352 pkey = X509_get_pubkey(x); 353 if (pkey == NULL) { 354 SSLerrorx(SSL_R_X509_LIB); 355 return (0); 356 } 357 358 i = ssl_cert_type(x, pkey); 359 if (i < 0) { 360 SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE); 361 EVP_PKEY_free(pkey); 362 return (0); 363 } 364 365 if (c->pkeys[i].privatekey != NULL) { 366 EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); 367 ERR_clear_error(); 368 369 /* 370 * Don't check the public/private key, this is mostly 371 * for smart cards. 372 */ 373 if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) && 374 (RSA_flags(c->pkeys[i].privatekey->pkey.rsa) & 375 RSA_METHOD_FLAG_NO_CHECK)) 376 ; 377 else 378 if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { 379 /* 380 * don't fail for a cert/key mismatch, just free 381 * current private key (when switching to a different 382 * cert & key, first this function should be used, 383 * then ssl_set_pkey 384 */ 385 EVP_PKEY_free(c->pkeys[i].privatekey); 386 c->pkeys[i].privatekey = NULL; 387 /* clear error queue */ 388 ERR_clear_error(); 389 } 390 } 391 392 EVP_PKEY_free(pkey); 393 394 X509_free(c->pkeys[i].x509); 395 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); 396 c->pkeys[i].x509 = x; 397 c->key = &(c->pkeys[i]); 398 399 c->valid = 0; 400 return (1); 401 } 402 403 int 404 SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) 405 { 406 int j; 407 BIO *in; 408 int ret = 0; 409 X509 *x = NULL; 410 411 in = BIO_new(BIO_s_file_internal()); 412 if (in == NULL) { 413 SSLerrorx(ERR_R_BUF_LIB); 414 goto end; 415 } 416 417 if (BIO_read_filename(in, file) <= 0) { 418 SSLerrorx(ERR_R_SYS_LIB); 419 goto end; 420 } 421 if (type == SSL_FILETYPE_ASN1) { 422 j = ERR_R_ASN1_LIB; 423 x = d2i_X509_bio(in, NULL); 424 } else if (type == SSL_FILETYPE_PEM) { 425 j = ERR_R_PEM_LIB; 426 x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, 427 ctx->default_passwd_callback_userdata); 428 } else { 429 SSLerrorx(SSL_R_BAD_SSL_FILETYPE); 430 goto end; 431 } 432 433 if (x == NULL) { 434 SSLerrorx(j); 435 goto end; 436 } 437 438 ret = SSL_CTX_use_certificate(ctx, x); 439 end: 440 X509_free(x); 441 BIO_free(in); 442 return (ret); 443 } 444 445 int 446 SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) 447 { 448 X509 *x; 449 int ret; 450 451 x = d2i_X509(NULL, &d, (long)len); 452 if (x == NULL) { 453 SSLerrorx(ERR_R_ASN1_LIB); 454 return (0); 455 } 456 457 ret = SSL_CTX_use_certificate(ctx, x); 458 X509_free(x); 459 return (ret); 460 } 461 462 int 463 SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) 464 { 465 int ret; 466 EVP_PKEY *pkey; 467 468 if (rsa == NULL) { 469 SSLerrorx(ERR_R_PASSED_NULL_PARAMETER); 470 return (0); 471 } 472 if ((pkey = EVP_PKEY_new()) == NULL) { 473 SSLerrorx(ERR_R_EVP_LIB); 474 return (0); 475 } 476 477 RSA_up_ref(rsa); 478 EVP_PKEY_assign_RSA(pkey, rsa); 479 480 ret = ssl_set_pkey(ctx->internal->cert, pkey); 481 EVP_PKEY_free(pkey); 482 return (ret); 483 } 484 485 int 486 SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) 487 { 488 int j, ret = 0; 489 BIO *in; 490 RSA *rsa = NULL; 491 492 in = BIO_new(BIO_s_file_internal()); 493 if (in == NULL) { 494 SSLerrorx(ERR_R_BUF_LIB); 495 goto end; 496 } 497 498 if (BIO_read_filename(in, file) <= 0) { 499 SSLerrorx(ERR_R_SYS_LIB); 500 goto end; 501 } 502 if (type == SSL_FILETYPE_ASN1) { 503 j = ERR_R_ASN1_LIB; 504 rsa = d2i_RSAPrivateKey_bio(in, NULL); 505 } else if (type == SSL_FILETYPE_PEM) { 506 j = ERR_R_PEM_LIB; 507 rsa = PEM_read_bio_RSAPrivateKey(in, NULL, 508 ctx->default_passwd_callback, 509 ctx->default_passwd_callback_userdata); 510 } else { 511 SSLerrorx(SSL_R_BAD_SSL_FILETYPE); 512 goto end; 513 } 514 if (rsa == NULL) { 515 SSLerrorx(j); 516 goto end; 517 } 518 ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); 519 RSA_free(rsa); 520 end: 521 BIO_free(in); 522 return (ret); 523 } 524 525 int 526 SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len) 527 { 528 int ret; 529 RSA *rsa; 530 531 if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) { 532 SSLerrorx(ERR_R_ASN1_LIB); 533 return (0); 534 } 535 536 ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); 537 RSA_free(rsa); 538 return (ret); 539 } 540 541 int 542 SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) 543 { 544 if (pkey == NULL) { 545 SSLerrorx(ERR_R_PASSED_NULL_PARAMETER); 546 return (0); 547 } 548 return (ssl_set_pkey(ctx->internal->cert, pkey)); 549 } 550 551 int 552 SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) 553 { 554 int j, ret = 0; 555 BIO *in; 556 EVP_PKEY *pkey = NULL; 557 558 in = BIO_new(BIO_s_file_internal()); 559 if (in == NULL) { 560 SSLerrorx(ERR_R_BUF_LIB); 561 goto end; 562 } 563 564 if (BIO_read_filename(in, file) <= 0) { 565 SSLerrorx(ERR_R_SYS_LIB); 566 goto end; 567 } 568 if (type == SSL_FILETYPE_PEM) { 569 j = ERR_R_PEM_LIB; 570 pkey = PEM_read_bio_PrivateKey(in, NULL, 571 ctx->default_passwd_callback, 572 ctx->default_passwd_callback_userdata); 573 } else if (type == SSL_FILETYPE_ASN1) { 574 j = ERR_R_ASN1_LIB; 575 pkey = d2i_PrivateKey_bio(in, NULL); 576 } else { 577 SSLerrorx(SSL_R_BAD_SSL_FILETYPE); 578 goto end; 579 } 580 if (pkey == NULL) { 581 SSLerrorx(j); 582 goto end; 583 } 584 ret = SSL_CTX_use_PrivateKey(ctx, pkey); 585 EVP_PKEY_free(pkey); 586 end: 587 BIO_free(in); 588 return (ret); 589 } 590 591 int 592 SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d, 593 long len) 594 { 595 int ret; 596 EVP_PKEY *pkey; 597 598 if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) { 599 SSLerrorx(ERR_R_ASN1_LIB); 600 return (0); 601 } 602 603 ret = SSL_CTX_use_PrivateKey(ctx, pkey); 604 EVP_PKEY_free(pkey); 605 return (ret); 606 } 607 608 609 /* 610 * Read a bio that contains our certificate in "PEM" format, 611 * possibly followed by a sequence of CA certificates that should be 612 * sent to the peer in the Certificate message. 613 */ 614 static int 615 use_certificate_chain_bio(BIO *in, CERT *cert, pem_password_cb *passwd_cb, 616 void *passwd_arg) 617 { 618 X509 *ca, *x = NULL; 619 unsigned long err; 620 int ret = 0; 621 622 if ((x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_arg)) == 623 NULL) { 624 SSLerrorx(ERR_R_PEM_LIB); 625 goto err; 626 } 627 628 if (!ssl_set_cert(cert, x)) 629 goto err; 630 631 if (!ssl_cert_set0_chain(cert, NULL)) 632 goto err; 633 634 /* Process any additional CA certificates. */ 635 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_arg)) != 636 NULL) { 637 if (!ssl_cert_add0_chain_cert(cert, ca)) { 638 X509_free(ca); 639 goto err; 640 } 641 } 642 643 /* When the while loop ends, it's usually just EOF. */ 644 err = ERR_peek_last_error(); 645 if (ERR_GET_LIB(err) == ERR_LIB_PEM && 646 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) { 647 ERR_clear_error(); 648 ret = 1; 649 } 650 651 err: 652 X509_free(x); 653 654 return (ret); 655 } 656 657 int 658 use_certificate_chain_file(const char *file, CERT *cert, 659 pem_password_cb *passwd_cb, void *passwd_arg) 660 { 661 BIO *in; 662 int ret = 0; 663 664 in = BIO_new(BIO_s_file_internal()); 665 if (in == NULL) { 666 SSLerrorx(ERR_R_BUF_LIB); 667 goto end; 668 } 669 670 if (BIO_read_filename(in, file) <= 0) { 671 SSLerrorx(ERR_R_SYS_LIB); 672 goto end; 673 } 674 675 ret = use_certificate_chain_bio(in, cert, passwd_cb, passwd_arg); 676 677 end: 678 BIO_free(in); 679 return (ret); 680 } 681 682 int 683 SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) 684 { 685 return use_certificate_chain_file(file, ctx->internal->cert, 686 ctx->default_passwd_callback, 687 ctx->default_passwd_callback_userdata); 688 } 689 690 int 691 SSL_use_certificate_chain_file(SSL *ssl, const char *file) 692 { 693 return use_certificate_chain_file(file, ssl->cert, 694 ssl->ctx->default_passwd_callback, 695 ssl->ctx->default_passwd_callback_userdata); 696 } 697 698 int 699 SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len) 700 { 701 BIO *in; 702 int ret = 0; 703 704 in = BIO_new_mem_buf(buf, len); 705 if (in == NULL) { 706 SSLerrorx(ERR_R_BUF_LIB); 707 goto end; 708 } 709 710 ret = use_certificate_chain_bio(in, ctx->internal->cert, 711 ctx->default_passwd_callback, 712 ctx->default_passwd_callback_userdata); 713 714 end: 715 BIO_free(in); 716 return (ret); 717 } 718