1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay (at) cryptsoft.com). 6 * The implementation was written so as to conform with Netscapes SSL. 7 * 8 * This library is free for commercial and non-commercial use as long as 9 * the following conditions are aheared to. The following conditions 10 * apply to all code found in this distribution, be it the RC4, RSA, 11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * included with this distribution is covered by the same copyright terms 13 * except that the holder is Tim Hudson (tjh (at) cryptsoft.com). 14 * 15 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * the code are not to be removed. 17 * If this package is used in a product, Eric Young should be given attribution 18 * as the author of the parts of the library used. 19 * This can be in the form of a textual message at program startup or 20 * in documentation (online or textual) provided with the package. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * "This product includes cryptographic software written by 33 * Eric Young (eay (at) cryptsoft.com)" 34 * The word 'cryptographic' can be left out if the rouines from the library 35 * being used are not cryptographic related :-). 36 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * the apps directory (application code) you must include an acknowledgement: 38 * "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 * 52 * The licence and distribution terms for any publically available version or 53 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * copied and put under another distribution licence 55 * [including the GNU Public Licence.] */ 56 57 #include <stdio.h> 58 59 #include <openssl/bio.h> 60 #include <openssl/err.h> 61 #include <openssl/evp.h> 62 #include <openssl/mem.h> 63 #include <openssl/obj.h> 64 #include <openssl/pem.h> 65 #include <openssl/x509.h> 66 67 #include "internal.h" 68 69 static int ssl_set_cert(CERT *c, X509 *x509); 70 static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); 71 72 int SSL_use_certificate(SSL *ssl, X509 *x) { 73 if (x == NULL) { 74 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate, ERR_R_PASSED_NULL_PARAMETER); 75 return 0; 76 } 77 return ssl_set_cert(ssl->cert, x); 78 } 79 80 int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { 81 int reason_code; 82 BIO *in; 83 int ret = 0; 84 X509 *x = NULL; 85 86 in = BIO_new(BIO_s_file()); 87 if (in == NULL) { 88 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, ERR_R_BUF_LIB); 89 goto end; 90 } 91 92 if (BIO_read_filename(in, file) <= 0) { 93 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, ERR_R_SYS_LIB); 94 goto end; 95 } 96 97 if (type == SSL_FILETYPE_ASN1) { 98 reason_code = ERR_R_ASN1_LIB; 99 x = d2i_X509_bio(in, NULL); 100 } else if (type == SSL_FILETYPE_PEM) { 101 reason_code = ERR_R_PEM_LIB; 102 x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback, 103 ssl->ctx->default_passwd_callback_userdata); 104 } else { 105 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, SSL_R_BAD_SSL_FILETYPE); 106 goto end; 107 } 108 109 if (x == NULL) { 110 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, reason_code); 111 goto end; 112 } 113 114 ret = SSL_use_certificate(ssl, x); 115 116 end: 117 X509_free(x); 118 BIO_free(in); 119 120 return ret; 121 } 122 123 int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *d, int len) { 124 X509 *x; 125 int ret; 126 127 x = d2i_X509(NULL, &d, (long)len); 128 if (x == NULL) { 129 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_ASN1, ERR_R_ASN1_LIB); 130 return 0; 131 } 132 133 ret = SSL_use_certificate(ssl, x); 134 X509_free(x); 135 return ret; 136 } 137 138 int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) { 139 EVP_PKEY *pkey; 140 int ret; 141 142 if (rsa == NULL) { 143 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey, ERR_R_PASSED_NULL_PARAMETER); 144 return 0; 145 } 146 147 pkey = EVP_PKEY_new(); 148 if (pkey == NULL) { 149 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey, ERR_R_EVP_LIB); 150 return 0; 151 } 152 153 RSA_up_ref(rsa); 154 EVP_PKEY_assign_RSA(pkey, rsa); 155 156 ret = ssl_set_pkey(ssl->cert, pkey); 157 EVP_PKEY_free(pkey); 158 159 return ret; 160 } 161 162 static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) { 163 int i; 164 165 i = ssl_cert_type(pkey); 166 if (i < 0) { 167 OPENSSL_PUT_ERROR(SSL, ssl_set_pkey, SSL_R_UNKNOWN_CERTIFICATE_TYPE); 168 return 0; 169 } 170 171 if (c->pkeys[i].x509 != NULL) { 172 /* Sanity-check that the private key and the certificate match, unless the 173 * key is opaque (in case of, say, a smartcard). */ 174 if (!EVP_PKEY_is_opaque(pkey) && 175 !X509_check_private_key(c->pkeys[i].x509, pkey)) { 176 X509_free(c->pkeys[i].x509); 177 c->pkeys[i].x509 = NULL; 178 return 0; 179 } 180 } 181 182 EVP_PKEY_free(c->pkeys[i].privatekey); 183 c->pkeys[i].privatekey = EVP_PKEY_up_ref(pkey); 184 c->key = &(c->pkeys[i]); 185 186 return 1; 187 } 188 189 int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) { 190 int reason_code, ret = 0; 191 BIO *in; 192 RSA *rsa = NULL; 193 194 in = BIO_new(BIO_s_file()); 195 if (in == NULL) { 196 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, ERR_R_BUF_LIB); 197 goto end; 198 } 199 200 if (BIO_read_filename(in, file) <= 0) { 201 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, ERR_R_SYS_LIB); 202 goto end; 203 } 204 205 if (type == SSL_FILETYPE_ASN1) { 206 reason_code = ERR_R_ASN1_LIB; 207 rsa = d2i_RSAPrivateKey_bio(in, NULL); 208 } else if (type == SSL_FILETYPE_PEM) { 209 reason_code = ERR_R_PEM_LIB; 210 rsa = 211 PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback, 212 ssl->ctx->default_passwd_callback_userdata); 213 } else { 214 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, SSL_R_BAD_SSL_FILETYPE); 215 goto end; 216 } 217 218 if (rsa == NULL) { 219 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, reason_code); 220 goto end; 221 } 222 ret = SSL_use_RSAPrivateKey(ssl, rsa); 223 RSA_free(rsa); 224 225 end: 226 BIO_free(in); 227 return ret; 228 } 229 230 int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, uint8_t *d, long len) { 231 int ret; 232 const uint8_t *p; 233 RSA *rsa; 234 235 p = d; 236 rsa = d2i_RSAPrivateKey(NULL, &p, (long)len); 237 if (rsa == NULL) { 238 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB); 239 return 0; 240 } 241 242 ret = SSL_use_RSAPrivateKey(ssl, rsa); 243 RSA_free(rsa); 244 return ret; 245 } 246 247 int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { 248 int ret; 249 250 if (pkey == NULL) { 251 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey, ERR_R_PASSED_NULL_PARAMETER); 252 return 0; 253 } 254 255 ret = ssl_set_pkey(ssl->cert, pkey); 256 return ret; 257 } 258 259 int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) { 260 int reason_code, ret = 0; 261 BIO *in; 262 EVP_PKEY *pkey = NULL; 263 264 in = BIO_new(BIO_s_file()); 265 if (in == NULL) { 266 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, ERR_R_BUF_LIB); 267 goto end; 268 } 269 270 if (BIO_read_filename(in, file) <= 0) { 271 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, ERR_R_SYS_LIB); 272 goto end; 273 } 274 275 if (type == SSL_FILETYPE_PEM) { 276 reason_code = ERR_R_PEM_LIB; 277 pkey = PEM_read_bio_PrivateKey(in, NULL, ssl->ctx->default_passwd_callback, 278 ssl->ctx->default_passwd_callback_userdata); 279 } else if (type == SSL_FILETYPE_ASN1) { 280 reason_code = ERR_R_ASN1_LIB; 281 pkey = d2i_PrivateKey_bio(in, NULL); 282 } else { 283 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, SSL_R_BAD_SSL_FILETYPE); 284 goto end; 285 } 286 287 if (pkey == NULL) { 288 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, reason_code); 289 goto end; 290 } 291 ret = SSL_use_PrivateKey(ssl, pkey); 292 EVP_PKEY_free(pkey); 293 294 end: 295 BIO_free(in); 296 return ret; 297 } 298 299 int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *d, long len) { 300 int ret; 301 const uint8_t *p; 302 EVP_PKEY *pkey; 303 304 p = d; 305 pkey = d2i_PrivateKey(type, NULL, &p, (long)len); 306 if (pkey == NULL) { 307 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_ASN1, ERR_R_ASN1_LIB); 308 return 0; 309 } 310 311 ret = SSL_use_PrivateKey(ssl, pkey); 312 EVP_PKEY_free(pkey); 313 return ret; 314 } 315 316 int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) { 317 if (x == NULL) { 318 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate, 319 ERR_R_PASSED_NULL_PARAMETER); 320 return 0; 321 } 322 323 return ssl_set_cert(ctx->cert, x); 324 } 325 326 static int ssl_set_cert(CERT *c, X509 *x) { 327 EVP_PKEY *pkey; 328 int i; 329 330 pkey = X509_get_pubkey(x); 331 if (pkey == NULL) { 332 OPENSSL_PUT_ERROR(SSL, ssl_set_cert, SSL_R_X509_LIB); 333 return 0; 334 } 335 336 i = ssl_cert_type(pkey); 337 if (i < 0) { 338 OPENSSL_PUT_ERROR(SSL, ssl_set_cert, SSL_R_UNKNOWN_CERTIFICATE_TYPE); 339 EVP_PKEY_free(pkey); 340 return 0; 341 } 342 343 if (c->pkeys[i].privatekey != NULL) { 344 /* Sanity-check that the private key and the certificate match, unless the 345 * key is opaque (in case of, say, a smartcard). */ 346 if (!EVP_PKEY_is_opaque(c->pkeys[i].privatekey) && 347 !X509_check_private_key(x, c->pkeys[i].privatekey)) { 348 /* don't fail for a cert/key mismatch, just free current private key 349 * (when switching to a different cert & key, first this function should 350 * be used, then ssl_set_pkey */ 351 EVP_PKEY_free(c->pkeys[i].privatekey); 352 c->pkeys[i].privatekey = NULL; 353 /* clear error queue */ 354 ERR_clear_error(); 355 } 356 } 357 358 EVP_PKEY_free(pkey); 359 360 X509_free(c->pkeys[i].x509); 361 c->pkeys[i].x509 = X509_up_ref(x); 362 c->key = &(c->pkeys[i]); 363 364 return 1; 365 } 366 367 int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) { 368 int reason_code; 369 BIO *in; 370 int ret = 0; 371 X509 *x = NULL; 372 373 in = BIO_new(BIO_s_file()); 374 if (in == NULL) { 375 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, ERR_R_BUF_LIB); 376 goto end; 377 } 378 379 if (BIO_read_filename(in, file) <= 0) { 380 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, ERR_R_SYS_LIB); 381 goto end; 382 } 383 384 if (type == SSL_FILETYPE_ASN1) { 385 reason_code = ERR_R_ASN1_LIB; 386 x = d2i_X509_bio(in, NULL); 387 } else if (type == SSL_FILETYPE_PEM) { 388 reason_code = ERR_R_PEM_LIB; 389 x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, 390 ctx->default_passwd_callback_userdata); 391 } else { 392 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, 393 SSL_R_BAD_SSL_FILETYPE); 394 goto end; 395 } 396 397 if (x == NULL) { 398 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, reason_code); 399 goto end; 400 } 401 402 ret = SSL_CTX_use_certificate(ctx, x); 403 404 end: 405 X509_free(x); 406 BIO_free(in); 407 return ret; 408 } 409 410 int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const uint8_t *d) { 411 X509 *x; 412 int ret; 413 414 x = d2i_X509(NULL, &d, (long)len); 415 if (x == NULL) { 416 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_ASN1, ERR_R_ASN1_LIB); 417 return 0; 418 } 419 420 ret = SSL_CTX_use_certificate(ctx, x); 421 X509_free(x); 422 return ret; 423 } 424 425 int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) { 426 int ret; 427 EVP_PKEY *pkey; 428 429 if (rsa == NULL) { 430 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey, 431 ERR_R_PASSED_NULL_PARAMETER); 432 return 0; 433 } 434 435 pkey = EVP_PKEY_new(); 436 if (pkey == NULL) { 437 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey, ERR_R_EVP_LIB); 438 return 0; 439 } 440 441 RSA_up_ref(rsa); 442 EVP_PKEY_assign_RSA(pkey, rsa); 443 444 ret = ssl_set_pkey(ctx->cert, pkey); 445 EVP_PKEY_free(pkey); 446 return ret; 447 } 448 449 int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) { 450 int reason_code, ret = 0; 451 BIO *in; 452 RSA *rsa = NULL; 453 454 in = BIO_new(BIO_s_file()); 455 if (in == NULL) { 456 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, ERR_R_BUF_LIB); 457 goto end; 458 } 459 460 if (BIO_read_filename(in, file) <= 0) { 461 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, ERR_R_SYS_LIB); 462 goto end; 463 } 464 465 if (type == SSL_FILETYPE_ASN1) { 466 reason_code = ERR_R_ASN1_LIB; 467 rsa = d2i_RSAPrivateKey_bio(in, NULL); 468 } else if (type == SSL_FILETYPE_PEM) { 469 reason_code = ERR_R_PEM_LIB; 470 rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback, 471 ctx->default_passwd_callback_userdata); 472 } else { 473 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, 474 SSL_R_BAD_SSL_FILETYPE); 475 goto end; 476 } 477 478 if (rsa == NULL) { 479 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, reason_code); 480 goto end; 481 } 482 ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); 483 RSA_free(rsa); 484 485 end: 486 BIO_free(in); 487 return ret; 488 } 489 490 int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *d, long len) { 491 int ret; 492 const uint8_t *p; 493 RSA *rsa; 494 495 p = d; 496 rsa = d2i_RSAPrivateKey(NULL, &p, (long)len); 497 if (rsa == NULL) { 498 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB); 499 return 0; 500 } 501 502 ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); 503 RSA_free(rsa); 504 return ret; 505 } 506 507 int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { 508 if (pkey == NULL) { 509 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey, ERR_R_PASSED_NULL_PARAMETER); 510 return 0; 511 } 512 513 return ssl_set_pkey(ctx->cert, pkey); 514 } 515 516 int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) { 517 int reason_code, ret = 0; 518 BIO *in; 519 EVP_PKEY *pkey = NULL; 520 521 in = BIO_new(BIO_s_file()); 522 if (in == NULL) { 523 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, ERR_R_BUF_LIB); 524 goto end; 525 } 526 527 if (BIO_read_filename(in, file) <= 0) { 528 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, ERR_R_SYS_LIB); 529 goto end; 530 } 531 532 if (type == SSL_FILETYPE_PEM) { 533 reason_code = ERR_R_PEM_LIB; 534 pkey = PEM_read_bio_PrivateKey(in, NULL, ctx->default_passwd_callback, 535 ctx->default_passwd_callback_userdata); 536 } else if (type == SSL_FILETYPE_ASN1) { 537 reason_code = ERR_R_ASN1_LIB; 538 pkey = d2i_PrivateKey_bio(in, NULL); 539 } else { 540 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, SSL_R_BAD_SSL_FILETYPE); 541 goto end; 542 } 543 544 if (pkey == NULL) { 545 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, reason_code); 546 goto end; 547 } 548 ret = SSL_CTX_use_PrivateKey(ctx, pkey); 549 EVP_PKEY_free(pkey); 550 551 end: 552 BIO_free(in); 553 return ret; 554 } 555 556 int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *d, 557 long len) { 558 int ret; 559 const uint8_t *p; 560 EVP_PKEY *pkey; 561 562 p = d; 563 pkey = d2i_PrivateKey(type, NULL, &p, (long)len); 564 if (pkey == NULL) { 565 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_ASN1, ERR_R_ASN1_LIB); 566 return 0; 567 } 568 569 ret = SSL_CTX_use_PrivateKey(ctx, pkey); 570 EVP_PKEY_free(pkey); 571 return ret; 572 } 573 574 575 /* Read a file that contains our certificate in "PEM" format, possibly followed 576 * by a sequence of CA certificates that should be sent to the peer in the 577 * Certificate message. */ 578 int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) { 579 BIO *in; 580 int ret = 0; 581 X509 *x = NULL; 582 583 ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */ 584 585 in = BIO_new(BIO_s_file()); 586 if (in == NULL) { 587 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_BUF_LIB); 588 goto end; 589 } 590 591 if (BIO_read_filename(in, file) <= 0) { 592 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_SYS_LIB); 593 goto end; 594 } 595 596 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, 597 ctx->default_passwd_callback_userdata); 598 if (x == NULL) { 599 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_PEM_LIB); 600 goto end; 601 } 602 603 ret = SSL_CTX_use_certificate(ctx, x); 604 605 if (ERR_peek_error() != 0) { 606 ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */ 607 } 608 609 if (ret) { 610 /* If we could set up our certificate, now proceed to the CA 611 * certificates. */ 612 X509 *ca; 613 int r; 614 uint32_t err; 615 616 SSL_CTX_clear_chain_certs(ctx); 617 618 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, 619 ctx->default_passwd_callback_userdata)) != 620 NULL) { 621 r = SSL_CTX_add0_chain_cert(ctx, ca); 622 if (!r) { 623 X509_free(ca); 624 ret = 0; 625 goto end; 626 } 627 /* Note that we must not free r if it was successfully added to the chain 628 * (while we must free the main certificate, since its reference count is 629 * increased by SSL_CTX_use_certificate). */ 630 } 631 632 /* When the while loop ends, it's usually just EOF. */ 633 err = ERR_peek_last_error(); 634 if (ERR_GET_LIB(err) == ERR_LIB_PEM && 635 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) { 636 ERR_clear_error(); 637 } else { 638 ret = 0; /* some real error */ 639 } 640 } 641 642 end: 643 X509_free(x); 644 BIO_free(in); 645 return ret; 646 } 647