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