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