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 /* ==================================================================== 58 * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. 59 * 60 * Redistribution and use in source and binary forms, with or without 61 * modification, are permitted provided that the following conditions 62 * are met: 63 * 64 * 1. Redistributions of source code must retain the above copyright 65 * notice, this list of conditions and the following disclaimer. 66 * 67 * 2. Redistributions in binary form must reproduce the above copyright 68 * notice, this list of conditions and the following disclaimer in 69 * the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3. All advertising materials mentioning features or use of this 73 * software must display the following acknowledgment: 74 * "This product includes software developed by the OpenSSL Project 75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 76 * 77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 78 * endorse or promote products derived from this software without 79 * prior written permission. For written permission, please contact 80 * openssl-core (at) openssl.org. 81 * 82 * 5. Products derived from this software may not be called "OpenSSL" 83 * nor may "OpenSSL" appear in their names without prior written 84 * permission of the OpenSSL Project. 85 * 86 * 6. Redistributions of any form whatsoever must retain the following 87 * acknowledgment: 88 * "This product includes software developed by the OpenSSL Project 89 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 90 * 91 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 92 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 94 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 95 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 96 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 98 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 100 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 101 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 102 * OF THE POSSIBILITY OF SUCH DAMAGE. 103 * ==================================================================== 104 * 105 * This product includes cryptographic software written by Eric Young 106 * (eay (at) cryptsoft.com). This product includes software written by Tim 107 * Hudson (tjh (at) cryptsoft.com). 108 * 109 */ 110 111 #include <openssl/ssl.h> 112 113 #include <errno.h> 114 #include <string.h> 115 116 #include <openssl/asn1.h> 117 #include <openssl/bio.h> 118 #include <openssl/err.h> 119 #include <openssl/mem.h> 120 #include <openssl/pem.h> 121 #include <openssl/stack.h> 122 #include <openssl/x509.h> 123 124 #include "../crypto/directory.h" 125 #include "internal.h" 126 127 128 static int xname_cmp(const X509_NAME **a, const X509_NAME **b) { 129 return X509_NAME_cmp(*a, *b); 130 } 131 132 /* TODO(davidben): Is there any reason this doesn't call 133 * |SSL_add_file_cert_subjects_to_stack|? */ 134 STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) { 135 BIO *in; 136 X509 *x = NULL; 137 X509_NAME *xn = NULL; 138 STACK_OF(X509_NAME) *ret = NULL, *sk; 139 140 sk = sk_X509_NAME_new(xname_cmp); 141 in = BIO_new(BIO_s_file()); 142 143 if (sk == NULL || in == NULL) { 144 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); 145 goto err; 146 } 147 148 if (!BIO_read_filename(in, file)) { 149 goto err; 150 } 151 152 for (;;) { 153 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) { 154 break; 155 } 156 if (ret == NULL) { 157 ret = sk_X509_NAME_new_null(); 158 if (ret == NULL) { 159 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); 160 goto err; 161 } 162 } 163 xn = X509_get_subject_name(x); 164 if (xn == NULL) { 165 goto err; 166 } 167 168 /* check for duplicates */ 169 xn = X509_NAME_dup(xn); 170 if (xn == NULL) { 171 goto err; 172 } 173 if (sk_X509_NAME_find(sk, NULL, xn)) { 174 X509_NAME_free(xn); 175 } else { 176 sk_X509_NAME_push(sk, xn); 177 sk_X509_NAME_push(ret, xn); 178 } 179 } 180 181 if (0) { 182 err: 183 sk_X509_NAME_pop_free(ret, X509_NAME_free); 184 ret = NULL; 185 } 186 187 sk_X509_NAME_free(sk); 188 BIO_free(in); 189 X509_free(x); 190 if (ret != NULL) { 191 ERR_clear_error(); 192 } 193 return ret; 194 } 195 196 int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 197 const char *file) { 198 BIO *in; 199 X509 *x = NULL; 200 X509_NAME *xn = NULL; 201 int ret = 1; 202 int (*oldcmp)(const X509_NAME **a, const X509_NAME **b); 203 204 oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); 205 in = BIO_new(BIO_s_file()); 206 207 if (in == NULL) { 208 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); 209 goto err; 210 } 211 212 if (!BIO_read_filename(in, file)) { 213 goto err; 214 } 215 216 for (;;) { 217 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) { 218 break; 219 } 220 xn = X509_get_subject_name(x); 221 if (xn == NULL) { 222 goto err; 223 } 224 xn = X509_NAME_dup(xn); 225 if (xn == NULL) { 226 goto err; 227 } 228 if (sk_X509_NAME_find(stack, NULL, xn)) { 229 X509_NAME_free(xn); 230 } else { 231 sk_X509_NAME_push(stack, xn); 232 } 233 } 234 235 ERR_clear_error(); 236 237 if (0) { 238 err: 239 ret = 0; 240 } 241 242 BIO_free(in); 243 X509_free(x); 244 245 (void) sk_X509_NAME_set_cmp_func(stack, oldcmp); 246 247 return ret; 248 } 249 250 /* Add a directory of certs to a stack. 251 * 252 * \param stack the stack to append to. 253 * \param dir the directory to append from. All files in this directory will be 254 * examined as potential certs. Any that are acceptable to 255 * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will 256 * be included. 257 * \return 1 for success, 0 for failure. Note that in the case of failure some 258 * certs may have been added to \c stack. */ 259 int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 260 const char *dir) { 261 OPENSSL_DIR_CTX *d = NULL; 262 const char *filename; 263 int ret = 0; 264 265 /* Note that a side effect is that the CAs will be sorted by name */ 266 while ((filename = OPENSSL_DIR_read(&d, dir))) { 267 char buf[1024]; 268 int r; 269 270 if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) { 271 OPENSSL_PUT_ERROR(SSL, SSL_R_PATH_TOO_LONG); 272 goto err; 273 } 274 275 r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename); 276 if (r <= 0 || r >= (int)sizeof(buf) || 277 !SSL_add_file_cert_subjects_to_stack(stack, buf)) { 278 goto err; 279 } 280 } 281 282 if (errno) { 283 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); 284 ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')"); 285 goto err; 286 } 287 288 ret = 1; 289 290 err: 291 if (d) { 292 OPENSSL_DIR_end(&d); 293 } 294 return ret; 295 } 296 297 int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { 298 int reason_code; 299 BIO *in; 300 int ret = 0; 301 X509 *x = NULL; 302 303 in = BIO_new(BIO_s_file()); 304 if (in == NULL) { 305 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); 306 goto end; 307 } 308 309 if (BIO_read_filename(in, file) <= 0) { 310 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); 311 goto end; 312 } 313 314 if (type == SSL_FILETYPE_ASN1) { 315 reason_code = ERR_R_ASN1_LIB; 316 x = d2i_X509_bio(in, NULL); 317 } else if (type == SSL_FILETYPE_PEM) { 318 reason_code = ERR_R_PEM_LIB; 319 x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback, 320 ssl->ctx->default_passwd_callback_userdata); 321 } else { 322 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); 323 goto end; 324 } 325 326 if (x == NULL) { 327 OPENSSL_PUT_ERROR(SSL, reason_code); 328 goto end; 329 } 330 331 ret = SSL_use_certificate(ssl, x); 332 333 end: 334 X509_free(x); 335 BIO_free(in); 336 337 return ret; 338 } 339 340 int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) { 341 int reason_code, ret = 0; 342 BIO *in; 343 RSA *rsa = NULL; 344 345 in = BIO_new(BIO_s_file()); 346 if (in == NULL) { 347 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); 348 goto end; 349 } 350 351 if (BIO_read_filename(in, file) <= 0) { 352 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); 353 goto end; 354 } 355 356 if (type == SSL_FILETYPE_ASN1) { 357 reason_code = ERR_R_ASN1_LIB; 358 rsa = d2i_RSAPrivateKey_bio(in, NULL); 359 } else if (type == SSL_FILETYPE_PEM) { 360 reason_code = ERR_R_PEM_LIB; 361 rsa = 362 PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback, 363 ssl->ctx->default_passwd_callback_userdata); 364 } else { 365 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); 366 goto end; 367 } 368 369 if (rsa == NULL) { 370 OPENSSL_PUT_ERROR(SSL, reason_code); 371 goto end; 372 } 373 ret = SSL_use_RSAPrivateKey(ssl, rsa); 374 RSA_free(rsa); 375 376 end: 377 BIO_free(in); 378 return ret; 379 } 380 381 int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) { 382 int reason_code, ret = 0; 383 BIO *in; 384 EVP_PKEY *pkey = NULL; 385 386 in = BIO_new(BIO_s_file()); 387 if (in == NULL) { 388 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); 389 goto end; 390 } 391 392 if (BIO_read_filename(in, file) <= 0) { 393 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); 394 goto end; 395 } 396 397 if (type == SSL_FILETYPE_PEM) { 398 reason_code = ERR_R_PEM_LIB; 399 pkey = PEM_read_bio_PrivateKey(in, NULL, ssl->ctx->default_passwd_callback, 400 ssl->ctx->default_passwd_callback_userdata); 401 } else if (type == SSL_FILETYPE_ASN1) { 402 reason_code = ERR_R_ASN1_LIB; 403 pkey = d2i_PrivateKey_bio(in, NULL); 404 } else { 405 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); 406 goto end; 407 } 408 409 if (pkey == NULL) { 410 OPENSSL_PUT_ERROR(SSL, reason_code); 411 goto end; 412 } 413 ret = SSL_use_PrivateKey(ssl, pkey); 414 EVP_PKEY_free(pkey); 415 416 end: 417 BIO_free(in); 418 return ret; 419 } 420 421 int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) { 422 int reason_code; 423 BIO *in; 424 int ret = 0; 425 X509 *x = NULL; 426 427 in = BIO_new(BIO_s_file()); 428 if (in == NULL) { 429 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); 430 goto end; 431 } 432 433 if (BIO_read_filename(in, file) <= 0) { 434 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); 435 goto end; 436 } 437 438 if (type == SSL_FILETYPE_ASN1) { 439 reason_code = ERR_R_ASN1_LIB; 440 x = d2i_X509_bio(in, NULL); 441 } else if (type == SSL_FILETYPE_PEM) { 442 reason_code = ERR_R_PEM_LIB; 443 x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, 444 ctx->default_passwd_callback_userdata); 445 } else { 446 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); 447 goto end; 448 } 449 450 if (x == NULL) { 451 OPENSSL_PUT_ERROR(SSL, reason_code); 452 goto end; 453 } 454 455 ret = SSL_CTX_use_certificate(ctx, x); 456 457 end: 458 X509_free(x); 459 BIO_free(in); 460 return ret; 461 } 462 463 int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) { 464 int reason_code, ret = 0; 465 BIO *in; 466 RSA *rsa = NULL; 467 468 in = BIO_new(BIO_s_file()); 469 if (in == NULL) { 470 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); 471 goto end; 472 } 473 474 if (BIO_read_filename(in, file) <= 0) { 475 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); 476 goto end; 477 } 478 479 if (type == SSL_FILETYPE_ASN1) { 480 reason_code = ERR_R_ASN1_LIB; 481 rsa = d2i_RSAPrivateKey_bio(in, NULL); 482 } else if (type == SSL_FILETYPE_PEM) { 483 reason_code = ERR_R_PEM_LIB; 484 rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback, 485 ctx->default_passwd_callback_userdata); 486 } else { 487 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); 488 goto end; 489 } 490 491 if (rsa == NULL) { 492 OPENSSL_PUT_ERROR(SSL, reason_code); 493 goto end; 494 } 495 ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); 496 RSA_free(rsa); 497 498 end: 499 BIO_free(in); 500 return ret; 501 } 502 503 int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) { 504 int reason_code, ret = 0; 505 BIO *in; 506 EVP_PKEY *pkey = NULL; 507 508 in = BIO_new(BIO_s_file()); 509 if (in == NULL) { 510 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); 511 goto end; 512 } 513 514 if (BIO_read_filename(in, file) <= 0) { 515 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); 516 goto end; 517 } 518 519 if (type == SSL_FILETYPE_PEM) { 520 reason_code = ERR_R_PEM_LIB; 521 pkey = PEM_read_bio_PrivateKey(in, NULL, ctx->default_passwd_callback, 522 ctx->default_passwd_callback_userdata); 523 } else if (type == SSL_FILETYPE_ASN1) { 524 reason_code = ERR_R_ASN1_LIB; 525 pkey = d2i_PrivateKey_bio(in, NULL); 526 } else { 527 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); 528 goto end; 529 } 530 531 if (pkey == NULL) { 532 OPENSSL_PUT_ERROR(SSL, reason_code); 533 goto end; 534 } 535 ret = SSL_CTX_use_PrivateKey(ctx, pkey); 536 EVP_PKEY_free(pkey); 537 538 end: 539 BIO_free(in); 540 return ret; 541 } 542 543 /* Read a file that contains our certificate in "PEM" format, possibly followed 544 * by a sequence of CA certificates that should be sent to the peer in the 545 * Certificate message. */ 546 int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) { 547 BIO *in; 548 int ret = 0; 549 X509 *x = NULL; 550 551 ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */ 552 553 in = BIO_new(BIO_s_file()); 554 if (in == NULL) { 555 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); 556 goto end; 557 } 558 559 if (BIO_read_filename(in, file) <= 0) { 560 OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); 561 goto end; 562 } 563 564 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, 565 ctx->default_passwd_callback_userdata); 566 if (x == NULL) { 567 OPENSSL_PUT_ERROR(SSL, ERR_R_PEM_LIB); 568 goto end; 569 } 570 571 ret = SSL_CTX_use_certificate(ctx, x); 572 573 if (ERR_peek_error() != 0) { 574 ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */ 575 } 576 577 if (ret) { 578 /* If we could set up our certificate, now proceed to the CA 579 * certificates. */ 580 X509 *ca; 581 int r; 582 uint32_t err; 583 584 SSL_CTX_clear_chain_certs(ctx); 585 586 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, 587 ctx->default_passwd_callback_userdata)) != 588 NULL) { 589 r = SSL_CTX_add0_chain_cert(ctx, ca); 590 if (!r) { 591 X509_free(ca); 592 ret = 0; 593 goto end; 594 } 595 /* Note that we must not free r if it was successfully added to the chain 596 * (while we must free the main certificate, since its reference count is 597 * increased by SSL_CTX_use_certificate). */ 598 } 599 600 /* When the while loop ends, it's usually just EOF. */ 601 err = ERR_peek_last_error(); 602 if (ERR_GET_LIB(err) == ERR_LIB_PEM && 603 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) { 604 ERR_clear_error(); 605 } else { 606 ret = 0; /* some real error */ 607 } 608 } 609 610 end: 611 X509_free(x); 612 BIO_free(in); 613 return ret; 614 } 615 616 void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) { 617 ctx->default_passwd_callback = cb; 618 } 619 620 void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *data) { 621 ctx->default_passwd_callback_userdata = data; 622 } 623 624 SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out) { 625 return ASN1_d2i_bio_of(SSL_SESSION, SSL_SESSION_new, d2i_SSL_SESSION, bio, 626 out); 627 } 628 629 int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session) { 630 return ASN1_i2d_bio_of(SSL_SESSION, i2d_SSL_SESSION, bio, session); 631 } 632 633 IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION) 634