int IoTHubClient_Auth_Set_xio_Certificate(IOTHUB_AUTHORIZATION_HANDLE handle, XIO_HANDLE xio) { int result; if (handle == NULL || xio == NULL) { LogError("Invalid Parameter handle: %p xio: %p", handle, xio); result = __FAILURE__; } else if (handle->cred_type != IOTHUB_CREDENTIAL_TYPE_X509_ECC) { LogError("Invalid credential types for this operation"); result = __FAILURE__; } else { #ifdef USE_PROV_MODULE CREDENTIAL_RESULT* cred_result = iothub_device_auth_generate_credentials(handle->device_auth_handle, NULL); if (cred_result == NULL) { LogError("Failure generating credentials"); result = __FAILURE__; } else { if (xio_setoption(xio, OPTION_X509_ECC_CERT, cred_result->auth_cred_result.x509_result.x509_cert) != 0) { LogError("Failure setting x509 cert on xio"); result = __FAILURE__; } else if (xio_setoption(xio, OPTION_X509_ECC_KEY, cred_result->auth_cred_result.x509_result.x509_alias_key) != 0) { LogError("Failure setting x509 key on xio"); result = __FAILURE__; } else { result = 0; } free(cred_result); } #else LogError("Failed HSM module is not supported"); result = __FAILURE__; #endif } return result; }
static XIO_HANDLE mqtt_transport_io(const char* fqdn, const HTTP_PROXY_OPTIONS* proxy_info) { XIO_HANDLE result; HTTP_PROXY_IO_CONFIG proxy_config; TLSIO_CONFIG tls_io_config; memset(&tls_io_config, 0, sizeof(TLSIO_CONFIG)); tls_io_config.hostname = fqdn; tls_io_config.port = MQTT_PORT_NUM; if (proxy_info != NULL) { /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_012: [ If proxy_info is not NULL, amqp_transport_io shall construct a HTTP_PROXY_IO_CONFIG object and assign it to TLSIO_CONFIG underlying_io_parameters ] */ proxy_config.hostname = tls_io_config.hostname; proxy_config.port = MQTT_PORT_NUM; proxy_config.proxy_hostname = proxy_info->host_address; proxy_config.proxy_port = proxy_info->port; proxy_config.username = proxy_info->username; proxy_config.password = proxy_info->password; tls_io_config.underlying_io_interface = http_proxy_io_get_interface_description(); tls_io_config.underlying_io_parameters = &proxy_config; } const IO_INTERFACE_DESCRIPTION* tlsio_interface = platform_get_default_tlsio(); if (tlsio_interface == NULL) { /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_013: [ If any failure is encountered amqp_transport_io shall return NULL ]*/ LogError("platform_get_default_tlsio return NULL IO Interface"); result = NULL; } else { result = xio_create(tlsio_interface, &tls_io_config); if (result == NULL) { /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_013: [ If any failure is encountered amqp_transport_io shall return NULL ]*/ LogError("failed calling xio_create on underlying io"); result = NULL; } else { #ifdef USE_OPENSSL // requires tls 1.2 int tls_version = 12; xio_setoption(result, OPTION_TLS_VERSION, &tls_version); #endif } } /* Codes_PROV_TRANSPORT_MQTT_CLIENT_07_014: [ On success mqtt_transport_io shall return allocated XIO_HANDLE. ] */ return result; }
static int create_sasl_components(AMQP_CONNECTION_INSTANCE* instance) { int result; SASL_MECHANISM_HANDLE sasl_mechanism; XIO_HANDLE sasl_io; // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_012: [`instance->sasl_mechanism` shall be created using saslmechanism_create()] if ((sasl_mechanism = saslmechanism_create(saslmssbcbs_get_interface(), NULL)) == NULL) { // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_013: [If saslmechanism_create() fails, amqp_connection_create() shall fail and return NULL] LogError("Failed creating the SASL mechanism (saslmechanism_create failed)"); result = __FAILURE__; } else { // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_014: [A SASLCLIENTIO_CONFIG shall be set with `instance->underlying_io_transport` and `instance->sasl_mechanism`] SASLCLIENTIO_CONFIG sasl_client_config; sasl_client_config.sasl_mechanism = sasl_mechanism; sasl_client_config.underlying_io = instance->underlying_io_transport; // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_015: [`instance->sasl_io` shall be created using xio_create() passing saslclientio_get_interface_description() and the SASLCLIENTIO_CONFIG instance] if ((sasl_io = xio_create(saslclientio_get_interface_description(), &sasl_client_config)) == NULL) { // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_016: [If xio_create() fails, amqp_connection_create() shall fail and return NULL] LogError("Failed creating the SASL I/O (xio_create failed)"); saslmechanism_destroy(sasl_mechanism); result = __FAILURE__; } // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_017: [The sasl_io "logtrace" option shall be set using xio_setoption(), passing `instance->is_trace_on`] else if (xio_setoption(sasl_io, SASL_IO_OPTION_LOG_TRACE, (const void*)&instance->is_trace_on) != RESULT_OK) { LogError("Failed setting the SASL I/O logging trace option (xio_setoption failed)"); xio_destroy(sasl_io); saslmechanism_destroy(sasl_mechanism); result = __FAILURE__; } else { instance->sasl_mechanism = sasl_mechanism; instance->sasl_io = sasl_io; result = RESULT_OK; } } return result; }
int tlsio_wolfssl_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, const void* value) { int result; if (tls_io == NULL || optionName == NULL) { result = __LINE__; } else { TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; if (strcmp("TrustedCerts", optionName) == 0) { const char* cert = (const char*)value; if (tls_io_instance->certificate != NULL) { // Free the memory if it has been previously allocated free(tls_io_instance->certificate); } // Store the certificate size_t len = strlen(cert); tls_io_instance->certificate = (const char*)malloc(len+1); if (tls_io_instance->certificate == NULL) { result = __LINE__; } else { (void)strcpy(tls_io_instance->certificate, cert); result = 0; } } else if (tls_io_instance->socket_io == NULL) { result = __LINE__; } else { result = xio_setoption(tls_io_instance->socket_io, optionName, value); } } return result; }
int amqp_connection_set_logging(AMQP_CONNECTION_HANDLE conn_handle, bool is_trace_on) { int result; // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_052: [If `conn_handle` is NULL, amqp_connection_set_logging() shall fail and return __FAILURE__] if (conn_handle == NULL) { result = __FAILURE__; LogError("amqp_connection_set_logging failed (conn_handle is NULL)"); } else { AMQP_CONNECTION_INSTANCE* instance = (AMQP_CONNECTION_INSTANCE*)conn_handle; // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_053: [`instance->is_trace_on` shall be set to `is_trace_on`] instance->is_trace_on = is_trace_on; // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_054: [Tracing on `instance->sasl_io` shall be set to `instance->is_trace_on` if the value has changed] if (instance->sasl_io != NULL && xio_setoption(instance->sasl_io, SASL_IO_OPTION_LOG_TRACE, (const void*)&instance->is_trace_on) != RESULT_OK) { // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_072: [If xio_setoption() fails, amqp_connection_set_logging() shall fail and return __FAILURE__] result = __FAILURE__; LogError("amqp_connection_set_logging failed (xio_setoption() failed)"); } else { // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_055: [Tracing on `instance->connection_handle` shall be set to `instance->is_trace_on` if the value has changed] connection_set_trace(instance->connection_handle, instance->is_trace_on); // Codes_SRS_IOTHUBTRANSPORT_AMQP_CONNECTION_09_056: [amqp_connection_set_logging() shall return success code 0] result = RESULT_OK; } } return result; }
int tlsio_schannel_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, const void* value) { int result; if (tls_io == NULL || optionName == NULL) { result = __LINE__; } else { TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; if (tls_io_instance->socket_io == NULL) { result = __LINE__; } else { result = xio_setoption(tls_io_instance->socket_io, optionName, value); } } return result; }
static PROV_TRANSPORT_IO_INFO* amqp_transport_ws_io(const char* fqdn, SASL_MECHANISM_HANDLE* sasl_mechanism, const HTTP_PROXY_OPTIONS* proxy_info) { PROV_TRANSPORT_IO_INFO* result; HTTP_PROXY_IO_CONFIG proxy_config; TLSIO_CONFIG tls_io_config; WSIO_CONFIG ws_io_config; const IO_INTERFACE_DESCRIPTION* ws_io_interface; const IO_INTERFACE_DESCRIPTION* tlsio_interface; if ((ws_io_interface = wsio_get_interface_description()) == NULL) { /* Codes_PROV_TRANSPORT_AMQP_WS_CLIENT_07_013: [ If any failure is encountered amqp_transport_ws_io shall return NULL ] */ LogError("wsio_get_interface_description return NULL IO Interface"); result = NULL; } else if ((tlsio_interface = platform_get_default_tlsio()) == NULL) { /* Codes_PROV_TRANSPORT_AMQP_WS_CLIENT_07_013: [ If any failure is encountered amqp_transport_ws_io shall return NULL ] */ LogError("platform_get_default_tlsio return NULL IO Interface"); result = NULL; } else { memset(&tls_io_config, 0, sizeof(TLSIO_CONFIG)); ws_io_config.hostname = fqdn; ws_io_config.port = PROV_AMQP_WS_PORT_NUM; ws_io_config.protocol = PROV_AMQP_WS_PROTOCOL_NAME; ws_io_config.resource_name = PROV_AMQP_WS_RELATIVE_PATH; ws_io_config.underlying_io_interface = tlsio_interface; ws_io_config.underlying_io_parameters = &tls_io_config; tls_io_config.hostname = fqdn; tls_io_config.port = PROV_AMQP_WS_PORT_NUM; if (proxy_info != NULL) { /* Codes_PROV_TRANSPORT_AMQP_WS_CLIENT_07_012: [ If proxy_info is not NULL, amqp_transport_ws_io shall construct a HTTP_PROXY_IO_CONFIG object and assign it to TLSIO_CONFIG underlying_io_parameters ] */ proxy_config.hostname = tls_io_config.hostname; proxy_config.port = proxy_info->port; proxy_config.proxy_hostname = proxy_info->host_address; proxy_config.proxy_port = proxy_info->port; proxy_config.username = proxy_info->username; proxy_config.password = proxy_info->password; tls_io_config.underlying_io_interface = http_proxy_io_get_interface_description(); tls_io_config.underlying_io_parameters = &proxy_config; } /* Codes_PROV_TRANSPORT_AMQP_WS_CLIENT_07_014: [ On success amqp_transport_ws_io shall return an allocated PROV_TRANSPORT_IO_INFO structure. ] */ if ((result = (PROV_TRANSPORT_IO_INFO*)malloc(sizeof(PROV_TRANSPORT_IO_INFO))) == NULL) { /* Codes_PROV_TRANSPORT_AMQP_WS_CLIENT_07_013: [ If any failure is encountered amqp_transport_ws_io shall return NULL ] */ LogError("failure allocating prov_transport info"); result = NULL; } else { memset(result, 0, sizeof(PROV_TRANSPORT_IO_INFO)); /* Codes_PROV_TRANSPORT_AMQP_WS_CLIENT_07_015: [ amqp_transport_ws_io shall allocate a PROV_TRANSPORT_IO_INFO transfer_handle by calling xio_create with the ws_io_interface. ] */ result->transport_handle = xio_create(ws_io_interface, &ws_io_config); if (result->transport_handle == NULL) { /* Codes_PROV_TRANSPORT_AMQP_WS_CLIENT_07_013: [ If any failure is encountered amqp_transport_ws_io shall return NULL ] */ LogError("failed calling xio_create on underlying io"); free(result); result = NULL; } else { #ifdef USE_OPENSSL // Default to tls 1.2 int tls_version = 12; xio_setoption(result->transport_handle, OPTION_TLS_VERSION, &tls_version); #endif if (sasl_mechanism != NULL) { const IO_INTERFACE_DESCRIPTION* saslio_interface; SASLCLIENTIO_CONFIG sasl_io_config; sasl_io_config.underlying_io = result->transport_handle; sasl_io_config.sasl_mechanism = *sasl_mechanism; saslio_interface = saslclientio_get_interface_description(); if (saslio_interface == NULL) { /* Codes_PROV_TRANSPORT_AMQP_WS_CLIENT_07_013: [ If any failure is encountered amqp_transport_ws_io shall return NULL ] */ LogError("failed calling xio_create on underlying io"); xio_destroy(result->transport_handle); free(result); result = NULL; } else { /* Codes_PROV_TRANSPORT_AMQP_WS_CLIENT_07_016: [ amqp_transport_ws_io shall allocate a PROV_TRANSPORT_IO_INFO sasl_handle by calling xio_create with the saslio_interface. ] */ result->sasl_handle = xio_create(saslio_interface, &sasl_io_config); if (result->sasl_handle == NULL) { /* Codes_PROV_TRANSPORT_AMQP_WS_CLIENT_07_013: [ If any failure is encountered amqp_transport_ws_io shall return NULL ] */ LogError("failed calling xio_create on sasl client interface"); xio_destroy(result->transport_handle); free(result); result = NULL; } } } } } } return result; }
static int construct_transport(PROV_TRANSPORT_MQTT_INFO* mqtt_info) { int result; if (mqtt_info->transport_io == NULL) { HTTP_PROXY_OPTIONS* transport_proxy; if (mqtt_info->proxy_option.host_address != NULL) { transport_proxy = &mqtt_info->proxy_option; } else { transport_proxy = NULL; } if ((mqtt_info->transport_io = mqtt_info->transport_io_cb(mqtt_info->hostname, transport_proxy)) == NULL) { LogError("Failure calling transport_io callback"); result = __FAILURE__; } else { if (mqtt_info->certificate != NULL && xio_setoption(mqtt_info->transport_io, OPTION_TRUSTED_CERT, mqtt_info->certificate) != 0) { LogError("Failure setting trusted certs"); result = __FAILURE__; xio_destroy(mqtt_info->transport_io); mqtt_info->transport_io = NULL; } else if (mqtt_info->hsm_type == TRANSPORT_HSM_TYPE_X509) { if (mqtt_info->x509_cert != NULL && mqtt_info->private_key != NULL) { if (xio_setoption(mqtt_info->transport_io, OPTION_X509_ECC_CERT, mqtt_info->x509_cert) != 0) { LogError("Failure setting x509 cert on xio"); xio_destroy(mqtt_info->transport_io); mqtt_info->transport_io = NULL; result = __FAILURE__; } else if (xio_setoption(mqtt_info->transport_io, OPTION_X509_ECC_KEY, mqtt_info->private_key) != 0) { LogError("Failure setting x509 key on xio"); xio_destroy(mqtt_info->transport_io); mqtt_info->transport_io = NULL; result = __FAILURE__; } else { result = 0; } } else { LogError("x509 certificate is NULL"); xio_destroy(mqtt_info->transport_io); mqtt_info->transport_io = NULL; result = __FAILURE__; } } else { result = 0; } } } else { result = 0; } return result; }
int tlsio_schannel_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, const void* value) { int result; if (tls_io == NULL || optionName == NULL) { result = __LINE__; } else { TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; /*x509certificate and x509privatekey are "referenced" by this layer*/ if (strcmp("x509certificate", optionName) == 0) { if (tls_io_instance->x509certificate != NULL) { LogError("unable to set x509 options more than once"); result =__LINE__; } else { tls_io_instance->x509certificate = (const char *)tlsio_schannel_CloneOption("x509certificate", value); if (tls_io_instance->x509privatekey != NULL) { tls_io_instance->x509_schannel_handle = x509_schannel_create(tls_io_instance->x509certificate, tls_io_instance->x509privatekey); if (tls_io_instance->x509_schannel_handle == NULL) { LogError("x509_schannel_create failed"); result = __LINE__; } else { /*all is fine, the x509 shall be used later*/ result = 0; } } else { result = 0; /*all is fine, maybe x509 privatekey will come and then x509 is set*/ } } } else if (strcmp("x509privatekey", optionName) == 0) { if (tls_io_instance->x509privatekey != NULL) { LogError("unable to set more than once x509 options"); result = __LINE__; } else { tls_io_instance->x509privatekey = (const char *)tlsio_schannel_CloneOption("x509privatekey", value); if (tls_io_instance->x509certificate!= NULL) { tls_io_instance->x509_schannel_handle = x509_schannel_create(tls_io_instance->x509certificate, tls_io_instance->x509privatekey); if (tls_io_instance->x509_schannel_handle == NULL) { LogError("x509_schannel_create failed"); result = __LINE__; } else { /*all is fine, the x509 shall be used later*/ result = 0; } } else { result = 0; /*all is fine, maybe x509 privatekey will come and then x509 is set*/ } } } else if (tls_io_instance->socket_io == NULL) { result = __LINE__; } else { result = xio_setoption(tls_io_instance->socket_io, optionName, value); } } return result; }
int tls_server_io_schannel_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, const void* value) { int result; if (tls_io == NULL || optionName == NULL) { LogError("invalid argument detected: CONCRETE_IO_HANDLE tls_io = %p, const char* optionName = %p", tls_io, optionName); result = __FAILURE__; } else { TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; if (strcmp("x509certificate", optionName) == 0) { if (tls_io_instance->x509certificate != NULL) { LogError("x509certificate has already been specified"); result = __FAILURE__; } else { tls_io_instance->x509certificate = (char *)tls_server_io_schannel_CloneOption("x509certificate", value); if (tls_io_instance->x509certificate == NULL) { LogError("tls_server_io_schannel_CloneOption failed"); result = __FAILURE__; } else { if (tls_io_instance->x509privatekey != NULL) { tls_io_instance->x509_schannel_handle = x509_schannel_create(tls_io_instance->x509certificate, tls_io_instance->x509privatekey); if (tls_io_instance->x509_schannel_handle == NULL) { LogError("x509_schannel_create failed"); result = __FAILURE__; } else { /*all is fine, the x509 shall be used later*/ result = 0; } } else { result = 0; /*all is fine, maybe x509 privatekey will come and then x509 is set*/ } } } } else if (strcmp("x509privatekey", optionName) == 0) { if (tls_io_instance->x509privatekey != NULL) { LogError("x509privatekey has already been specified"); result = __FAILURE__; } else { tls_io_instance->x509privatekey = (char *)tls_server_io_schannel_CloneOption("x509privatekey", value); if (tls_io_instance->x509privatekey == NULL) { LogError("tls_server_io_schannel_CloneOption failed"); result = __FAILURE__; } else { if (tls_io_instance->x509certificate != NULL) { tls_io_instance->x509_schannel_handle = x509_schannel_create(tls_io_instance->x509certificate, tls_io_instance->x509privatekey); if (tls_io_instance->x509_schannel_handle == NULL) { LogError("x509_schannel_create failed"); result = __FAILURE__; } else { /*all is fine, the x509 shall be used later*/ result = 0; } } else { result = 0; /*all is fine, maybe x509 cert will come and then x509 is set*/ } } } } else if (tls_io_instance->socket_io == NULL) { LogError("tls_io_instance->socket_io is not set"); result = __FAILURE__; } else { result = xio_setoption(tls_io_instance->socket_io, optionName, value); } } return result; }