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