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