1 /* crypto/bio/bio_lib.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 <errno.h> 61 #include <openssl/crypto.h> 62 #include "cryptlib.h" 63 #include <openssl/bio.h> 64 #include <openssl/stack.h> 65 66 BIO 67 *BIO_new(BIO_METHOD *method) 68 { 69 BIO *ret = NULL; 70 71 ret = (BIO *)OPENSSL_malloc(sizeof(BIO)); 72 if (ret == NULL) { 73 BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE); 74 return (NULL); 75 } 76 if (!BIO_set(ret, method)) { 77 OPENSSL_free(ret); 78 ret = NULL; 79 } 80 return (ret); 81 } 82 83 int 84 BIO_set(BIO *bio, BIO_METHOD *method) 85 { 86 bio->method = method; 87 bio->callback = NULL; 88 bio->cb_arg = NULL; 89 bio->init = 0; 90 bio->shutdown = 1; 91 bio->flags = 0; 92 bio->retry_reason = 0; 93 bio->num = 0; 94 bio->ptr = NULL; 95 bio->prev_bio = NULL; 96 bio->next_bio = NULL; 97 bio->references = 1; 98 bio->num_read = 0L; 99 bio->num_write = 0L; 100 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); 101 if (method->create != NULL) 102 if (!method->create(bio)) { 103 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, 104 &bio->ex_data); 105 return (0); 106 } 107 return (1); 108 } 109 110 int 111 BIO_free(BIO *a) 112 { 113 int i; 114 115 if (a == NULL) 116 return (0); 117 118 i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO); 119 #ifdef REF_PRINT 120 REF_PRINT("BIO", a); 121 #endif 122 if (i > 0) 123 return (1); 124 #ifdef REF_CHECK 125 if (i < 0) { 126 fprintf(stderr, "BIO_free, bad reference count\n"); 127 abort(); 128 } 129 #endif 130 if ((a->callback != NULL) && 131 ((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0)) 132 return (i); 133 134 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data); 135 136 if ((a->method == NULL) || (a->method->destroy == NULL)) 137 return (1); 138 a->method->destroy(a); 139 OPENSSL_free(a); 140 return (1); 141 } 142 143 void 144 BIO_vfree(BIO *a) 145 { 146 BIO_free(a); 147 } 148 149 void 150 BIO_clear_flags(BIO *b, int flags) 151 { 152 b->flags &= ~flags; 153 } 154 155 int 156 BIO_test_flags(const BIO *b, int flags) 157 { 158 return (b->flags & flags); 159 } 160 161 void 162 BIO_set_flags(BIO *b, int flags) 163 { 164 b->flags |= flags; 165 } 166 167 long 168 (*BIO_get_callback(const BIO *b))(struct bio_st *, int, const char *, int, 169 long, long) 170 { 171 return b->callback; 172 } 173 174 void 175 BIO_set_callback(BIO *b, long (*cb)(struct bio_st *, int, const char *, int, 176 long, long)) 177 { 178 b->callback = cb; 179 } 180 181 void 182 BIO_set_callback_arg(BIO *b, char *arg) 183 { 184 b->cb_arg = arg; 185 } 186 187 char * 188 BIO_get_callback_arg(const BIO *b) 189 { 190 return b->cb_arg; 191 } 192 193 const char * 194 BIO_method_name(const BIO *b) 195 { 196 return b->method->name; 197 } 198 199 int 200 BIO_method_type(const BIO *b) 201 { 202 return b->method->type; 203 } 204 205 int 206 BIO_read(BIO *b, void *out, int outl) 207 { 208 int i; 209 long (*cb)(BIO *, int, const char *, int, long, long); 210 211 if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) { 212 BIOerr(BIO_F_BIO_READ, BIO_R_UNSUPPORTED_METHOD); 213 return (-2); 214 } 215 216 cb = b->callback; 217 if ((cb != NULL) && 218 ((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0)) 219 return (i); 220 221 if (!b->init) { 222 BIOerr(BIO_F_BIO_READ, BIO_R_UNINITIALIZED); 223 return (-2); 224 } 225 226 i = b->method->bread(b, out, outl); 227 228 if (i > 0) 229 b->num_read += (unsigned long)i; 230 231 if (cb != NULL) 232 i = (int)cb(b, BIO_CB_READ|BIO_CB_RETURN, out, outl, 233 0L, (long)i); 234 return (i); 235 } 236 237 int 238 BIO_write(BIO *b, const void *in, int inl) 239 { 240 int i; 241 long (*cb)(BIO *, int, const char *, int, long, long); 242 243 if (b == NULL) 244 return (0); 245 246 cb = b->callback; 247 if ((b->method == NULL) || (b->method->bwrite == NULL)) { 248 BIOerr(BIO_F_BIO_WRITE, BIO_R_UNSUPPORTED_METHOD); 249 return (-2); 250 } 251 252 if ((cb != NULL) && 253 ((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0)) 254 return (i); 255 256 if (!b->init) { 257 BIOerr(BIO_F_BIO_WRITE, BIO_R_UNINITIALIZED); 258 return (-2); 259 } 260 261 i = b->method->bwrite(b, in, inl); 262 263 if (i > 0) 264 b->num_write += (unsigned long)i; 265 266 if (cb != NULL) 267 i = (int)cb(b, BIO_CB_WRITE|BIO_CB_RETURN, in, inl, 268 0L, (long)i); 269 return (i); 270 } 271 272 int 273 BIO_puts(BIO *b, const char *in) 274 { 275 int i; 276 long (*cb)(BIO *, int, const char *, int, long, long); 277 278 if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) { 279 BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD); 280 return (-2); 281 } 282 283 cb = b->callback; 284 285 if ((cb != NULL) && 286 ((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0)) 287 return (i); 288 289 if (!b->init) { 290 BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED); 291 return (-2); 292 } 293 294 i = b->method->bputs(b, in); 295 296 if (i > 0) 297 b->num_write += (unsigned long)i; 298 299 if (cb != NULL) 300 i = (int)cb(b, BIO_CB_PUTS|BIO_CB_RETURN, in, 0, 0L, (long)i); 301 return (i); 302 } 303 304 int 305 BIO_gets(BIO *b, char *in, int inl) 306 { 307 int i; 308 long (*cb)(BIO *, int, const char *, int, long, long); 309 310 if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) { 311 BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD); 312 return (-2); 313 } 314 315 cb = b->callback; 316 317 if ((cb != NULL) && 318 ((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0)) 319 return (i); 320 321 if (!b->init) { 322 BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED); 323 return (-2); 324 } 325 326 i = b->method->bgets(b, in, inl); 327 328 if (cb != NULL) 329 i = (int)cb(b, BIO_CB_GETS|BIO_CB_RETURN, in, inl, 0L, (long)i); 330 return (i); 331 } 332 333 int 334 BIO_indent(BIO *b, int indent, int max) 335 { 336 if (indent < 0) 337 indent = 0; 338 if (indent > max) 339 indent = max; 340 while (indent--) 341 if (BIO_puts(b, " ") != 1) 342 return 0; 343 return 1; 344 } 345 346 long 347 BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) 348 { 349 int i; 350 351 i = iarg; 352 return (BIO_ctrl(b, cmd, larg,(char *)&i)); 353 } 354 355 char 356 *BIO_ptr_ctrl(BIO *b, int cmd, long larg) 357 { 358 char *p = NULL; 359 360 if (BIO_ctrl(b, cmd, larg,(char *)&p) <= 0) 361 return (NULL); 362 else 363 return (p); 364 } 365 366 long 367 BIO_ctrl(BIO *b, int cmd, long larg, void *parg) 368 { 369 long ret; 370 long (*cb)(BIO *, int, const char *, int, long, long); 371 372 if (b == NULL) 373 return (0); 374 375 if ((b->method == NULL) || (b->method->ctrl == NULL)) { 376 BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD); 377 return (-2); 378 } 379 380 cb = b->callback; 381 382 if ((cb != NULL) && 383 ((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0)) 384 return (ret); 385 386 ret = b->method->ctrl(b, cmd, larg, parg); 387 388 if (cb != NULL) 389 ret = cb(b, BIO_CB_CTRL|BIO_CB_RETURN, parg, cmd, larg, ret); 390 return (ret); 391 } 392 393 long 394 BIO_callback_ctrl(BIO *b, int cmd, 395 void (*fp)(struct bio_st *, int, const char *, int, long, long)) 396 { 397 long ret; 398 long (*cb)(BIO *, int, const char *, int, long, long); 399 400 if (b == NULL) 401 return (0); 402 403 if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) { 404 BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD); 405 return (-2); 406 } 407 408 cb = b->callback; 409 410 if ((cb != NULL) && 411 ((ret = cb(b, BIO_CB_CTRL,(void *)&fp, cmd, 0, 1L)) <= 0)) 412 return (ret); 413 414 ret = b->method->callback_ctrl(b, cmd, fp); 415 416 if (cb != NULL) 417 ret = cb(b, BIO_CB_CTRL|BIO_CB_RETURN,(void *)&fp, cmd, 0, ret); 418 return (ret); 419 } 420 421 /* It is unfortunate to duplicate in functions what the BIO_(w)pending macros 422 * do; but those macros have inappropriate return type, and for interfacing 423 * from other programming languages, C macros aren't much of a help anyway. */ 424 size_t 425 BIO_ctrl_pending(BIO *bio) 426 { 427 return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL); 428 } 429 430 size_t 431 BIO_ctrl_wpending(BIO *bio) 432 { 433 return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL); 434 } 435 436 437 /* put the 'bio' on the end of b's list of operators */ 438 BIO 439 *BIO_push(BIO *b, BIO *bio) 440 { 441 BIO *lb; 442 443 if (b == NULL) 444 return (bio); 445 lb = b; 446 while (lb->next_bio != NULL) 447 lb = lb->next_bio; 448 lb->next_bio = bio; 449 if (bio != NULL) 450 bio->prev_bio = lb; 451 /* called to do internal processing */ 452 BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb); 453 return (b); 454 } 455 456 /* Remove the first and return the rest */ 457 BIO 458 *BIO_pop(BIO *b) 459 { 460 BIO *ret; 461 462 if (b == NULL) 463 return (NULL); 464 ret = b->next_bio; 465 466 BIO_ctrl(b, BIO_CTRL_POP, 0, b); 467 468 if (b->prev_bio != NULL) 469 b->prev_bio->next_bio = b->next_bio; 470 if (b->next_bio != NULL) 471 b->next_bio->prev_bio = b->prev_bio; 472 473 b->next_bio = NULL; 474 b->prev_bio = NULL; 475 return (ret); 476 } 477 478 BIO 479 *BIO_get_retry_BIO(BIO *bio, int *reason) 480 { 481 BIO *b, *last; 482 483 b = last = bio; 484 for (;;) { 485 if (!BIO_should_retry(b)) break; 486 last = b; 487 b = b->next_bio; 488 if (b == NULL) 489 break; 490 } 491 if (reason != NULL) 492 *reason = last->retry_reason; 493 return (last); 494 } 495 496 int 497 BIO_get_retry_reason(BIO *bio) 498 { 499 return (bio->retry_reason); 500 } 501 502 BIO 503 *BIO_find_type(BIO *bio, int type) 504 { 505 int mt, mask; 506 507 if (!bio) 508 return NULL; 509 mask = type & 0xff; 510 do { 511 if (bio->method != NULL) { 512 mt = bio->method->type; 513 if (!mask) { 514 if (mt & type) 515 return (bio); 516 } else if (mt == type) 517 return (bio); 518 } 519 bio = bio->next_bio; 520 } while (bio != NULL); 521 return (NULL); 522 } 523 524 BIO 525 *BIO_next(BIO *b) 526 { 527 if (!b) 528 return NULL; 529 return b->next_bio; 530 } 531 532 void 533 BIO_free_all(BIO *bio) 534 { 535 BIO *b; 536 int ref; 537 538 while (bio != NULL) { 539 b = bio; 540 ref = b->references; 541 bio = bio->next_bio; 542 BIO_free(b); 543 /* Since ref count > 1, don't free anyone else. */ 544 if (ref > 1) 545 break; 546 } 547 } 548 549 BIO 550 *BIO_dup_chain(BIO *in) 551 { 552 BIO *ret = NULL, *eoc = NULL, *bio, *new_bio; 553 554 for (bio = in; bio != NULL; bio = bio->next_bio) { 555 if ((new_bio = BIO_new(bio->method)) == NULL) goto err; 556 new_bio->callback = bio->callback; 557 new_bio->cb_arg = bio->cb_arg; 558 new_bio->init = bio->init; 559 new_bio->shutdown = bio->shutdown; 560 new_bio->flags = bio->flags; 561 562 /* This will let SSL_s_sock() work with stdin/stdout */ 563 new_bio->num = bio->num; 564 565 if (!BIO_dup_state(bio,(char *)new_bio)) { 566 BIO_free(new_bio); 567 goto err; 568 } 569 570 /* copy app data */ 571 if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, 572 &new_bio->ex_data, &bio->ex_data)) 573 goto err; 574 575 if (ret == NULL) { 576 eoc = new_bio; 577 ret = eoc; 578 } else { 579 BIO_push(eoc, new_bio); 580 eoc = new_bio; 581 } 582 } 583 return (ret); 584 err: 585 if (ret != NULL) 586 BIO_free(ret); 587 return (NULL); 588 589 } 590 591 void 592 BIO_copy_next_retry(BIO *b) 593 { 594 BIO_set_flags(b, BIO_get_retry_flags(b->next_bio)); 595 b->retry_reason = b->next_bio->retry_reason; 596 } 597 598 int 599 BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 600 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) 601 { 602 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp, 603 new_func, dup_func, free_func); 604 } 605 606 int 607 BIO_set_ex_data(BIO *bio, int idx, void *data) 608 { 609 return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data)); 610 } 611 612 void 613 *BIO_get_ex_data(BIO *bio, int idx) 614 { 615 return (CRYPTO_get_ex_data(&(bio->ex_data), idx)); 616 } 617 618 unsigned long 619 BIO_number_read(BIO *bio) 620 { 621 if (bio) 622 return bio->num_read; 623 return 0; 624 } 625 626 unsigned long 627 BIO_number_written(BIO *bio) 628 { 629 if (bio) 630 return bio->num_write; 631 return 0; 632 } 633 634 IMPLEMENT_STACK_OF(BIO) 635