1 /* ssl/bio_ssl.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 <stdlib.h> 61 #include <string.h> 62 #include <errno.h> 63 #include "crypto.h" 64 #include "bio.h" 65 #include "err.h" 66 #include "ssl.h" 67 68 #ifndef NOPROTO 69 static int ssl_write(BIO *h,char *buf,int num); 70 static int ssl_read(BIO *h,char *buf,int size); 71 static int ssl_puts(BIO *h,char *str); 72 static long ssl_ctrl(BIO *h,int cmd,long arg1,char *arg2); 73 static int ssl_new(BIO *h); 74 static int ssl_free(BIO *data); 75 #else 76 static int ssl_write(); 77 static int ssl_read(); 78 static int ssl_puts(); 79 static long ssl_ctrl(); 80 static int ssl_new(); 81 static int ssl_free(); 82 #endif 83 84 typedef struct bio_ssl_st 85 { 86 SSL *ssl; /* The ssl handle :-) */ 87 /* re-negotiate every time the total number of bytes is this size */ 88 int num_renegotiates; 89 unsigned long renegotiate_count; 90 unsigned long byte_count; 91 unsigned long renegotiate_timeout; 92 unsigned long last_time; 93 } BIO_SSL; 94 95 static BIO_METHOD methods_sslp= 96 { 97 BIO_TYPE_SSL,"ssl", 98 ssl_write, 99 ssl_read, 100 ssl_puts, 101 NULL, /* ssl_gets, */ 102 ssl_ctrl, 103 ssl_new, 104 ssl_free, 105 }; 106 107 BIO_METHOD *BIO_f_ssl() 108 { 109 return(&methods_sslp); 110 } 111 112 static int ssl_new(bi) 113 BIO *bi; 114 { 115 BIO_SSL *bs; 116 117 bs=(BIO_SSL *)Malloc(sizeof(BIO_SSL)); 118 if (bs == NULL) 119 { 120 BIOerr(BIO_F_SSL_NEW,ERR_R_MALLOC_FAILURE); 121 return(0); 122 } 123 memset(bs,0,sizeof(BIO_SSL)); 124 bi->init=0; 125 bi->ptr=(char *)bs; 126 bi->flags=0; 127 return(1); 128 } 129 130 static int ssl_free(a) 131 BIO *a; 132 { 133 BIO_SSL *bs; 134 135 if (a == NULL) return(0); 136 bs=(BIO_SSL *)a->ptr; 137 if (bs->ssl != NULL) SSL_shutdown(bs->ssl); 138 if (a->shutdown) 139 { 140 if (a->init && (bs->ssl != NULL)) 141 SSL_free(bs->ssl); 142 a->init=0; 143 a->flags=0; 144 } 145 if (a->ptr != NULL) 146 Free(a->ptr); 147 return(1); 148 } 149 150 static int ssl_read(b,out,outl) 151 BIO *b; 152 char *out; 153 int outl; 154 { 155 int ret=1; 156 BIO_SSL *sb; 157 SSL *ssl; 158 int retry_reason=0; 159 int r=0; 160 161 if (out == NULL) return(0); 162 sb=(BIO_SSL *)b->ptr; 163 ssl=sb->ssl; 164 165 BIO_clear_retry_flags(b); 166 167 #if 0 168 if (!SSL_is_init_finished(ssl)) 169 { 170 /* ret=SSL_do_handshake(ssl); */ 171 if (ret > 0) 172 { 173 174 outflags=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY); 175 ret= -1; 176 goto end; 177 } 178 } 179 #endif 180 /* if (ret > 0) */ 181 ret=SSL_read(ssl,out,outl); 182 183 switch (SSL_get_error(ssl,ret)) 184 { 185 case SSL_ERROR_NONE: 186 if (ret <= 0) break; 187 if (sb->renegotiate_count > 0) 188 { 189 sb->byte_count+=ret; 190 if (sb->byte_count > sb->renegotiate_count) 191 { 192 sb->byte_count=0; 193 sb->num_renegotiates++; 194 SSL_renegotiate(ssl); 195 r=1; 196 } 197 } 198 if ((sb->renegotiate_timeout > 0) && (!r)) 199 { 200 unsigned long tm; 201 202 tm=(unsigned long)time(NULL); 203 if (tm > sb->last_time+sb->renegotiate_timeout) 204 { 205 sb->last_time=tm; 206 sb->num_renegotiates++; 207 SSL_renegotiate(ssl); 208 } 209 } 210 211 break; 212 case SSL_ERROR_WANT_READ: 213 BIO_set_retry_read(b); 214 break; 215 case SSL_ERROR_WANT_WRITE: 216 BIO_set_retry_write(b); 217 break; 218 case SSL_ERROR_WANT_X509_LOOKUP: 219 BIO_set_retry_special(b); 220 retry_reason=BIO_RR_SSL_X509_LOOKUP; 221 break; 222 case SSL_ERROR_WANT_CONNECT: 223 BIO_set_retry_special(b); 224 retry_reason=BIO_RR_CONNECT; 225 break; 226 case SSL_ERROR_SYSCALL: 227 case SSL_ERROR_SSL: 228 case SSL_ERROR_ZERO_RETURN: 229 default: 230 break; 231 } 232 233 b->retry_reason=retry_reason; 234 return(ret); 235 } 236 237 static int ssl_write(b,out,outl) 238 BIO *b; 239 char *out; 240 int outl; 241 { 242 int ret,r=0; 243 int retry_reason=0; 244 SSL *ssl; 245 BIO_SSL *bs; 246 247 if (out == NULL) return(0); 248 bs=(BIO_SSL *)b->ptr; 249 ssl=bs->ssl; 250 251 BIO_clear_retry_flags(b); 252 253 /* ret=SSL_do_handshake(ssl); 254 if (ret > 0) */ 255 ret=SSL_write(ssl,out,outl); 256 257 switch (SSL_get_error(ssl,ret)) 258 { 259 case SSL_ERROR_NONE: 260 if (ret <= 0) break; 261 if (bs->renegotiate_count > 0) 262 { 263 bs->byte_count+=ret; 264 if (bs->byte_count > bs->renegotiate_count) 265 { 266 bs->byte_count=0; 267 bs->num_renegotiates++; 268 SSL_renegotiate(ssl); 269 r=1; 270 } 271 } 272 if ((bs->renegotiate_timeout > 0) && (!r)) 273 { 274 unsigned long tm; 275 276 tm=(unsigned long)time(NULL); 277 if (tm > bs->last_time+bs->renegotiate_timeout) 278 { 279 bs->last_time=tm; 280 bs->num_renegotiates++; 281 SSL_renegotiate(ssl); 282 } 283 } 284 break; 285 case SSL_ERROR_WANT_WRITE: 286 BIO_set_retry_write(b); 287 break; 288 case SSL_ERROR_WANT_READ: 289 BIO_set_retry_read(b); 290 break; 291 case SSL_ERROR_WANT_X509_LOOKUP: 292 BIO_set_retry_special(b); 293 retry_reason=BIO_RR_SSL_X509_LOOKUP; 294 break; 295 case SSL_ERROR_WANT_CONNECT: 296 BIO_set_retry_special(b); 297 retry_reason=BIO_RR_CONNECT; 298 case SSL_ERROR_SYSCALL: 299 case SSL_ERROR_SSL: 300 default: 301 break; 302 } 303 304 b->retry_reason=retry_reason; 305 return(ret); 306 } 307 308 static long ssl_ctrl(b,cmd,num,ptr) 309 BIO *b; 310 int cmd; 311 long num; 312 char *ptr; 313 { 314 SSL **sslp,*ssl; 315 BIO_SSL *bs; 316 BIO *dbio,*bio; 317 long ret=1; 318 319 bs=(BIO_SSL *)b->ptr; 320 ssl=bs->ssl; 321 if ((ssl == NULL) && (cmd != BIO_C_SET_SSL)) 322 return(0); 323 switch (cmd) 324 { 325 case BIO_CTRL_RESET: 326 SSL_shutdown(ssl); 327 328 if (ssl->handshake_func == ssl->method->ssl_connect) 329 SSL_set_connect_state(ssl); 330 else if (ssl->handshake_func == ssl->method->ssl_accept) 331 SSL_set_accept_state(ssl); 332 333 SSL_clear(ssl); 334 335 if (b->next_bio != NULL) 336 ret=BIO_ctrl(b->next_bio,cmd,num,ptr); 337 else if (ssl->rbio != NULL) 338 ret=BIO_ctrl(ssl->rbio,cmd,num,ptr); 339 else 340 ret=1; 341 break; 342 case BIO_CTRL_INFO: 343 ret=0; 344 break; 345 case BIO_C_SSL_MODE: 346 if (num) /* client mode */ 347 SSL_set_connect_state(ssl); 348 else 349 SSL_set_accept_state(ssl); 350 break; 351 case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT: 352 ret=bs->renegotiate_timeout; 353 if (num < 60) num=5; 354 bs->renegotiate_timeout=(unsigned long)num; 355 bs->last_time=(unsigned long)time(NULL); 356 break; 357 case BIO_C_SET_SSL_RENEGOTIATE_BYTES: 358 ret=bs->renegotiate_count; 359 if ((long)num >=512) 360 bs->renegotiate_count=(unsigned long)num; 361 break; 362 case BIO_C_GET_SSL_NUM_RENEGOTIATES: 363 ret=bs->num_renegotiates; 364 break; 365 case BIO_C_SET_SSL: 366 if (ssl != NULL) 367 ssl_free(b); 368 b->shutdown=(int)num; 369 ssl=(SSL *)ptr; 370 ((BIO_SSL *)b->ptr)->ssl=ssl; 371 bio=SSL_get_rbio(ssl); 372 if (bio != NULL) 373 { 374 if (b->next_bio != NULL) 375 BIO_push(bio,b->next_bio); 376 b->next_bio=bio; 377 CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO); 378 } 379 b->init=1; 380 break; 381 case BIO_C_GET_SSL: 382 if (ptr != NULL) 383 { 384 sslp=(SSL **)ptr; 385 *sslp=ssl; 386 } 387 else 388 ret=0; 389 break; 390 case BIO_CTRL_GET_CLOSE: 391 ret=b->shutdown; 392 break; 393 case BIO_CTRL_SET_CLOSE: 394 b->shutdown=(int)num; 395 break; 396 case BIO_CTRL_WPENDING: 397 ret=BIO_ctrl(ssl->wbio,cmd,num,ptr); 398 break; 399 case BIO_CTRL_PENDING: 400 ret=SSL_pending(ssl); 401 if (ret == 0) 402 ret=BIO_pending(ssl->rbio); 403 break; 404 case BIO_CTRL_FLUSH: 405 BIO_clear_retry_flags(b); 406 ret=BIO_ctrl(ssl->wbio,cmd,num,ptr); 407 BIO_copy_next_retry(b); 408 break; 409 case BIO_CTRL_PUSH: 410 if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) 411 { 412 SSL_set_bio(ssl,b->next_bio,b->next_bio); 413 CRYPTO_add(&b->next_bio->references,1,CRYPTO_LOCK_BIO); 414 } 415 break; 416 case BIO_CTRL_POP: 417 /* ugly bit of a hack */ 418 if (ssl->rbio != ssl->wbio) /* we are in trouble :-( */ 419 { 420 BIO_free_all(ssl->wbio); 421 } 422 ssl->wbio=NULL; 423 ssl->rbio=NULL; 424 break; 425 case BIO_C_DO_STATE_MACHINE: 426 BIO_clear_retry_flags(b); 427 428 b->retry_reason=0; 429 ret=(int)SSL_do_handshake(ssl); 430 431 switch (SSL_get_error(ssl,(int)ret)) 432 { 433 case SSL_ERROR_WANT_READ: 434 BIO_set_flags(b, 435 BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY); 436 break; 437 case SSL_ERROR_WANT_WRITE: 438 BIO_set_flags(b, 439 BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY); 440 break; 441 case SSL_ERROR_WANT_CONNECT: 442 BIO_set_flags(b, 443 BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY); 444 b->retry_reason=b->next_bio->retry_reason; 445 break; 446 default: 447 break; 448 } 449 break; 450 case BIO_CTRL_DUP: 451 dbio=(BIO *)ptr; 452 if (((BIO_SSL *)dbio->ptr)->ssl != NULL) 453 SSL_free(((BIO_SSL *)dbio->ptr)->ssl); 454 ((BIO_SSL *)dbio->ptr)->ssl=SSL_dup(ssl); 455 ((BIO_SSL *)dbio->ptr)->renegotiate_count= 456 ((BIO_SSL *)b->ptr)->renegotiate_count; 457 ((BIO_SSL *)dbio->ptr)->byte_count= 458 ((BIO_SSL *)b->ptr)->byte_count; 459 ((BIO_SSL *)dbio->ptr)->renegotiate_timeout= 460 ((BIO_SSL *)b->ptr)->renegotiate_timeout; 461 ((BIO_SSL *)dbio->ptr)->last_time= 462 ((BIO_SSL *)b->ptr)->last_time; 463 ret=(((BIO_SSL *)dbio->ptr)->ssl != NULL); 464 break; 465 case BIO_C_GET_FD: 466 ret=BIO_ctrl(ssl->rbio,cmd,num,ptr); 467 break; 468 case BIO_CTRL_SET_CALLBACK: 469 SSL_set_info_callback(ssl,(void (*)())ptr); 470 break; 471 case BIO_CTRL_GET_CALLBACK: 472 { 473 void (**fptr)(); 474 475 fptr=(void (**)())ptr; 476 *fptr=SSL_get_info_callback(ssl); 477 } 478 break; 479 default: 480 ret=BIO_ctrl(ssl->rbio,cmd,num,ptr); 481 break; 482 } 483 return(ret); 484 } 485 486 static int ssl_puts(bp,str) 487 BIO *bp; 488 char *str; 489 { 490 int n,ret; 491 492 n=strlen(str); 493 ret=BIO_write(bp,str,n); 494 return(ret); 495 } 496 497 BIO *BIO_new_buffer_ssl_connect(ctx) 498 SSL_CTX *ctx; 499 { 500 BIO *ret=NULL,*buf=NULL,*ssl=NULL; 501 502 if ((buf=BIO_new(BIO_f_buffer())) == NULL) 503 return(NULL); 504 if ((ssl=BIO_new_ssl_connect(ctx)) == NULL) 505 goto err; 506 if ((ret=BIO_push(buf,ssl)) == NULL) 507 goto err; 508 return(ret); 509 err: 510 if (buf != NULL) BIO_free(buf); 511 if (ssl != NULL) BIO_free(ssl); 512 return(NULL); 513 } 514 515 BIO *BIO_new_ssl_connect(ctx) 516 SSL_CTX *ctx; 517 { 518 BIO *ret=NULL,*con=NULL,*ssl=NULL; 519 520 if ((con=BIO_new(BIO_s_connect())) == NULL) 521 return(NULL); 522 if ((ssl=BIO_new_ssl(ctx,1)) == NULL) 523 goto err; 524 if ((ret=BIO_push(ssl,con)) == NULL) 525 goto err; 526 return(ret); 527 err: 528 if (con != NULL) BIO_free(con); 529 if (ret != NULL) BIO_free(ret); 530 return(NULL); 531 } 532 533 BIO *BIO_new_ssl(ctx,client) 534 SSL_CTX *ctx; 535 int client; 536 { 537 BIO *ret; 538 SSL *ssl; 539 540 if ((ret=BIO_new(BIO_f_ssl())) == NULL) 541 return(NULL); 542 if ((ssl=SSL_new(ctx)) == NULL) 543 { 544 BIO_free(ret); 545 return(NULL); 546 } 547 if (client) 548 SSL_set_connect_state(ssl); 549 else 550 SSL_set_accept_state(ssl); 551 552 BIO_set_ssl(ret,ssl,BIO_CLOSE); 553 return(ret); 554 } 555 556 int BIO_ssl_copy_session_id(t,f) 557 BIO *t,*f; 558 { 559 t=BIO_find_type(t,BIO_TYPE_SSL); 560 f=BIO_find_type(f,BIO_TYPE_SSL); 561 if ((t == NULL) || (f == NULL)) 562 return(0); 563 if ( (((BIO_SSL *)t->ptr)->ssl == NULL) || 564 (((BIO_SSL *)f->ptr)->ssl == NULL)) 565 return(0); 566 SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl,((BIO_SSL *)f->ptr)->ssl); 567 return(1); 568 } 569 570 void BIO_ssl_shutdown(b) 571 BIO *b; 572 { 573 SSL *s; 574 575 while (b != NULL) 576 { 577 if (b->method->type == BIO_TYPE_SSL) 578 { 579 s=((BIO_SSL *)b->ptr)->ssl; 580 SSL_shutdown(s); 581 break; 582 } 583 b=b->next_bio; 584 } 585 } 586