static int create_and_put_SAS_token_to_cbs(AUTHENTICATION_INSTANCE* instance) { int result; char* sas_token; STRING_HANDLE devices_path; if ((devices_path = create_devices_path(instance->iothub_host_fqdn, instance->device_id)) == NULL) { // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_054: [If `devices_path` failed to be created, authentication_do_work() shall fail and return] // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_072: [If `devices_path` failed to be created, authentication_do_work() shall fail and return] result = __FAILURE__; sas_token = NULL; LogError("Failed creating a SAS token (create_devices_path() failed)"); } else { /* Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_07_001: [ authentication_do_work() shall determine what credential type is used SAS_TOKEN or DEVICE_KEY by calling IoTHubClient_Auth_Get_Credential_Type ] */ IOTHUB_CREDENTIAL_TYPE cred_type = IoTHubClient_Auth_Get_Credential_Type(instance->authorization_module); if (cred_type == IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY) { double seconds_since_epoch; // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_053: [A STRING_HANDLE, referred to as `devices_path`, shall be created from the following parts: iothub_host_fqdn + "/devices/" + device_id] // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_071: [A STRING_HANDLE, referred to as `devices_path`, shall be created from the following parts: iothub_host_fqdn + "/devices/" + device_id] if (get_seconds_since_epoch(&seconds_since_epoch) != RESULT_OK) { result = __FAILURE__; sas_token = NULL; LogError("Failed creating a SAS token (get_seconds_since_epoch() failed)"); } else { // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_052: [The SAS token expiration time shall be calculated adding `instance->sas_token_lifetime_secs` to the current number of seconds since epoch time UTC] // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_070: [The SAS token expiration time shall be calculated adding `instance->sas_token_lifetime_secs` to the current number of seconds since epoch time UTC] size_t sas_token_expiration_time_secs = (size_t)seconds_since_epoch + instance->sas_token_lifetime_secs; /* Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_049: [authentication_do_work() shall create a SAS token using IoTHubClient_Auth_Get_SasToken, unless it has failed previously] */ sas_token = IoTHubClient_Auth_Get_SasToken(instance->authorization_module, STRING_c_str(devices_path), sas_token_expiration_time_secs); if (sas_token == NULL) { LogError("failure getting sas token."); result = __FAILURE__; } else { result = RESULT_OK; } } } else if (cred_type == IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN) { /* Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_07_002: [ If credential Type is SAS_TOKEN authentication_do_work() shall validate the sas_token, and fail if it's not valid. ] */ SAS_TOKEN_STATUS token_status = IoTHubClient_Auth_Is_SasToken_Valid(instance->authorization_module); if (token_status == SAS_TOKEN_STATUS_INVALID) { LogError("sas token is invalid."); sas_token = NULL; result = __FAILURE__; } else if (token_status == SAS_TOKEN_STATUS_FAILED) { LogError("testing Sas Token failed."); sas_token = NULL; result = __FAILURE__; } else { /* Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_049: [authentication_do_work() shall create a SAS token using IoTHubClient_Auth_Get_SasToken, unless it has failed previously] */ sas_token = IoTHubClient_Auth_Get_SasToken(instance->authorization_module, NULL, 0); if (sas_token == NULL) { LogError("failure getting sas Token."); result = __FAILURE__; } else { result = RESULT_OK; } } } else if (cred_type == IOTHUB_CREDENTIAL_TYPE_X509) { sas_token = NULL; result = RESULT_OK; } else { LogError("failure unknown credential type found."); sas_token = NULL; result = __FAILURE__; } if (sas_token != NULL) { if (put_SAS_token_to_cbs(instance, devices_path, sas_token) != RESULT_OK) { result = __FAILURE__; LogError("Failed putting SAS token to CBS"); } else { result = RESULT_OK; } free(sas_token); } // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_081: [authentication_do_work() shall free the memory it allocated for `devices_path`, `sasTokenKeyName` and SAS token] STRING_delete(devices_path); } return result; }
char* IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const char* scope, size_t expiry_time_relative_seconds, const char* key_name) { char* result; (void)expiry_time_relative_seconds; /* Codes_SRS_IoTHub_Authorization_07_009: [ if handle or scope are NULL, IoTHubClient_Auth_Get_SasToken shall return NULL. ] */ if (handle == NULL) { LogError("Invalid Parameter handle: %p", handle); result = NULL; } else { if (handle->cred_type == IOTHUB_CREDENTIAL_TYPE_DEVICE_AUTH) { #ifdef USE_PROV_MODULE DEVICE_AUTH_CREDENTIAL_INFO dev_auth_cred; size_t sec_since_epoch; if (get_seconds_since_epoch(&sec_since_epoch) != 0) { LogError("failure getting seconds from epoch"); result = NULL; } else { memset(&dev_auth_cred, 0, sizeof(DEVICE_AUTH_CREDENTIAL_INFO)); size_t expiry_time = sec_since_epoch + handle->token_expiry_time_sec; dev_auth_cred.sas_info.expiry_seconds = expiry_time; dev_auth_cred.sas_info.token_scope = scope; dev_auth_cred.sas_info.key_name = key_name; dev_auth_cred.dev_auth_type = AUTH_TYPE_SAS; CREDENTIAL_RESULT* cred_result = iothub_device_auth_generate_credentials(handle->device_auth_handle, &dev_auth_cred); if (cred_result == NULL) { LogError("failure getting credentials from device auth module"); result = NULL; } else { if (mallocAndStrcpy_s(&result, cred_result->auth_cred_result.sas_result.sas_token) != 0) { LogError("failure allocating Sas Token"); result = NULL; } free(cred_result); } } #else LogError("Failed HSM module is not supported"); result = NULL; #endif } else if (handle->cred_type == IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN) { /* Codes_SRS_IoTHub_Authorization_07_021: [If the device_sas_token is NOT NULL IoTHubClient_Auth_Get_SasToken shall return a copy of the device_sas_token. ] */ if (handle->device_sas_token != NULL) { if (mallocAndStrcpy_s(&result, handle->device_sas_token) != 0) { LogError("failure allocating sas token"); result = NULL; } } else { LogError("failure device sas token is NULL"); result = NULL; } } else if (handle->cred_type == IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY) { /* Codes_SRS_IoTHub_Authorization_07_009: [ if handle or scope are NULL, IoTHubClient_Auth_Get_SasToken shall return NULL. ] */ if (scope == NULL) { LogError("Invalid Parameter scope: %p", scope); result = NULL; } else { STRING_HANDLE sas_token; size_t sec_since_epoch; /* Codes_SRS_IoTHub_Authorization_07_010: [ IoTHubClient_Auth_Get_SasToken` shall construct the expiration time using the handle->token_expiry_time_sec added to epoch time. ] */ if (get_seconds_since_epoch(&sec_since_epoch) != 0) { /* Codes_SRS_IoTHub_Authorization_07_020: [ If any error is encountered IoTHubClient_Auth_Get_ConnString shall return NULL. ] */ LogError("failure getting seconds from epoch"); result = NULL; } else { /* Codes_SRS_IoTHub_Authorization_07_011: [ IoTHubClient_Auth_Get_ConnString shall call SASToken_CreateString to construct the sas token. ] */ size_t expiry_time = sec_since_epoch + handle->token_expiry_time_sec; if ( (sas_token = SASToken_CreateString(handle->device_key, scope, key_name, expiry_time)) == NULL) { /* Codes_SRS_IoTHub_Authorization_07_020: [ If any error is encountered IoTHubClient_Auth_Get_ConnString shall return NULL. ] */ LogError("Failed creating sas_token"); result = NULL; } else { /* Codes_SRS_IoTHub_Authorization_07_012: [ On success IoTHubClient_Auth_Get_ConnString shall allocate and return the sas token in a char*. ] */ if (mallocAndStrcpy_s(&result, STRING_c_str(sas_token) ) != 0) { /* Codes_SRS_IoTHub_Authorization_07_020: [ If any error is encountered IoTHubClient_Auth_Get_ConnString shall return NULL. ] */ LogError("Failed copying result"); result = NULL; } STRING_delete(sas_token); } } } } else { LogError("Failed getting sas token invalid credential type"); result = NULL; } } return result; }
char* IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const char* scope, size_t expire_time) { char* result; /* Codes_SRS_IoTHub_Authorization_07_009: [ if handle or scope are NULL, IoTHubClient_Auth_Get_SasToken shall return NULL. ] */ if (handle == NULL) { LogError("Invalid Parameter handle: %p", handle); result = NULL; } else { /* Codes_SRS_IoTHub_Authorization_07_021: [If the device_sas_token is NOT NULL IoTHubClient_Auth_Get_SasToken shall return a copy of the device_sas_token. ] */ if (handle->device_sas_token != NULL) { if (mallocAndStrcpy_s(&result, handle->device_sas_token) != 0) { LogError("failure allocating sas token", scope); result = NULL; } } /* Codes_SRS_IoTHub_Authorization_07_009: [ if handle or scope are NULL, IoTHubClient_Auth_Get_SasToken shall return NULL. ] */ else if (scope == NULL) { LogError("Invalid Parameter scope: %p", scope); result = NULL; } else { const char* key_name = ""; STRING_HANDLE sas_token; size_t sec_since_epoch; /* Codes_SRS_IoTHub_Authorization_07_010: [ IoTHubClient_Auth_Get_ConnString shall construct the expiration time using the expire_time. ] */ if (get_seconds_since_epoch(&sec_since_epoch) != 0) { /* Codes_SRS_IoTHub_Authorization_07_020: [ If any error is encountered IoTHubClient_Auth_Get_ConnString shall return NULL. ] */ LogError("failure getting seconds from epoch"); result = NULL; } else { /* Codes_SRS_IoTHub_Authorization_07_011: [ IoTHubClient_Auth_Get_ConnString shall call SASToken_CreateString to construct the sas token. ] */ size_t expiry_time = sec_since_epoch+expire_time; if ( (sas_token = SASToken_CreateString(handle->device_key, scope, key_name, expiry_time)) == NULL) { /* Codes_SRS_IoTHub_Authorization_07_020: [ If any error is encountered IoTHubClient_Auth_Get_ConnString shall return NULL. ] */ LogError("Failed creating sas_token"); result = NULL; } else { /* Codes_SRS_IoTHub_Authorization_07_012: [ On success IoTHubClient_Auth_Get_ConnString shall allocate and return the sas token in a char*. ] */ if (mallocAndStrcpy_s(&result, STRING_c_str(sas_token) ) != 0) { /* Codes_SRS_IoTHub_Authorization_07_020: [ If any error is encountered IoTHubClient_Auth_Get_ConnString shall return NULL. ] */ LogError("Failed copying result"); result = NULL; } STRING_delete(sas_token); } } } } return result; }