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