- Timestamp:
- Jun 27, 2021, 10:17:43 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/tlsio_wolfssl.c
r464 r471 52 52 char* x509privatekey; 53 53 int wolfssl_device_id; 54 char* hostname; 55 bool ignore_host_name_check; 54 size_t socket_reads; 56 55 } TLS_IO_INSTANCE; 57 56 58 57 STATIC_VAR_UNUSED const char* const OPTION_WOLFSSL_SET_DEVICE_ID = "SetDeviceId"; 59 static const size_t SOCKET_READ_LIMIT = 5;58 static const size_t SOCKET_READ_LIMIT = 10000; // 10,000 ms ? 60 59 61 60 /*this function will clone an option given by name and value*/ … … 106 105 } 107 106 } 108 #ifdef INVALID_DEVID109 else if(strcmp(name, OPTION_WOLFSSL_SET_DEVICE_ID) == 0 )110 {111 int* value_clone;112 113 if ((value_clone = malloc(sizeof(int))) == NULL)114 {115 LogError("unable to clone device id option");116 }117 else118 {119 *value_clone = *(int*)value;120 }121 122 result = value_clone;123 }124 #endif125 107 else 126 108 { … … 144 126 if ((strcmp(name, OPTION_TRUSTED_CERT) == 0) || 145 127 (strcmp(name, SU_OPTION_X509_CERT) == 0) || 146 (strcmp(name, SU_OPTION_X509_PRIVATE_KEY) == 0) || 147 (strcmp(name, OPTION_WOLFSSL_SET_DEVICE_ID) == 0)) 128 (strcmp(name, SU_OPTION_X509_PRIVATE_KEY) == 0)) 148 129 { 149 130 free((void*)value); … … 203 184 result = NULL; 204 185 } 205 #ifdef INVALID_DEVID206 else if (207 (tls_io_instance->wolfssl_device_id != INVALID_DEVID) &&208 (OptionHandler_AddOption(result, OPTION_WOLFSSL_SET_DEVICE_ID, &tls_io_instance->wolfssl_device_id) != OPTIONHANDLER_OK)209 )210 {211 LogError("unable to save deviceid option");212 OptionHandler_Destroy(result);213 result = NULL;214 }215 #endif216 186 else 217 187 { … … 287 257 int res; 288 258 tls_io_instance->tlsio_state = TLSIO_STATE_IN_HANDSHAKE; 259 tls_io_instance->socket_reads = 0; 289 260 290 261 res = wolfSSL_connect(tls_io_instance->ssl); 291 262 if (res != SSL_SUCCESS) 292 263 { 293 // Error codes explained in https://www.wolfssl.com/docs/wolfssl-manual/appendix-c/ 294 LogError("WolfSSL connect failed (%d)", wolfSSL_get_error(tls_io_instance->ssl, res)); 264 LogError("WolfSSL connect failed"); 295 265 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR); 296 266 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; … … 384 354 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 385 355 unsigned char* new_socket_io_read_bytes; 386 size_t socket_reads = 0;387 356 388 357 AZURE_UNREFERENCED_PARAMETER(ssl); 389 while (tls_io_instance->socket_io_read_byte_count == 0 && socket_reads < SOCKET_READ_LIMIT) 390 { 358 if (tls_io_instance->socket_io_read_byte_count == 0) 359 { 360 if (tls_io_instance->socket_reads >= SOCKET_READ_LIMIT) { 361 return WOLFSSL_CBIO_ERR_TIMEOUT; 362 } 391 363 xio_dowork(tls_io_instance->socket_io); 392 if (tls_io_instance->tlsio_state != TLSIO_STATE_IN_HANDSHAKE) 393 { 394 break; 395 } 396 socket_reads++; 364 if (tls_io_instance->tlsio_state == TLSIO_STATE_IN_HANDSHAKE) 365 { 366 tls_io_instance->socket_reads++; 367 ThreadAPI_Sleep(1); 368 return 0; 369 } 397 370 } 398 371 … … 443 416 } 444 417 418 static void on_send_complete(void* context, IO_SEND_RESULT send_result) 419 { 420 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 421 if ((tls_io_instance == NULL) || (tls_io_instance->on_send_complete == NULL)) 422 return; 423 424 tls_io_instance->on_send_complete(tls_io_instance->on_send_complete_callback_context, send_result); 425 426 tls_io_instance->on_send_complete = NULL; 427 tls_io_instance->on_send_complete_callback_context = NULL; 428 } 429 445 430 static int on_io_send(WOLFSSL *ssl, char *buf, int sz, void *context) 446 431 { … … 450 435 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 451 436 452 if (xio_send(tls_io_instance->socket_io, buf, sz, tls_io_instance->on_send_complete, tls_io_instance->on_send_complete_callback_context) != 0)437 if (xio_send(tls_io_instance->socket_io, buf, sz, on_send_complete, tls_io_instance) != 0) 453 438 { 454 439 LogError("Failed sending bytes through underlying IO"); 455 440 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; 456 441 indicate_error(tls_io_instance); 457 result = WOLFSSL_CBIO_ERR_GENERAL;442 result = -1; 458 443 } 459 444 else … … 469 454 AZURE_UNREFERENCED_PARAMETER(ssl); 470 455 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 471 if (tls_io_instance->tlsio_state != TLSIO_STATE_IN_HANDSHAKE) 456 if (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN) { 457 } 458 else if (tls_io_instance->tlsio_state != TLSIO_STATE_IN_HANDSHAKE) 472 459 { 473 460 LogInfo("on_handshake_done called when not in IN_HANDSHAKE state"); … … 569 556 } 570 557 571 static int enable_domain_check(TLS_IO_INSTANCE* tls_io_instance)572 {573 int result = 0;574 575 if (!tls_io_instance->ignore_host_name_check)576 {577 if (wolfSSL_check_domain_name(tls_io_instance->ssl, tls_io_instance->hostname) != WOLFSSL_SUCCESS)578 {579 result = MU_FAILURE;580 }581 }582 583 return result;584 }585 586 558 static int prepare_wolfssl_open(TLS_IO_INSTANCE* tls_io_instance) 587 559 { 588 560 int result; 589 590 if (enable_domain_check(tls_io_instance)) 591 { 592 LogError("Failed to configure domain name verification"); 593 result = MU_FAILURE; 594 } 595 else if (add_certificate_to_store(tls_io_instance) != 0) 561 if (add_certificate_to_store(tls_io_instance) != 0) 596 562 { 597 563 LogError("Failed to add certificates to store"); … … 607 573 result = MU_FAILURE; 608 574 } 575 #ifdef INVALID_DEVID 576 else if (tls_io_instance->wolfssl_device_id != INVALID_DEVID && wolfSSL_SetDevId(tls_io_instance->ssl, tls_io_instance->wolfssl_device_id) != WOLFSSL_SUCCESS) 577 { 578 LogError("Failure setting device id"); 579 result = MU_FAILURE; 580 } 581 #endif 609 582 else 610 583 { … … 653 626 { 654 627 LogError("Cannot create the wolfSSL context"); 655 free(result);656 result = NULL;657 }658 else if (mallocAndStrcpy_s(&result->hostname, tls_io_config->hostname) != 0)659 {660 LogError("Failed copying the target hostname.");661 628 free(result); 662 629 result = NULL; … … 691 658 LogError("Failed getting socket IO interface description."); 692 659 wolfSSL_CTX_free(result->ssl_context); 693 free(result->hostname);694 660 free(result); 695 661 result = NULL; … … 702 668 LogError("Failure connecting to underlying socket_io"); 703 669 wolfSSL_CTX_free(result->ssl_context); 704 free(result->hostname);705 670 free(result); 706 671 result = NULL; … … 710 675 LogError("Failure connecting to underlying socket_io"); 711 676 wolfSSL_CTX_free(result->ssl_context); 712 free(result->hostname);713 677 free(result); 714 678 result = NULL; … … 753 717 754 718 xio_destroy(tls_io_instance->socket_io); 755 free(tls_io_instance->hostname);756 719 free(tls_io); 757 720 } … … 803 766 else 804 767 { 805 // The state can get changed in the on_underlying_io_open_complete 806 if (tls_io_instance->tlsio_state != TLSIO_STATE_OPEN) 768 result = 0; 769 } 770 } 771 } 772 773 return result; 774 } 775 776 int tlsio_wolfssl_close(CONCRETE_IO_HANDLE tls_io, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context) 777 { 778 int result = 0; 779 780 if (tls_io == NULL) 781 { 782 LogError("NULL tls_io handle."); 783 result = MU_FAILURE; 784 } 785 else 786 { 787 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 788 789 if ((tls_io_instance->tlsio_state == TLSIO_STATE_NOT_OPEN) || 790 (tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING)) 791 { 792 LogError("Close called while not open."); 793 result = MU_FAILURE; 794 } 795 else 796 { 797 tls_io_instance->tlsio_state = TLSIO_STATE_CLOSING; 798 tls_io_instance->on_io_close_complete = on_io_close_complete; 799 tls_io_instance->on_io_close_complete_context = callback_context; 800 801 if (xio_close(tls_io_instance->socket_io, on_underlying_io_close_complete, tls_io_instance) != 0) 802 { 803 LogError("xio_close failed."); 804 result = MU_FAILURE; 805 } 806 else 807 { 808 result = 0; 809 } 810 } 811 } 812 813 return result; 814 } 815 816 int tlsio_wolfssl_send(CONCRETE_IO_HANDLE tls_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context) 817 { 818 int result; 819 820 if (tls_io == NULL || buffer == NULL || size == 0) 821 { 822 LogError("Invalid parameter specified tls_io: %p, buffer: %p, size: %ul", tls_io, buffer, (unsigned int)size); 823 result = MU_FAILURE; 824 } 825 else 826 { 827 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 828 829 if (tls_io_instance->tlsio_state != TLSIO_STATE_OPEN) 830 { 831 LogError("send called while not open"); 832 result = MU_FAILURE; 833 } 834 if (tls_io_instance->on_send_complete != NULL) 835 { 836 LogError("Error writing data"); 837 result = MU_FAILURE; 838 } 839 else 840 { 841 tls_io_instance->on_send_complete = on_send_complete; 842 tls_io_instance->on_send_complete_callback_context = callback_context; 843 844 int res = wolfSSL_write(tls_io_instance->ssl, buffer, size); 845 if ((res < 0) || ((size_t)res != size)) // Best way I can think of to safely compare an int to a size_t 846 { 847 LogError("Error writing data through WolfSSL"); 848 result = MU_FAILURE; 849 } 850 else 851 { 852 result = 0; 853 } 854 } 855 } 856 857 return result; 858 } 859 860 void tlsio_wolfssl_dowork(CONCRETE_IO_HANDLE tls_io) 861 { 862 if (tls_io == NULL) 863 { 864 LogError("NULL tls_io"); 865 } 866 else 867 { 868 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 869 870 if ((tls_io_instance->tlsio_state != TLSIO_STATE_NOT_OPEN) && 871 (tls_io_instance->tlsio_state != TLSIO_STATE_ERROR)) 872 { 873 if (tls_io_instance->tlsio_state != TLSIO_STATE_OPENING_UNDERLYING_IO) 874 decode_ssl_received_bytes(tls_io_instance); 875 xio_dowork(tls_io_instance->socket_io); 876 } 877 } 878 } 879 880 881 static int process_option(char** destination, const char* name, const char* value) 882 { 883 int result; 884 if (*destination != NULL) 885 { 886 free(*destination); 887 *destination = NULL; 888 } 889 if (mallocAndStrcpy_s(destination, value) != 0) 890 { 891 LogError("unable to process option %s",name); 892 result = MU_FAILURE; 893 } 894 else 895 { 896 result = 0; 897 } 898 return result; 899 } 900 901 int tlsio_wolfssl_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, const void* value) 902 { 903 int result; 904 905 if (tls_io == NULL || optionName == NULL) 906 { 907 LogError("Bad arguments, tls_io = %p, optionName = %p", tls_io, optionName); 908 result = MU_FAILURE; 909 } 910 else 911 { 912 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 913 914 if (strcmp(OPTION_TRUSTED_CERT, optionName) == 0) 915 { 916 result = process_option(&tls_io_instance->certificate, optionName, value); 917 } 918 else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0 || strcmp(OPTION_X509_ECC_CERT, optionName) == 0) 919 { 920 result = process_option(&tls_io_instance->x509certificate, optionName, value); 921 } 922 else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0 || strcmp(OPTION_X509_ECC_KEY, optionName) == 0) 923 { 924 result = process_option(&tls_io_instance->x509privatekey, optionName, value); 925 } 926 else if (strcmp(optionName, OPTION_SET_TLS_RENEGOTIATION) == 0) 927 { 928 // No need to do anything for WolfSSL 929 result = 0; 930 } 931 #ifdef INVALID_DEVID 932 else if (strcmp(OPTION_WOLFSSL_SET_DEVICE_ID, optionName) == 0) 933 { 934 int device_id = *((int *)value); 935 if (tls_io_instance->ssl != NULL) 936 { 937 if (tls_io_instance->ssl != NULL && wolfSSL_SetDevId(tls_io_instance->ssl, device_id) != WOLFSSL_SUCCESS) 807 938 { 808 LogError("Fail ed to connect to server. The certificates may not be correct.");939 LogError("Failure setting device id on ssl"); 809 940 result = MU_FAILURE; 810 941 } … … 814 945 } 815 946 } 816 } 817 } 818 819 return result; 820 } 821 822 int tlsio_wolfssl_close(CONCRETE_IO_HANDLE tls_io, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context) 823 { 824 int result = 0; 825 826 if (tls_io == NULL) 827 { 828 LogError("NULL tls_io handle."); 829 result = MU_FAILURE; 830 } 831 else 832 { 833 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 834 835 if ((tls_io_instance->tlsio_state == TLSIO_STATE_NOT_OPEN) || 836 (tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING)) 837 { 838 LogError("Close called while not open."); 839 result = MU_FAILURE; 840 } 841 else 842 { 843 tls_io_instance->tlsio_state = TLSIO_STATE_CLOSING; 844 tls_io_instance->on_io_close_complete = on_io_close_complete; 845 tls_io_instance->on_io_close_complete_context = callback_context; 846 847 if (xio_close(tls_io_instance->socket_io, on_underlying_io_close_complete, tls_io_instance) != 0) 848 { 849 LogError("xio_close failed."); 850 result = MU_FAILURE; 851 } 852 else 853 { 854 result = 0; 855 } 856 } 857 } 858 859 return result; 860 } 861 862 int tlsio_wolfssl_send(CONCRETE_IO_HANDLE tls_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context) 863 { 864 int result; 865 866 if (tls_io == NULL || buffer == NULL || size == 0) 867 { 868 LogError("Invalid parameter specified tls_io: %p, buffer: %p, size: %ul", tls_io, buffer, (unsigned int)size); 869 result = MU_FAILURE; 870 } 871 else 872 { 873 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 874 875 if (tls_io_instance->tlsio_state != TLSIO_STATE_OPEN) 876 { 877 LogError("send called while not open"); 878 result = MU_FAILURE; 879 } 880 else 881 { 882 tls_io_instance->on_send_complete = on_send_complete; 883 tls_io_instance->on_send_complete_callback_context = callback_context; 884 885 int res = wolfSSL_write(tls_io_instance->ssl, buffer, size); 886 if ((res < 0) || ((size_t)res != size)) // Best way I can think of to safely compare an int to a size_t 887 { 888 LogError("Error writing data through WolfSSL"); 889 result = MU_FAILURE; 890 } 891 else 892 { 893 result = 0; 894 } 895 } 896 } 897 898 return result; 899 } 900 901 void tlsio_wolfssl_dowork(CONCRETE_IO_HANDLE tls_io) 902 { 903 if (tls_io == NULL) 904 { 905 LogError("NULL tls_io"); 906 } 907 else 908 { 909 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 910 911 if ((tls_io_instance->tlsio_state != TLSIO_STATE_NOT_OPEN) && 912 (tls_io_instance->tlsio_state != TLSIO_STATE_ERROR)) 913 { 914 decode_ssl_received_bytes(tls_io_instance); 915 xio_dowork(tls_io_instance->socket_io); 916 } 917 } 918 } 919 920 921 static int process_option(char** destination, const char* name, const char* value) 922 { 923 924 (void) name; 925 926 int result; 927 if (*destination != NULL) 928 { 929 free(*destination); 930 *destination = NULL; 931 } 932 if (mallocAndStrcpy_s(destination, value) != 0) 933 { 934 LogError("unable to process option %s",name); 935 result = MU_FAILURE; 936 } 937 else 938 { 939 result = 0; 940 } 941 return result; 942 } 943 944 int tlsio_wolfssl_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, const void* value) 945 { 946 int result; 947 948 if (tls_io == NULL || optionName == NULL) 949 { 950 LogError("Bad arguments, tls_io = %p, optionName = %p", tls_io, optionName); 951 result = MU_FAILURE; 952 } 953 else 954 { 955 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 956 957 if (strcmp(OPTION_TRUSTED_CERT, optionName) == 0) 958 { 959 result = process_option(&tls_io_instance->certificate, optionName, value); 960 } 961 else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0 || strcmp(OPTION_X509_ECC_CERT, optionName) == 0) 962 { 963 result = process_option(&tls_io_instance->x509certificate, optionName, value); 964 } 965 else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0 || strcmp(OPTION_X509_ECC_KEY, optionName) == 0) 966 { 967 result = process_option(&tls_io_instance->x509privatekey, optionName, value); 968 } 969 else if (strcmp(optionName, OPTION_SET_TLS_RENEGOTIATION) == 0) 970 { 971 // No need to do anything for WolfSSL 972 result = 0; 973 } 974 #ifdef INVALID_DEVID 975 else if (strcmp(OPTION_WOLFSSL_SET_DEVICE_ID, optionName) == 0) 976 { 977 int device_id = *((int *)value); 978 if (tls_io_instance->ssl != NULL && wolfSSL_SetDevId(tls_io_instance->ssl, device_id) != WOLFSSL_SUCCESS) 979 { 980 LogError("Failure setting device id on ssl"); 981 result = MU_FAILURE; 982 } 983 else 984 { 985 // Save the device Id even if ssl object not yet created. 947 else 948 { 949 // Save the id till we create the ssl object 986 950 tls_io_instance->wolfssl_device_id = device_id; 987 951 result = 0; … … 989 953 } 990 954 #endif 991 else if (strcmp("ignore_host_name_check", optionName) == 0)992 {993 bool* server_name_check = (bool*)value;994 tls_io_instance->ignore_host_name_check = *server_name_check;995 result = 0;996 }997 955 else 998 956 {
Note:
See TracChangeset
for help on using the changeset viewer.