Successful connection!
\r\n" 183 | 184 | #define MAX_HANDSHAKE_STEPS (sizeof(client_steps)/sizeof(client_steps[0])) 185 | 186 | /* Store sent messages in files for fuzzing. */ 187 | #if !defined(PACKET_FILE_PREFIX) 188 | #define PACKET_FILE_PREFIX "./packet-" 189 | #endif 190 | static size_t packet_count = 1; 191 | static size_t packet_in_num = 0; 192 | static const char *packet_in_file = NULL; 193 | 194 | #if !SOCKET_COMMUNICATION 195 | #define BUF_SIZE 4096 196 | 197 | static unsigned char server_send_buf[BUF_SIZE]; 198 | static size_t server_send_off = 0; 199 | static size_t server_recv_off = 0; 200 | 201 | static unsigned char client_send_buf[BUF_SIZE]; 202 | static size_t client_send_off = 0; 203 | static size_t client_recv_off = 0; 204 | 205 | static unsigned char *shared_buf = NULL; 206 | static size_t *send_off = NULL; 207 | static size_t *recv_off = NULL; 208 | 209 | #else 210 | static int recv_would_block = 0; 211 | #endif 212 | 213 | #define DEBUG_LEVEL 0 214 | 215 | /* 216 | * Write at most 'len' characters to shared buffer or file. 217 | * Multiple sends can occur before a receive; therefore, maintain an 218 | * offset. 219 | * Also, write content of file to shared buffer, if desired (determined 220 | * by command-line options). 221 | */ 222 | static int send_custom( void *ctx, const unsigned char *buf, 223 | size_t len ) 224 | { 225 | int ret; 226 | #if SOCKET_COMMUNICATION 227 | int fd = *((int *) ctx); 228 | 229 | if( fd < 0 ) 230 | return( POLARSSL_ERR_NET_SOCKET_FAILED ); 231 | #else 232 | ((void) ctx); 233 | #endif 234 | 235 | /* Read packet from file or write packet to file */ 236 | if( packet_count == packet_in_num ) 237 | { 238 | FILE *in_file; 239 | #if !SOCKET_COMMUNICATION 240 | size_t rlen; 241 | #endif 242 | 243 | if( !packet_in_file ) 244 | { 245 | polarssl_fprintf( stderr, "Packet input file not specified!\n" ); 246 | exit(1); 247 | } 248 | 249 | /* Read packet from file, ignoring buf */ 250 | in_file = fopen( packet_in_file, "rb" ); 251 | 252 | if( !in_file ) 253 | { 254 | perror( "Unable to open packet input file" ); 255 | exit( 1 ); 256 | } 257 | 258 | /* Write packet to socket/buffer. */ 259 | #if SOCKET_COMMUNICATION 260 | ret = (int) write( fd, buf, len ); 261 | #else 262 | rlen = fread( shared_buf, sizeof(shared_buf[0]), BUF_SIZE, 263 | in_file ); 264 | #endif 265 | if ( ferror( in_file ) ) 266 | { 267 | perror( "Unable to read packet input file" ); 268 | exit( 1 ); 269 | } 270 | #if !SOCKET_COMMUNICATION 271 | else { 272 | *send_off += rlen; 273 | ret = rlen; 274 | } 275 | #endif 276 | fclose( in_file ); 277 | } 278 | else 279 | { 280 | /* Write packet to socket/buffer. */ 281 | #if SOCKET_COMMUNICATION 282 | ret = (int) write( fd, buf, len ); 283 | #else 284 | if ( (len <= BUF_SIZE) && memcpy( shared_buf, buf, len ) ) 285 | { 286 | *send_off += len; 287 | ret = len; 288 | } 289 | else 290 | { 291 | ret = -1; 292 | } 293 | #endif 294 | 295 | if( packet_in_num == 0 ) 296 | { 297 | char out_filename[100]; 298 | FILE *out_file; 299 | 300 | /* Write packet to file. */ 301 | snprintf( out_filename, sizeof(out_filename), "%s%zd", 302 | PACKET_FILE_PREFIX, packet_count ); 303 | out_file = fopen( out_filename, "wb" ); 304 | fwrite( buf, sizeof(char), len, out_file ); 305 | fclose( out_file ); 306 | } 307 | } 308 | packet_count++; 309 | 310 | #if SOCKET_COMMUNICATION 311 | if( ret < 0 ) 312 | { 313 | if( net_would_block( fd ) != 0 ) 314 | return( POLARSSL_ERR_NET_WANT_WRITE ); 315 | 316 | #if( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ 317 | !defined(EFI32) 318 | if( WSAGetLastError() == WSAECONNRESET ) 319 | return( POLARSSL_ERR_NET_CONN_RESET ); 320 | #else 321 | if( errno == EPIPE || errno == ECONNRESET ) 322 | return( POLARSSL_ERR_NET_CONN_RESET ); 323 | 324 | if( errno == EINTR ) 325 | return( POLARSSL_ERR_NET_WANT_WRITE ); 326 | #endif 327 | 328 | return( POLARSSL_ERR_NET_SEND_FAILED ); 329 | } 330 | #endif 331 | 332 | return( ret ); 333 | } 334 | 335 | /* 336 | * Read at most 'len' characters and write to buf. 337 | */ 338 | static int recv_custom( void *ctx, unsigned char *buf, size_t len ) 339 | { 340 | int ret; 341 | #if SOCKET_COMMUNICATION 342 | int fd = *((int *) ctx); 343 | 344 | if( fd < 0 ) 345 | return( POLARSSL_ERR_NET_SOCKET_FAILED ); 346 | ret = (int) read( fd, buf, len ); 347 | #else 348 | ((void) ctx); 349 | ((void) len); 350 | 351 | if ( ((*recv_off + len) <= BUF_SIZE) && memcpy( buf, &shared_buf[*recv_off], len ) ) 352 | { 353 | *recv_off += len; 354 | if( *recv_off == *send_off ) 355 | { 356 | /* 357 | * Done copying buffer. 358 | * Reset offsets for next calls of send and rcv functions. 359 | */ 360 | *recv_off = 0; 361 | *send_off = 0; 362 | } 363 | /* Imitate the return value of read(2). */ 364 | ret = len; 365 | } 366 | else 367 | { 368 | ret = -1; 369 | } 370 | #endif 371 | 372 | #if SOCKET_COMMUNICATION 373 | if( ret < 0 ) 374 | { 375 | if( net_would_block( fd ) != 0 ) 376 | return( POLARSSL_ERR_NET_WANT_READ ); 377 | 378 | #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ 379 | !defined(EFI32) 380 | if( WSAGetLastError() == WSAECONNRESET ) 381 | return( POLARSSL_ERR_NET_CONN_RESET ); 382 | #else 383 | if( errno == EPIPE || errno == ECONNRESET ) 384 | return( POLARSSL_ERR_NET_CONN_RESET ); 385 | 386 | if( errno == EINTR ) 387 | return( POLARSSL_ERR_NET_WANT_READ ); 388 | #endif 389 | 390 | return( POLARSSL_ERR_NET_RECV_FAILED ); 391 | } 392 | #endif 393 | 394 | return( ret ); 395 | } 396 | 397 | /* 398 | * Make the program deterministic for fuzzing: always generate 1 bytes 399 | * instead of random numbers. 400 | */ 401 | static int ctr_drbg_deterministic( void *p_rng, unsigned char *output, size_t output_len ) 402 | { 403 | ((void) p_rng); 404 | 405 | /* Note that key generation would fail with 0 bytes. */ 406 | memset( output, 1, output_len ); 407 | 408 | return 0; 409 | } 410 | 411 | #if !SOCKET_COMMUNICATION 412 | static int func_server_send_buf( void *ctx, const unsigned char *buf, 413 | size_t len ) 414 | { 415 | shared_buf = server_send_buf; 416 | send_off = &server_send_off; 417 | 418 | return send_custom(ctx, buf, len); 419 | } 420 | 421 | static int func_client_send_buf( void *ctx, const unsigned char *buf, 422 | size_t len ) 423 | { 424 | shared_buf = client_send_buf; 425 | send_off = &client_send_off; 426 | 427 | return send_custom(ctx, buf, len); 428 | } 429 | 430 | static int func_server_recv_buf( void *ctx, unsigned char *buf, 431 | size_t len ) 432 | { 433 | shared_buf = client_send_buf; 434 | send_off = &client_send_off; 435 | recv_off = &server_recv_off; 436 | 437 | return recv_custom(ctx, buf, len); 438 | } 439 | 440 | static int func_client_recv_buf( void *ctx, unsigned char *buf, 441 | size_t len ) 442 | { 443 | shared_buf = server_send_buf; 444 | send_off = &server_send_off; 445 | recv_off = &client_recv_off; 446 | 447 | return recv_custom(ctx, buf, len); 448 | } 449 | #endif 450 | 451 | static void usage( const char *prog ) 452 | { 453 | polarssl_fprintf( stderr, "Usage: %s [packet number] [packet file]\n", prog ); 454 | } 455 | 456 | int main( int argc, const char *argv[] ) 457 | { 458 | /* Client and server declarations. */ 459 | int ret; 460 | int len; 461 | #if SOCKET_COMMUNICATION 462 | int listen_fd = -1; 463 | int client_fd = -1; 464 | int server_fd = -1; 465 | #endif 466 | unsigned char buf[1024]; 467 | /* Handshake step counter */ 468 | size_t step = 1; 469 | int flags; 470 | /* 471 | * The following number of steps are hardcoded to ensure 472 | * that the client and server complete the handshake without 473 | * waiting infinitely for the other side to send data. 474 | * 475 | * 1 2 3 4 5 6 7 8 9 476 | */ 477 | int client_steps[] = { 2, 1, 1, 1, 4, 2, 1, 1, 3 }; 478 | int server_steps[] = { 3, 1, 1, 3, 2, 1, 2, 1, 2 }; 479 | 480 | ssl_context s_ssl, c_ssl; 481 | x509_crt srvcert; 482 | pk_context pkey; 483 | #if defined(POLARSSL_SSL_CACHE_C) 484 | ssl_cache_context cache; 485 | #endif 486 | 487 | if( argc == 3) 488 | { 489 | packet_in_num = atoi(argv[1]); 490 | packet_in_file = argv[2]; 491 | } 492 | else if( argc != 1) 493 | { 494 | usage(argv[0]); 495 | exit(1); 496 | } 497 | 498 | /* Server init */ 499 | memset( &s_ssl, 0, sizeof( ssl_context ) ); 500 | #if defined(POLARSSL_SSL_CACHE_C) 501 | ssl_cache_init( &cache ); 502 | #endif 503 | x509_crt_init( &srvcert ); 504 | pk_init( &pkey ); 505 | 506 | /* Client init */ 507 | memset( &c_ssl, 0, sizeof( ssl_context ) ); 508 | /*x509_crt_init( &cacert );*/ 509 | 510 | #if defined(POLARSSL_DEBUG_C) 511 | debug_set_threshold( DEBUG_LEVEL ); 512 | #endif 513 | 514 | /* 515 | * Server: 516 | * Load the certificates and private RSA key 517 | */ 518 | if( packet_in_num == 0 ) 519 | { 520 | printf( " . Loading the server cert. and key..." ); 521 | fflush( stdout ); 522 | } 523 | 524 | /* 525 | * This demonstration program uses embedded test certificates. 526 | * Instead, you may want to use x509_crt_parse_file() to read the 527 | * server and CA certificates, as well as pk_parse_keyfile(). 528 | */ 529 | ret = x509_crt_parse( &srvcert, (const unsigned char *) test_srv_crt, 530 | strlen( test_srv_crt ) ); 531 | if( ret != 0 ) 532 | { 533 | printf( " failed\n ! x509_crt_parse returned %d\n\n", ret ); 534 | goto exit; 535 | } 536 | 537 | ret = x509_crt_parse( &srvcert, (const unsigned char *) test_ca_list, 538 | strlen( test_ca_list ) ); 539 | if( ret != 0 ) 540 | { 541 | polarssl_printf( " failed\n ! x509_crt_parse returned %d\n\n", ret ); 542 | goto exit; 543 | } 544 | 545 | ret = pk_parse_key( &pkey, (const unsigned char *) test_srv_key, 546 | strlen( test_srv_key ), NULL, 0 ); 547 | if( ret != 0 ) 548 | { 549 | printf( " failed\n ! pk_parse_key returned %d\n\n", ret ); 550 | goto exit; 551 | } 552 | 553 | if( packet_in_num == 0 ) 554 | { 555 | printf( " ok\n" ); 556 | } 557 | 558 | /* 559 | * Server: 560 | * Setup stuff 561 | */ 562 | if( packet_in_num == 0 ) 563 | { 564 | printf( " . Server: Setting up the SSL data...." ); 565 | fflush( stdout ); 566 | } 567 | 568 | if( ( ret = ssl_init( &s_ssl ) ) != 0 ) 569 | { 570 | polarssl_printf( " failed\n ! ssl_init returned %d\n\n", ret ); 571 | goto exit; 572 | } 573 | 574 | ssl_set_endpoint( &s_ssl, SSL_IS_SERVER ); 575 | ssl_set_authmode( &s_ssl, SSL_VERIFY_NONE ); 576 | 577 | /* SSLv3 is deprecated, set minimum to TLS 1.0 */ 578 | ssl_set_min_version( &s_ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1 ); 579 | /* RC4 is deprecated, disable it */ 580 | ssl_set_arc4_support( &s_ssl, SSL_ARC4_DISABLED ); 581 | 582 | ssl_set_rng( &s_ssl, ctr_drbg_deterministic, NULL ); 583 | ssl_set_dbg( &s_ssl, my_debug, stdout ); 584 | 585 | #if defined(POLARSSL_SSL_CACHE_C) 586 | ssl_set_session_cache( &s_ssl, ssl_cache_get, &cache, 587 | ssl_cache_set, &cache ); 588 | #endif 589 | 590 | ssl_set_ca_chain( &s_ssl, srvcert.next, NULL, NULL ); 591 | if( ( ret = ssl_set_own_cert( &s_ssl, &srvcert, &pkey ) ) != 0 ) 592 | { 593 | printf( " failed\n ! ssl_set_own_cert returned %d\n\n", ret ); 594 | goto exit; 595 | } 596 | 597 | if( packet_in_num == 0 ) 598 | { 599 | printf( " ok\n" ); 600 | } 601 | 602 | ssl_session_reset( &s_ssl ); 603 | 604 | #if SOCKET_COMMUNICATION 605 | /* 606 | * Server: 607 | * Setup the listening TCP socket 608 | */ 609 | if( packet_in_num == 0 ) 610 | { 611 | printf( " . Bind on https://localhost:%d/ ...", SERVER_PORT ); 612 | fflush( stdout ); 613 | } 614 | 615 | if( ( ret = net_bind( &listen_fd, NULL, SERVER_PORT ) ) != 0 ) 616 | { 617 | printf( " failed\n ! net_bind returned %d\n\n", ret ); 618 | goto exit; 619 | } 620 | 621 | if( packet_in_num == 0 ) 622 | { 623 | printf( " ok\n" ); 624 | } 625 | 626 | /* 627 | * Client: 628 | * Start the connection 629 | */ 630 | if( packet_in_num == 0 ) 631 | { 632 | printf( " . Connecting to tcp/%s/%d...", SERVER_NAME, SERVER_PORT ); 633 | fflush( stdout ); 634 | } 635 | 636 | if( ( ret = net_connect( &server_fd, SERVER_NAME, 637 | SERVER_PORT ) ) != 0 ) 638 | { 639 | printf( " failed\n ! net_connect returned %d\n\n", ret ); 640 | goto exit; 641 | } 642 | 643 | if( packet_in_num == 0 ) 644 | { 645 | printf( " ok\n" ); 646 | } 647 | 648 | /* 649 | * Server: 650 | * Start listening for client connections 651 | */ 652 | if( packet_in_num == 0 ) 653 | { 654 | printf( " . Waiting for a remote connection ..." ); 655 | fflush( stdout ); 656 | } 657 | 658 | /* 659 | * Server: 660 | * Accept client connection (socket is set non-blocking in 661 | * library/net.c) 662 | */ 663 | if( ( ret = net_accept( listen_fd, &client_fd, 664 | NULL ) ) != 0 ) 665 | { 666 | printf( " failed\n ! net_accept returned %d\n\n", ret ); 667 | goto exit; 668 | } 669 | 670 | if( packet_in_num == 0 ) 671 | { 672 | printf( " ok\n" ); 673 | } 674 | 675 | ssl_set_bio( &s_ssl, recv_custom, &client_fd, send_custom, &client_fd ); 676 | #else 677 | ssl_set_bio( &s_ssl, func_server_recv_buf, NULL, func_server_send_buf, NULL ); 678 | #endif 679 | 680 | /* 681 | * Client: 682 | * Setup stuff 683 | */ 684 | if( packet_in_num == 0 ) 685 | { 686 | printf( " . Client: Setting up the SSL/TLS structure..." ); 687 | fflush( stdout ); 688 | } 689 | 690 | if( ( ret = ssl_init( &c_ssl ) ) != 0 ) 691 | { 692 | polarssl_printf( " failed\n ! ssl_init returned %d\n\n", ret ); 693 | goto exit; 694 | } 695 | 696 | if( packet_in_num == 0 ) 697 | { 698 | polarssl_printf( " ok\n" ); 699 | } 700 | 701 | ssl_set_endpoint( &c_ssl, SSL_IS_CLIENT ); 702 | /* OPTIONAL is not optimal for security, 703 | * but makes interop easier in this simplified example */ 704 | ssl_set_authmode( &c_ssl, SSL_VERIFY_OPTIONAL ); 705 | /* NONE permits man-in-the-middle attacks. */ 706 | /*ssl_set_authmode( &c_ssl, VERIFY_NONE );*/ 707 | /*ssl_set_authmode( &c_ssl, SSL_VERIFY_REQUIRED );*/ 708 | ssl_set_ca_chain( &c_ssl, &srvcert, NULL, "PolarSSL Server 1" ); 709 | 710 | /* SSLv3 is deprecated, set minimum to TLS 1.0 */ 711 | ssl_set_min_version( &c_ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1 ); 712 | /* RC4 is deprecated, disable it */ 713 | ssl_set_arc4_support( &c_ssl, SSL_ARC4_DISABLED ); 714 | 715 | ssl_set_rng( &c_ssl, ctr_drbg_deterministic, NULL ); 716 | ssl_set_dbg( &c_ssl, my_debug, stdout ); 717 | 718 | if( ( ret = ssl_set_hostname( &c_ssl, "mbed TLS Server 1" ) ) != 0 ) 719 | { 720 | printf( " failed\n ! ssl_set_hostname returned %d\n\n", ret ); 721 | goto exit; 722 | } 723 | 724 | #if SOCKET_COMMUNICATION 725 | ssl_set_bio( &c_ssl, recv_custom, &server_fd, send_custom, &server_fd ); 726 | #else 727 | ssl_set_bio( &c_ssl, func_client_recv_buf, NULL, func_client_send_buf, NULL ); 728 | #endif 729 | 730 | if( packet_in_num == 0 ) 731 | { 732 | printf( " . Performing the SSL/TLS handshake...\n" ); 733 | fflush( stdout ); 734 | } 735 | 736 | do { 737 | /* 738 | * Client: 739 | * Handshake step 740 | */ 741 | int i; 742 | int no_steps; 743 | 744 | if( c_ssl.state == SSL_HANDSHAKE_OVER ) { 745 | no_steps = 0; 746 | } else { 747 | no_steps = client_steps[step - 1]; 748 | } 749 | 750 | for (i = 0; i < no_steps; i++) { 751 | if( ( ret = ssl_handshake_step( &c_ssl ) ) != 0 ) 752 | { 753 | if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) 754 | { 755 | printf( " failed\n ! ssl_handshake returned -0x%x\n\n", -ret ); 756 | goto exit; 757 | } 758 | } 759 | } 760 | 761 | if( packet_in_num == 0 ) 762 | { 763 | printf( "--- client handshake step %zd ok\n", step ); 764 | } 765 | 766 | /* 767 | * Server: 768 | * Handshake step 769 | */ 770 | if( s_ssl.state == SSL_HANDSHAKE_OVER ) { 771 | printf("over\n"); 772 | no_steps = 0; 773 | } else { 774 | no_steps = server_steps[step - 1]; 775 | } 776 | 777 | for (i = 0; i < no_steps; i++) { 778 | if( ( ret = ssl_handshake_step( &s_ssl ) ) != 0 ) 779 | { 780 | if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) 781 | { 782 | printf( " failed\n ! ssl_handshake returned %d\n\n", ret ); 783 | goto exit; 784 | } 785 | } 786 | } 787 | 788 | if( packet_in_num == 0 ) 789 | { 790 | printf( "--- server handshake step %zd ok\n", step ); 791 | } 792 | 793 | step++; 794 | } while( ((c_ssl.state != SSL_HANDSHAKE_OVER) 795 | || (s_ssl.state != SSL_HANDSHAKE_OVER)) 796 | && (step <= MAX_HANDSHAKE_STEPS) ); 797 | 798 | if( packet_in_num == 0 ) 799 | { 800 | printf( "c_ssl.state: %d\n", c_ssl.state != SSL_HANDSHAKE_OVER ); 801 | printf( "s_ssl.state: %d\n", s_ssl.state != SSL_HANDSHAKE_OVER ); 802 | } 803 | 804 | /* 805 | * Client: 806 | * Verify the server certificate 807 | */ 808 | if( packet_in_num == 0 ) 809 | { 810 | printf( " . Verifying peer X.509 certificate..." ); 811 | } 812 | 813 | /* In real life, we probably want to bail out when ret != 0 */ 814 | if( ( flags = ssl_get_verify_result( &c_ssl ) ) != 0 ) 815 | { 816 | char vrfy_buf[512]; 817 | 818 | printf( " failed\n" ); 819 | 820 | x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), " ! ", flags ); 821 | 822 | printf( "%s\n", vrfy_buf ); 823 | } 824 | else if( packet_in_num == 0 ) 825 | { 826 | printf( " ok\n" ); 827 | } 828 | 829 | /* 830 | * Client: 831 | * Write the GET request 832 | */ 833 | if( packet_in_num == 0 ) 834 | { 835 | printf( " > Write to server:" ); 836 | fflush( stdout ); 837 | } 838 | 839 | len = snprintf( (char *) buf, sizeof( buf ), GET_REQUEST ); 840 | 841 | while( ( ret = ssl_write( &c_ssl, buf, len ) ) <= 0 ) 842 | { 843 | if( ret !=POLARSSL_ERR_NET_WANT_READ && ret !=POLARSSL_ERR_NET_WANT_WRITE ) 844 | { 845 | printf( " failed\n ! ssl_write returned %d\n\n", ret ); 846 | goto exit; 847 | } 848 | } 849 | 850 | len = ret; 851 | if( packet_in_num == 0 ) 852 | { 853 | printf( " %d bytes written\n\n%s", len, (char *) buf ); 854 | } 855 | 856 | /* 857 | * Server: 858 | * Read the HTTP Request 859 | */ 860 | if( packet_in_num == 0 ) 861 | { 862 | printf( " < Read from client:" ); 863 | fflush( stdout ); 864 | } 865 | 866 | do 867 | { 868 | len = sizeof( buf ) - 1; 869 | memset( buf, 0, sizeof( buf ) ); 870 | ret = ssl_read( &s_ssl, buf, len ); 871 | 872 | if( ret ==POLARSSL_ERR_NET_WANT_READ || ret ==POLARSSL_ERR_NET_WANT_WRITE ) 873 | continue; 874 | 875 | if( ret <= 0 ) 876 | { 877 | switch( ret ) 878 | { 879 | case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY: 880 | printf( " connection was closed gracefully\n" ); 881 | break; 882 | 883 | case POLARSSL_ERR_NET_CONN_RESET: 884 | printf( " connection was reset by peer\n" ); 885 | break; 886 | 887 | default: 888 | printf( " ssl_read returned -0x%x\n", -ret ); 889 | break; 890 | } 891 | 892 | break; 893 | } 894 | 895 | len = ret; 896 | if( packet_in_num == 0 ) 897 | { 898 | printf( " %d bytes read\n\n%s", len, (char *) buf ); 899 | } 900 | 901 | if( ret > 0 ) 902 | break; 903 | } 904 | while( 1 ); 905 | 906 | /* 907 | * Server: 908 | * Write the 200 Response 909 | */ 910 | if( packet_in_num == 0 ) 911 | { 912 | printf( " > Write to client:" ); 913 | fflush( stdout ); 914 | } 915 | 916 | len = snprintf( (char *) buf, sizeof( buf ), HTTP_RESPONSE ); 917 | 918 | while( ( ret = ssl_write( &s_ssl, buf, len ) ) <= 0 ) 919 | { 920 | if( ret == POLARSSL_ERR_NET_CONN_RESET ) 921 | { 922 | printf( " failed\n ! peer closed the connection\n\n" ); 923 | goto exit; 924 | } 925 | 926 | if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) 927 | { 928 | printf( " failed\n ! ssl_write returned %d\n\n", ret ); 929 | goto exit; 930 | } 931 | } 932 | 933 | len = ret; 934 | if( packet_in_num == 0 ) 935 | { 936 | printf( " %d bytes written\n\n%s\n", len, (char *) buf ); 937 | } 938 | 939 | /* 940 | * Client: 941 | * Read the HTTP response 942 | */ 943 | if( packet_in_num == 0 ) 944 | { 945 | printf( " < Read from server:" ); 946 | fflush( stdout ); 947 | } 948 | 949 | do 950 | { 951 | len = sizeof( buf ) - 1; 952 | memset( buf, 0, sizeof( buf ) ); 953 | ret = ssl_read( &c_ssl, buf, len ); 954 | 955 | if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE ) 956 | continue; 957 | 958 | if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY ) 959 | { 960 | ret = 0; 961 | break; 962 | } 963 | 964 | if( ret < 0 ) 965 | { 966 | printf( "failed\n ! ssl_read returned %d\n\n", ret ); 967 | break; 968 | } 969 | 970 | if( ret == 0 ) 971 | { 972 | printf( "\n\nEOF\n\n" ); 973 | break; 974 | } 975 | 976 | len = ret; 977 | if( packet_in_num == 0 ) 978 | { 979 | printf( " %d bytes read\n\n%s", len, (char *) buf ); 980 | } 981 | 982 | /* 983 | * Server: 984 | * Client read response. Close connection. 985 | */ 986 | if ( packet_in_num == 0 ) 987 | { 988 | printf( " . Closing the connection..." ); 989 | fflush( stdout ); 990 | } 991 | 992 | while( ( ret = ssl_close_notify( &s_ssl ) ) < 0 ) 993 | { 994 | if( ret != POLARSSL_ERR_NET_WANT_READ && 995 | ret != POLARSSL_ERR_NET_WANT_WRITE ) 996 | { 997 | printf( " failed\n ! ssl_close_notify returned %d\n\n", ret ); 998 | goto exit; 999 | } 1000 | } 1001 | 1002 | if( packet_in_num == 0 ) 1003 | { 1004 | printf( " ok\n" ); 1005 | } 1006 | } 1007 | while( 1 ); 1008 | 1009 | /* 1010 | * Client: 1011 | * Close connection. 1012 | */ 1013 | if( packet_in_num == 0 ) 1014 | { 1015 | printf( " . Closing the connection..." ); 1016 | fflush( stdout ); 1017 | } 1018 | 1019 | ssl_close_notify( &c_ssl ); 1020 | 1021 | if( packet_in_num == 0 ) 1022 | { 1023 | printf( " ok\n" ); 1024 | } 1025 | 1026 | /* 1027 | * Server: 1028 | * We do not have multiple clients and therefore do not goto reset. 1029 | */ 1030 | /*ret = 0;*/ 1031 | /*goto reset;*/ 1032 | 1033 | exit: 1034 | 1035 | #ifdef POLARSSL_ERROR_C 1036 | if( ret != 0 ) 1037 | { 1038 | char error_buf[100]; 1039 | polarssl_strerror( ret, error_buf, 100 ); 1040 | printf("Last error was: %d - %s\n\n", ret, error_buf ); 1041 | } 1042 | #endif 1043 | 1044 | #if SOCKET_COMMUNICATION 1045 | if ( client_fd != 1 ) 1046 | net_close( client_fd ); 1047 | if( server_fd != -1 ) 1048 | net_close( server_fd ); 1049 | if ( listen_fd != 1 ) 1050 | net_close( listen_fd ); 1051 | #endif 1052 | 1053 | x509_crt_free( &srvcert ); 1054 | pk_free( &pkey ); 1055 | ssl_free( &s_ssl ); 1056 | ssl_free( &c_ssl ); 1057 | #if defined(POLARSSL_SSL_CACHE_C) 1058 | ssl_cache_free( &cache ); 1059 | #endif 1060 | 1061 | #if defined(_WIN32) 1062 | printf( " Press Enter to exit this program.\n" ); 1063 | fflush( stdout ); getchar(); 1064 | #endif 1065 | 1066 | return( ret ); 1067 | } 1068 | #endif /* POLARSSL_BIGNUM_C && POLARSSL_CERTS_C && POLARSSL_ENTROPY_C && 1069 | POLARSSL_SSL_TLS_C && POLARSSL_SSL_SRV_C && POLARSSL_NET_C && 1070 | POLARSSL_RSA_C && POLARSSL_CTR_DRBG_C && POLARSSL_X509_CRT_PARSE_C 1071 | && POLARSSL_FS_IO && POLARSSL_PEM_PARSE_C */ 1072 | -------------------------------------------------------------------------------- /selftls-2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Sets up a TLS server and a TLS client instance and lets the instances 3 | * talk to each other. 4 | * The purpose of this program is to allow for fuzzing the mbed TLS 5 | * library using afl. 6 | * 7 | * Copyright (C) 2015, Fabian Foerg, Gotham Digital Science, All Rights Reserved 8 | * 9 | * Based on code by: 10 | * 11 | * Copyright (C) 2006-2013, ARM Limited, All Rights Reserved 12 | * 13 | * This file is part of mbed TLS (https://tls.mbed.org) 14 | * 15 | * This program is free software; you can redistribute it and/or modify 16 | * it under the terms of the GNU General Public License as published by 17 | * the Free Software Foundation; either version 2 of the License, or 18 | * (at your option) any later version. 19 | * 20 | * This program is distributed in the hope that it will be useful, 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | * GNU General Public License for more details. 24 | * 25 | * You should have received a copy of the GNU General Public License along 26 | * with this program; if not, write to the Free Software Foundation, Inc., 27 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 28 | */ 29 | 30 | #if !defined(MBEDTLS_CONFIG_FILE) 31 | #include "mbedtls/config.h" 32 | #else 33 | #include MBEDTLS_CONFIG_FILE 34 | #endif 35 | 36 | #if defined(MBEDTLS_PLATFORM_C) 37 | #include "mbedtls/platform.h" 38 | #else 39 | #includeSuccessful connection!\r\n" 187 | 188 | #define MAX_HANDSHAKE_STEPS (sizeof(client_steps)/sizeof(client_steps[0])) 189 | 190 | /* Store sent messages in files for fuzzing. */ 191 | #if !defined(PACKET_FILE_PREFIX) 192 | #define PACKET_FILE_PREFIX "./packet-" 193 | #endif 194 | static size_t packet_count = 1; 195 | static size_t packet_in_num = 0; 196 | static const char *packet_in_file = NULL; 197 | 198 | #if !SOCKET_COMMUNICATION 199 | #define BUF_SIZE (4096) 200 | 201 | static unsigned char server_send_buf[BUF_SIZE]; 202 | static size_t server_send_off = 0; 203 | static size_t server_recv_off = 0; 204 | 205 | static unsigned char client_send_buf[BUF_SIZE]; 206 | static size_t client_send_off = 0; 207 | static size_t client_recv_off = 0; 208 | 209 | static unsigned char *shared_buf = NULL; 210 | static size_t *send_off = NULL; 211 | static size_t *recv_off = NULL; 212 | #endif 213 | 214 | #define DEBUG_LEVEL 0 215 | 216 | static void my_debug( void *ctx, int level, 217 | const char *file, int line, 218 | const char *str ) 219 | { 220 | ((void) level); 221 | 222 | mbedtls_fprintf( (FILE *) ctx, "%s:%04d: %s", file, line, str ); 223 | fflush( (FILE *) ctx ); 224 | } 225 | 226 | /* 227 | * Write at most 'len' characters to shared buffer or file. 228 | * Multiple sends can occur before a receive; therefore, maintain an 229 | * offset. 230 | * Also, write content of file to shared buffer, if desired (determined 231 | * by command-line options). 232 | */ 233 | static int mbedtls_send_custom( void *ctx, const unsigned char *buf, 234 | size_t len ) 235 | { 236 | int ret; 237 | #if SOCKET_COMMUNICATION 238 | int fd = ((mbedtls_net_context *) ctx)->fd; 239 | 240 | if( fd < 0 ) 241 | return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); 242 | #else 243 | ((void) ctx); 244 | #endif 245 | 246 | /* Read packet from file or write packet to file */ 247 | if( packet_count == packet_in_num ) 248 | { 249 | FILE *in_file; 250 | #if !SOCKET_COMMUNICATION 251 | size_t rlen; 252 | #endif 253 | 254 | if( !packet_in_file ) 255 | { 256 | mbedtls_fprintf( stderr, "Packet input file not specified!\n" ); 257 | exit(1); 258 | } 259 | 260 | /* Read packet from file, ignoring buf */ 261 | in_file = fopen( packet_in_file, "rb" ); 262 | 263 | if( !in_file ) 264 | { 265 | perror( "Unable to open packet input file" ); 266 | exit( 1 ); 267 | } 268 | 269 | /* Write packet to socket/buffer. */ 270 | #if SOCKET_COMMUNICATION 271 | ret = (int) write( fd, buf, len ); 272 | #else 273 | rlen = fread( shared_buf, sizeof(shared_buf[0]), BUF_SIZE, 274 | in_file ); 275 | #endif 276 | if ( ferror( in_file ) ) 277 | { 278 | perror( "Unable to read packet input file" ); 279 | exit( 1 ); 280 | } 281 | #if !SOCKET_COMMUNICATION 282 | else { 283 | *send_off += rlen; 284 | ret = rlen; 285 | } 286 | #endif 287 | fclose( in_file ); 288 | } 289 | else 290 | { 291 | /* Write packet to socket/buffer. */ 292 | #if SOCKET_COMMUNICATION 293 | ret = (int) write( fd, buf, len ); 294 | #else 295 | if ( (len <= BUF_SIZE) && memcpy( shared_buf, buf, len ) ) 296 | { 297 | *send_off += len; 298 | ret = len; 299 | } 300 | else 301 | { 302 | ret = -1; 303 | } 304 | #endif 305 | 306 | if( packet_in_num == 0 ) 307 | { 308 | char out_filename[100]; 309 | FILE *out_file; 310 | 311 | /* Write packet to file. */ 312 | snprintf( out_filename, sizeof(out_filename), "%s%zd", 313 | PACKET_FILE_PREFIX, packet_count ); 314 | out_file = fopen( out_filename, "wb" ); 315 | fwrite( buf, sizeof(char), len, out_file ); 316 | fclose( out_file ); 317 | } 318 | } 319 | packet_count++; 320 | 321 | #if SOCKET_COMMUNICATION 322 | if( ret < 0 ) 323 | { 324 | if( net_would_block( ctx ) != 0 ) 325 | return( MBEDTLS_ERR_SSL_WANT_WRITE ); 326 | 327 | #if( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ 328 | !defined(EFI32) 329 | if( WSAGetLastError() == WSAECONNRESET ) 330 | return( MBEDTLS_ERR_NET_CONN_RESET ); 331 | #else 332 | if( errno == EPIPE || errno == ECONNRESET ) 333 | return( MBEDTLS_ERR_NET_CONN_RESET ); 334 | 335 | if( errno == EINTR ) 336 | return( MBEDTLS_ERR_SSL_WANT_WRITE ); 337 | #endif 338 | 339 | return( MBEDTLS_ERR_NET_SEND_FAILED ); 340 | } 341 | #endif 342 | 343 | return( ret ); 344 | } 345 | 346 | /* 347 | * Read at most 'len' characters and write to buf. 348 | */ 349 | static int mbedtls_recv_custom( void *ctx, unsigned char *buf, size_t len ) 350 | { 351 | int ret; 352 | #if SOCKET_COMMUNICATION 353 | int fd = ((mbedtls_net_context *) ctx)->fd; 354 | 355 | if( fd < 0 ) 356 | return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); 357 | ret = (int) read( fd, buf, len ); 358 | #else 359 | ((void) ctx); 360 | ((void) len); 361 | 362 | if ( ((*recv_off + len) <= BUF_SIZE) && memcpy( buf, &shared_buf[*recv_off], len ) ) 363 | { 364 | *recv_off += len; 365 | if (*recv_off == *send_off) 366 | { 367 | /* 368 | * Done copying buffer. 369 | * Reset offsets for next calls of send and rcv functions. 370 | */ 371 | *recv_off = 0; 372 | *send_off = 0; 373 | } 374 | /* Imitate the return value of read(2). */ 375 | ret = len; 376 | } 377 | else 378 | { 379 | ret = -1; 380 | } 381 | #endif 382 | 383 | #if SOCKET_COMMUNICATION 384 | if( ret < 0 ) 385 | { 386 | if( net_would_block( ctx ) != 0 ) 387 | return( MBEDTLS_ERR_SSL_WANT_READ ); 388 | 389 | #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ 390 | !defined(EFI32) 391 | if( WSAGetLastError() == WSAECONNRESET ) 392 | return( MBEDTLS_ERR_NET_CONN_RESET ); 393 | #else 394 | if( errno == EPIPE || errno == ECONNRESET ) 395 | return( MBEDTLS_ERR_NET_CONN_RESET ); 396 | 397 | if( errno == EINTR ) 398 | return( MBEDTLS_ERR_SSL_WANT_READ ); 399 | #endif 400 | 401 | return( MBEDTLS_ERR_NET_RECV_FAILED ); 402 | } 403 | #endif 404 | 405 | return( ret ); 406 | } 407 | 408 | /* 409 | * Make the program deterministic for fuzzing: always generate 1 bytes 410 | * instead of random numbers. 411 | */ 412 | static int mbedtls_ctr_drbg_deterministic( void *p_rng, unsigned char *output, size_t output_len ) 413 | { 414 | ((void) p_rng); 415 | 416 | /* Note that key generation would fail with 0 bytes. */ 417 | memset( output, 1, output_len ); 418 | 419 | return 0; 420 | } 421 | 422 | #if !SOCKET_COMMUNICATION 423 | static int mbedtls_server_send_buf( void *ctx, const unsigned char *buf, 424 | size_t len ) 425 | { 426 | shared_buf = server_send_buf; 427 | send_off = &server_send_off; 428 | 429 | return mbedtls_send_custom(ctx, buf, len); 430 | } 431 | 432 | static int mbedtls_client_send_buf( void *ctx, const unsigned char *buf, 433 | size_t len ) 434 | { 435 | shared_buf = client_send_buf; 436 | send_off = &client_send_off; 437 | 438 | return mbedtls_send_custom(ctx, buf, len); 439 | } 440 | 441 | static int mbedtls_server_recv_buf( void *ctx, unsigned char *buf, 442 | size_t len ) 443 | { 444 | shared_buf = client_send_buf; 445 | send_off = &client_send_off; 446 | recv_off = &server_recv_off; 447 | 448 | return mbedtls_recv_custom(ctx, buf, len); 449 | } 450 | 451 | static int mbedtls_client_recv_buf( void *ctx, unsigned char *buf, 452 | size_t len ) 453 | { 454 | shared_buf = server_send_buf; 455 | send_off = &server_send_off; 456 | recv_off = &client_recv_off; 457 | 458 | return mbedtls_recv_custom(ctx, buf, len); 459 | } 460 | #endif 461 | 462 | static void usage( const char *prog ) 463 | { 464 | fprintf( stderr, "Usage: %s [packet number] [packet file]\n", prog ); 465 | } 466 | 467 | int main( int argc, const char *argv[] ) 468 | { 469 | /* Client and server declarations. */ 470 | int ret; 471 | int len; 472 | #if SOCKET_COMMUNICATION 473 | mbedtls_net_context listen_fd, client_fd, server_fd; 474 | #endif 475 | unsigned char buf[1024]; 476 | /* Handshake step counter */ 477 | size_t step = 1; 478 | int flags; 479 | /* 480 | * The following number of steps are hardcoded to ensure 481 | * that the client and server complete the handshake without 482 | * waiting infinitely for the other side to send data. 483 | * 484 | * 1 2 3 4 5 6 7 8 9 10 485 | */ 486 | int client_steps[] = { 2, 1, 1, 1, 4, 2, 1, 1, 2, 1 }; 487 | int server_steps[] = { 3, 1, 1, 2, 3, 1, 2, 1, 1, 1 }; 488 | 489 | mbedtls_ssl_context s_ssl, c_ssl; 490 | mbedtls_ssl_config s_conf, c_conf; 491 | mbedtls_x509_crt srvcert; 492 | mbedtls_pk_context pkey; 493 | #if defined(MBEDTLS_SSL_CACHE_C) 494 | mbedtls_ssl_cache_context cache; 495 | #endif 496 | 497 | if( argc == 3) 498 | { 499 | packet_in_num = atoi(argv[1]); 500 | packet_in_file = argv[2]; 501 | } 502 | else if( argc != 1) 503 | { 504 | usage(argv[0]); 505 | exit(1); 506 | } 507 | 508 | /* Server init */ 509 | #if SOCKET_COMMUNICATION 510 | mbedtls_net_init( &listen_fd ); 511 | mbedtls_net_init( &client_fd ); 512 | #endif 513 | mbedtls_ssl_init( &s_ssl ); 514 | mbedtls_ssl_config_init( &s_conf ); 515 | #if defined(MBEDTLS_SSL_CACHE_C) 516 | mbedtls_ssl_cache_init( &cache ); 517 | #endif 518 | mbedtls_x509_crt_init( &srvcert ); 519 | mbedtls_pk_init( &pkey ); 520 | 521 | /* Client init */ 522 | #if SOCKET_COMMUNICATION 523 | mbedtls_net_init( &server_fd ); 524 | #endif 525 | mbedtls_ssl_init( &c_ssl ); 526 | mbedtls_ssl_config_init( &c_conf ); 527 | /*mbedtls_x509_crt_init( &cacert );*/ 528 | 529 | #if defined(MBEDTLS_DEBUG_C) 530 | mbedtls_debug_set_threshold( DEBUG_LEVEL ); 531 | #endif 532 | 533 | /* 534 | * Server: 535 | * Load the certificates and private RSA key 536 | */ 537 | if( packet_in_num == 0 ) 538 | { 539 | mbedtls_printf( " . Loading the server cert. and key..." ); 540 | fflush( stdout ); 541 | } 542 | 543 | /* 544 | * This demonstration program uses embedded test certificates. 545 | * Instead, you may want to use mbedtls_x509_crt_parse_file() to read the 546 | * server and CA certificates, as well as mbedtls_pk_parse_keyfile(). 547 | */ 548 | ret = mbedtls_x509_crt_parse( &srvcert, (const unsigned char *) mbedtls_test_srv_crt, 549 | mbedtls_test_srv_crt_len ); 550 | if( ret != 0 ) 551 | { 552 | mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret ); 553 | goto exit; 554 | } 555 | 556 | ret = mbedtls_x509_crt_parse( &srvcert, (const unsigned char *) mbedtls_test_cas_pem, 557 | mbedtls_test_cas_pem_len ); 558 | if( ret != 0 ) 559 | { 560 | mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret ); 561 | goto exit; 562 | } 563 | 564 | ret = mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_srv_key, 565 | mbedtls_test_srv_key_len, NULL, 0 ); 566 | if( ret != 0 ) 567 | { 568 | mbedtls_printf( " failed\n ! mbedtls_pk_parse_key returned %d\n\n", ret ); 569 | goto exit; 570 | } 571 | 572 | if( packet_in_num == 0 ) 573 | { 574 | mbedtls_printf( " ok\n" ); 575 | } 576 | 577 | /* 578 | * Server: 579 | * Setup stuff 580 | */ 581 | if( packet_in_num == 0 ) 582 | { 583 | mbedtls_printf( " . Server: Setting up the SSL data...." ); 584 | fflush( stdout ); 585 | } 586 | 587 | if( ( ret = mbedtls_ssl_config_defaults( &s_conf, 588 | MBEDTLS_SSL_IS_SERVER, 589 | MBEDTLS_SSL_TRANSPORT_STREAM, 590 | MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) 591 | { 592 | mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); 593 | goto exit; 594 | } 595 | 596 | mbedtls_ssl_conf_rng( &s_conf, mbedtls_ctr_drbg_deterministic, NULL ); 597 | mbedtls_ssl_conf_dbg( &s_conf, my_debug, stdout ); 598 | 599 | #if defined(MBEDTLS_SSL_CACHE_C) 600 | mbedtls_ssl_conf_session_cache( &s_conf, &cache, 601 | mbedtls_ssl_cache_get, 602 | mbedtls_ssl_cache_set ); 603 | #endif 604 | 605 | mbedtls_ssl_conf_ca_chain( &s_conf, srvcert.next, NULL ); 606 | if( ( ret = mbedtls_ssl_conf_own_cert( &s_conf, &srvcert, &pkey ) ) != 0 ) 607 | { 608 | mbedtls_printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret ); 609 | goto exit; 610 | } 611 | 612 | if( ( ret = mbedtls_ssl_setup( &s_ssl, &s_conf ) ) != 0 ) 613 | { 614 | mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret ); 615 | goto exit; 616 | } 617 | 618 | if( packet_in_num == 0 ) 619 | { 620 | mbedtls_printf( " ok\n" ); 621 | } 622 | 623 | mbedtls_ssl_session_reset( &s_ssl ); 624 | 625 | #if SOCKET_COMMUNICATION 626 | /* 627 | * Server: 628 | * Setup the listening TCP socket 629 | */ 630 | if( packet_in_num == 0 ) 631 | { 632 | mbedtls_printf( " . Bind on https://localhost:%s/ ...", SERVER_PORT ); 633 | fflush( stdout ); 634 | } 635 | 636 | if( ( ret = mbedtls_net_bind( &listen_fd, NULL, SERVER_PORT, MBEDTLS_NET_PROTO_TCP ) ) != 0 ) 637 | { 638 | mbedtls_printf( " failed\n ! mbedtls_net_bind returned %d\n\n", ret ); 639 | goto exit; 640 | } 641 | 642 | if( packet_in_num == 0 ) 643 | { 644 | mbedtls_printf( " ok\n" ); 645 | } 646 | 647 | /* 648 | * Client: 649 | * Start the connection 650 | */ 651 | if( packet_in_num == 0 ) 652 | { 653 | mbedtls_printf( " . Connecting to tcp/%s/%s...", SERVER_NAME, SERVER_PORT ); 654 | fflush( stdout ); 655 | } 656 | 657 | if( ( ret = mbedtls_net_connect( &server_fd, SERVER_NAME, 658 | SERVER_PORT, MBEDTLS_NET_PROTO_TCP ) ) != 0 ) 659 | { 660 | mbedtls_printf( " failed\n ! mbedtls_net_connect returned %d\n\n", ret ); 661 | goto exit; 662 | } 663 | 664 | if( packet_in_num == 0 ) 665 | { 666 | mbedtls_printf( " ok\n" ); 667 | } 668 | 669 | /* 670 | * Server: 671 | * Start listening for client connections 672 | */ 673 | if( packet_in_num == 0 ) 674 | { 675 | mbedtls_printf( " . Waiting for a remote connection ..." ); 676 | fflush( stdout ); 677 | } 678 | 679 | /* 680 | * Server: 681 | * Accept client connection (socket is set non-blocking in 682 | * library/net.c) 683 | */ 684 | if( ( ret = mbedtls_net_accept( &listen_fd, &client_fd, 685 | NULL, 0, NULL ) ) != 0 ) 686 | { 687 | mbedtls_printf( " failed\n ! mbedtls_net_accept returned %d\n\n", ret ); 688 | goto exit; 689 | } 690 | 691 | if( packet_in_num == 0 ) 692 | { 693 | mbedtls_printf( " ok\n" ); 694 | } 695 | 696 | mbedtls_ssl_set_bio( &s_ssl, &client_fd, mbedtls_send_custom, mbedtls_recv_custom, NULL ); 697 | #else 698 | mbedtls_ssl_set_bio( &s_ssl, NULL, mbedtls_server_send_buf, mbedtls_server_recv_buf, NULL ); 699 | #endif 700 | 701 | /* 702 | * Client: 703 | * Setup stuff 704 | */ 705 | if( packet_in_num == 0 ) 706 | { 707 | mbedtls_printf( " . Client: Setting up the SSL/TLS structure..." ); 708 | fflush( stdout ); 709 | } 710 | 711 | if( ( ret = mbedtls_ssl_config_defaults( &c_conf, 712 | MBEDTLS_SSL_IS_CLIENT, 713 | MBEDTLS_SSL_TRANSPORT_STREAM, 714 | MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) 715 | { 716 | mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); 717 | goto exit; 718 | } 719 | 720 | if( packet_in_num == 0 ) 721 | { 722 | mbedtls_printf( " ok\n" ); 723 | } 724 | 725 | /* OPTIONAL is not optimal for security, 726 | * but makes interop easier in this simplified example */ 727 | mbedtls_ssl_conf_authmode( &c_conf, MBEDTLS_SSL_VERIFY_OPTIONAL ); 728 | /* NONE permits man-in-the-middle attacks. */ 729 | /*mbedtls_ssl_conf_authmode( &c_conf, MBEDTLS_SSL_VERIFY_NONE );*/ 730 | /*mbedtls_ssl_conf_authmode( &c_conf, MBEDTLS_SSL_VERIFY_REQUIRED );*/ 731 | mbedtls_ssl_conf_ca_chain( &c_conf, &srvcert, NULL ); 732 | mbedtls_ssl_conf_rng( &c_conf, mbedtls_ctr_drbg_deterministic, NULL ); 733 | mbedtls_ssl_conf_dbg( &c_conf, my_debug, stdout ); 734 | 735 | if( ( ret = mbedtls_ssl_setup( &c_ssl, &c_conf ) ) != 0 ) 736 | { 737 | mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret ); 738 | goto exit; 739 | } 740 | 741 | if( ( ret = mbedtls_ssl_set_hostname( &c_ssl, "mbed TLS Server 1" ) ) != 0 ) 742 | { 743 | mbedtls_printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret ); 744 | goto exit; 745 | } 746 | 747 | #if SOCKET_COMMUNICATION 748 | mbedtls_ssl_set_bio( &c_ssl, &server_fd, mbedtls_send_custom, mbedtls_recv_custom, NULL ); 749 | #else 750 | mbedtls_ssl_set_bio( &c_ssl, NULL, mbedtls_client_send_buf, mbedtls_client_recv_buf, NULL ); 751 | #endif 752 | 753 | if( packet_in_num == 0 ) 754 | { 755 | mbedtls_printf( " . Performing the SSL/TLS handshake...\n" ); 756 | fflush( stdout ); 757 | } 758 | 759 | do { 760 | /* 761 | * Client: 762 | * Handshake step 763 | */ 764 | int i; 765 | int no_steps; 766 | 767 | if( c_ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER) { 768 | no_steps = 0; 769 | } else { 770 | no_steps = client_steps[step - 1]; 771 | } 772 | 773 | for (i = 0; i < no_steps; i++) { 774 | if( ( ret = mbedtls_ssl_handshake_step( &c_ssl ) ) != 0 ) 775 | { 776 | if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) 777 | { 778 | mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret ); 779 | goto exit; 780 | } 781 | } 782 | } 783 | 784 | if( packet_in_num == 0 ) 785 | { 786 | mbedtls_printf( "--- client handshake step %zd ok\n", step ); 787 | } 788 | 789 | /* 790 | * Server: 791 | * Handshake step 792 | */ 793 | if( s_ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER) { 794 | no_steps = 0; 795 | } else { 796 | no_steps = server_steps[step - 1]; 797 | } 798 | 799 | for (i = 0; i < no_steps; i++) { 800 | if( ( ret = mbedtls_ssl_handshake_step( &s_ssl ) ) != 0 ) 801 | { 802 | if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) 803 | { 804 | mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned %d\n\n", ret ); 805 | goto exit; 806 | } 807 | } 808 | } 809 | 810 | if( packet_in_num == 0 ) 811 | { 812 | mbedtls_printf( "--- server handshake step %zd ok\n", step ); 813 | } 814 | 815 | step++; 816 | } while( ((c_ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER) 817 | || (s_ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER)) 818 | && (step <= MAX_HANDSHAKE_STEPS) ); 819 | 820 | if( packet_in_num == 0 ) 821 | { 822 | mbedtls_printf( "c_ssl.state: %d\n", c_ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER ); 823 | mbedtls_printf( "s_ssl.state: %d\n", s_ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER ); 824 | } 825 | 826 | /* 827 | * Client: 828 | * Verify the server certificate 829 | */ 830 | if( packet_in_num == 0 ) 831 | { 832 | mbedtls_printf( " . Verifying peer X.509 certificate..." ); 833 | } 834 | 835 | /* In real life, we probably want to bail out when ret != 0 */ 836 | if( ( flags = mbedtls_ssl_get_verify_result( &c_ssl ) ) != 0 ) 837 | { 838 | char vrfy_buf[512]; 839 | 840 | mbedtls_printf( " failed\n" ); 841 | 842 | mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), " ! ", flags ); 843 | 844 | mbedtls_printf( "%s\n", vrfy_buf ); 845 | } 846 | else if( packet_in_num == 0 ) 847 | { 848 | mbedtls_printf( " ok\n" ); 849 | } 850 | 851 | /* 852 | * Client: 853 | * Write the GET request 854 | */ 855 | if( packet_in_num == 0 ) 856 | { 857 | mbedtls_printf( " > Write to server:" ); 858 | fflush( stdout ); 859 | } 860 | 861 | len = snprintf( (char *) buf, sizeof( buf ), GET_REQUEST ); 862 | 863 | while( ( ret = mbedtls_ssl_write( &c_ssl, buf, len ) ) <= 0 ) 864 | { 865 | if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) 866 | { 867 | mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret ); 868 | goto exit; 869 | } 870 | } 871 | 872 | len = ret; 873 | if( packet_in_num == 0 ) 874 | { 875 | mbedtls_printf( " %d bytes written\n\n%s", len, (char *) buf ); 876 | } 877 | 878 | /* 879 | * Server: 880 | * Read the HTTP Request 881 | */ 882 | if( packet_in_num == 0 ) 883 | { 884 | mbedtls_printf( " < Read from client:" ); 885 | fflush( stdout ); 886 | } 887 | 888 | do 889 | { 890 | len = sizeof( buf ) - 1; 891 | memset( buf, 0, sizeof( buf ) ); 892 | ret = mbedtls_ssl_read( &s_ssl, buf, len ); 893 | 894 | if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE ) 895 | continue; 896 | 897 | if( ret <= 0 ) 898 | { 899 | switch( ret ) 900 | { 901 | case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: 902 | mbedtls_printf( " connection was closed gracefully\n" ); 903 | break; 904 | 905 | case MBEDTLS_ERR_NET_CONN_RESET: 906 | mbedtls_printf( " connection was reset by peer\n" ); 907 | break; 908 | 909 | default: 910 | mbedtls_printf( " mbedtls_ssl_read returned -0x%x\n", -ret ); 911 | break; 912 | } 913 | 914 | break; 915 | } 916 | 917 | len = ret; 918 | if( packet_in_num == 0 ) 919 | { 920 | mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf ); 921 | } 922 | 923 | if( ret > 0 ) 924 | break; 925 | } 926 | while( 1 ); 927 | 928 | /* 929 | * Server: 930 | * Write the 200 Response 931 | */ 932 | if( packet_in_num == 0 ) 933 | { 934 | mbedtls_printf( " > Write to client:" ); 935 | fflush( stdout ); 936 | } 937 | 938 | len = snprintf( (char *) buf, sizeof( buf ), HTTP_RESPONSE ); 939 | 940 | while( ( ret = mbedtls_ssl_write( &s_ssl, buf, len ) ) <= 0 ) 941 | { 942 | if( ret == MBEDTLS_ERR_NET_CONN_RESET ) 943 | { 944 | mbedtls_printf( " failed\n ! peer closed the connection\n\n" ); 945 | goto exit; 946 | } 947 | 948 | if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) 949 | { 950 | mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret ); 951 | goto exit; 952 | } 953 | } 954 | 955 | len = ret; 956 | if( packet_in_num == 0 ) 957 | { 958 | mbedtls_printf( " %d bytes written\n\n%s\n", len, (char *) buf ); 959 | } 960 | 961 | /* 962 | * Client: 963 | * Read the HTTP response 964 | */ 965 | if( packet_in_num == 0 ) 966 | { 967 | mbedtls_printf( " < Read from server:" ); 968 | fflush( stdout ); 969 | } 970 | 971 | do 972 | { 973 | len = sizeof( buf ) - 1; 974 | memset( buf, 0, sizeof( buf ) ); 975 | ret = mbedtls_ssl_read( &c_ssl, buf, len ); 976 | 977 | if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE ) 978 | continue; 979 | 980 | if( ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ) 981 | { 982 | ret = 0; 983 | break; 984 | } 985 | 986 | if( ret < 0 ) 987 | { 988 | mbedtls_printf( "failed\n ! mbedtls_ssl_read returned %d\n\n", ret ); 989 | break; 990 | } 991 | 992 | if( ret == 0 ) 993 | { 994 | mbedtls_printf( "\n\nEOF\n\n" ); 995 | break; 996 | } 997 | 998 | len = ret; 999 | if( packet_in_num == 0 ) 1000 | { 1001 | mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf ); 1002 | } 1003 | 1004 | /* 1005 | * Server: 1006 | * Client read response. Close connection. 1007 | */ 1008 | if ( packet_in_num == 0 ) 1009 | { 1010 | mbedtls_printf( " . Closing the connection..." ); 1011 | fflush( stdout ); 1012 | } 1013 | 1014 | while( ( ret = mbedtls_ssl_close_notify( &s_ssl ) ) < 0 ) 1015 | { 1016 | if( ret != MBEDTLS_ERR_SSL_WANT_READ && 1017 | ret != MBEDTLS_ERR_SSL_WANT_WRITE ) 1018 | { 1019 | mbedtls_printf( " failed\n ! mbedtls_ssl_close_notify returned %d\n\n", ret ); 1020 | goto exit; 1021 | } 1022 | } 1023 | 1024 | if( packet_in_num == 0 ) 1025 | { 1026 | mbedtls_printf( " ok\n" ); 1027 | } 1028 | } 1029 | while( 1 ); 1030 | 1031 | /* 1032 | * Client: 1033 | * Close connection. 1034 | */ 1035 | if( packet_in_num == 0 ) 1036 | { 1037 | mbedtls_printf( " . Closing the connection..." ); 1038 | fflush( stdout ); 1039 | } 1040 | 1041 | mbedtls_ssl_close_notify( &c_ssl ); 1042 | 1043 | if( packet_in_num == 0 ) 1044 | { 1045 | mbedtls_printf( " ok\n" ); 1046 | } 1047 | 1048 | /* 1049 | * Server: 1050 | * We do not have multiple clients and therefore do not goto reset. 1051 | */ 1052 | /*ret = 0;*/ 1053 | /*goto reset;*/ 1054 | 1055 | exit: 1056 | 1057 | #ifdef MBEDTLS_ERROR_C 1058 | if( ret != 0 ) 1059 | { 1060 | char error_buf[100]; 1061 | mbedtls_strerror( ret, error_buf, 100 ); 1062 | mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf ); 1063 | } 1064 | #endif 1065 | 1066 | #if SOCKET_COMMUNICATION 1067 | mbedtls_net_free( &client_fd ); 1068 | mbedtls_net_free( &listen_fd ); 1069 | mbedtls_net_free( &server_fd ); 1070 | #endif 1071 | 1072 | mbedtls_x509_crt_free( &srvcert ); 1073 | mbedtls_pk_free( &pkey ); 1074 | mbedtls_ssl_free( &s_ssl ); 1075 | mbedtls_ssl_free( &c_ssl ); 1076 | mbedtls_ssl_config_free( &s_conf ); 1077 | mbedtls_ssl_config_free( &c_conf ); 1078 | #if defined(MBEDTLS_SSL_CACHE_C) 1079 | mbedtls_ssl_cache_free( &cache ); 1080 | #endif 1081 | 1082 | #if defined(_WIN32) 1083 | mbedtls_printf( " Press Enter to exit this program.\n" ); 1084 | fflush( stdout ); getchar(); 1085 | #endif 1086 | 1087 | return( ret ); 1088 | } 1089 | #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_CERTS_C && MBEDTLS_ENTROPY_C && 1090 | MBEDTLS_SSL_TLS_C && MBEDTLS_SSL_SRV_C && MBEDTLS_NET_C && 1091 | MBEDTLS_RSA_C && MBEDTLS_CTR_DRBG_C && MBEDTLS_X509_CRT_PARSE_C 1092 | && MBEDTLS_FS_IO && MBEDTLS_PEM_PARSE_C */ 1093 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | readonly ARCHIVE_SUFFIX='-gpl.tgz' 4 | readonly MBEDTLS_2_3='mbedtls-2.3.0' 5 | readonly SHA_256_2_3='21237014f779bde70b2d71399cc1ea53365eb7f10cdd74a13ee6329a1910cb49' 6 | readonly MBEDTLS_2_1='mbedtls-2.1.5' 7 | readonly SHA_256_2_1='119ff3ee2788a2c5f0604b247bdffd401c439c8e551561cbb4b1f9d3a21a120d' 8 | readonly MBEDTLS_1_3='mbedtls-1.3.17' 9 | readonly SHA_256_1_3='f5beb43e850283915e3e0f8d37495eade3bfb5beedfb61e7b8da70d4c68edb82' 10 | readonly MBEDTLS_A=( "$MBEDTLS_2_3" "$MBEDTLS_2_1" "$MBEDTLS_1_3" ) 11 | readonly SHA_256_A=( "$SHA_256_2_3" "$SHA_256_2_1" "$SHA_256_1_3" ) 12 | readonly NO_TIME=1 13 | 14 | main() { 15 | # sudo apt-get install build-essential automake cmake wget 16 | 17 | echo -e " ************\n Please make sure to update the constants of scripts in the 'fuzz' folder!\n ************\n" 18 | 19 | for i in "${!MBEDTLS_A[@]}"; do 20 | # download if necessary 21 | wget -nc https://tls.mbed.org/download/"${MBEDTLS_A[$i]}${ARCHIVE_SUFFIX}" 22 | 23 | # validate the checksum of the code archives 24 | CHECKSUM=$(shasum -a 256 "${MBEDTLS_A[$i]}${ARCHIVE_SUFFIX}") 25 | 26 | if [[ "$CHECKSUM" != "${SHA_256_A[$i]} ${MBEDTLS_A[$i]}${ARCHIVE_SUFFIX}" ]]; then 27 | echo "Error: ${MBEDTLS_A[$i]}${ARCHIVE_SUFFIX} checksum check failed!" 28 | exit 1 29 | fi 30 | 31 | # extract archives 32 | tar xzf "${MBEDTLS_A[$i]}${ARCHIVE_SUFFIX}" 33 | 34 | VERSION='2' 35 | INCLUDE_DIR='mbedtls' 36 | 37 | if [[ "${MBEDTLS_A[$i]}" = "$MBEDTLS_1_3" ]]; then 38 | VERSION='1.3' 39 | INCLUDE_DIR='polarssl' 40 | fi 41 | 42 | # copy fuzzing code and configuration 43 | cp -R fuzz "${MBEDTLS_A[$i]}" 44 | cp "selftls-${VERSION}.c" "${MBEDTLS_A[$i]}/fuzz/selftls.c" 45 | 46 | # patch CMakeLists 47 | pushd "${MBEDTLS_A[$i]}" && patch -p1 < "../CMakeLists-${VERSION}.patch"; popd 48 | 49 | # make sure TLS time field is constant 50 | if [[ "$NO_TIME" = "1" ]]; then 51 | cp "config-${VERSION}.h" "${MBEDTLS_A[$i]}/include/${INCLUDE_DIR}/config.h" 52 | else 53 | pushd "${MBEDTLS_A[$i]}" && patch -p1 < "../time-${VERSION}.patch"; popd 54 | fi 55 | 56 | # compile the code 57 | pushd "${MBEDTLS_A[$i]}/fuzz" && ./compile.sh; popd 58 | done 59 | 60 | echo -e "\n ************\n If everything compiled correctly, go into one of the 'mbedtls-2.?.?/fuzz/' folders and run './fuzz.sh'\n ************" 61 | } 62 | 63 | main "$@" 64 | 65 | -------------------------------------------------------------------------------- /time-1.3.patch: -------------------------------------------------------------------------------- 1 | --- a/library/ssl_cli.c 2 | +++ b/library/ssl_cli.c 3 | @@ -551,7 +551,8 @@ static int ssl_write_client_hello( ssl_context *ssl ) 4 | buf[4], buf[5] ) ); 5 | 6 | #if defined(POLARSSL_HAVE_TIME) 7 | - t = time( NULL ); 8 | + /*t = time( NULL );*/ 9 | + t = 1; 10 | *p++ = (unsigned char)( t >> 24 ); 11 | *p++ = (unsigned char)( t >> 16 ); 12 | *p++ = (unsigned char)( t >> 8 ); 13 | --- a/library/ssl_srv.c 14 | +++ b/library/ssl_srv.c 15 | @@ -2099,7 +2099,8 @@ static int ssl_write_server_hello( ssl_context *ssl ) 16 | buf[4], buf[5] ) ); 17 | 18 | #if defined(POLARSSL_HAVE_TIME) 19 | - t = time( NULL ); 20 | + /*t = time( NULL );*/ 21 | + t = 1; 22 | *p++ = (unsigned char)( t >> 24 ); 23 | *p++ = (unsigned char)( t >> 16 ); 24 | *p++ = (unsigned char)( t >> 8 ); 25 | -------------------------------------------------------------------------------- /time-2.patch: -------------------------------------------------------------------------------- 1 | --- a/library/ssl_cli.c 2 | +++ b/library/ssl_cli.c 3 | @@ -490,7 +490,8 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl ) 4 | #endif 5 | 6 | #if defined(MBEDTLS_HAVE_TIME) 7 | - t = time( NULL ); 8 | + /*t = time( NULL );*/ 9 | + t = 1; 10 | *p++ = (unsigned char)( t >> 24 ); 11 | *p++ = (unsigned char)( t >> 16 ); 12 | *p++ = (unsigned char)( t >> 8 ); 13 | --- a/library/ssl_srv.c 14 | +++ b/library/ssl_srv.c 15 | @@ -2153,7 +2153,8 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) 16 | buf[4], buf[5] ) ); 17 | 18 | #if defined(MBEDTLS_HAVE_TIME) 19 | - t = time( NULL ); 20 | + /*t = time( NULL );*/ 21 | + t = 1; 22 | *p++ = (unsigned char)( t >> 24 ); 23 | *p++ = (unsigned char)( t >> 16 ); 24 | *p++ = (unsigned char)( t >> 8 ); 25 | --------------------------------------------------------------------------------