static STRING_HANDLE create_devices_path(STRING_HANDLE iothub_host_fqdn, const char* device_id)
{
    STRING_HANDLE devices_path;
    if ((devices_path = STRING_construct_sprintf(IOTHUB_DEVICES_PATH_FMT, STRING_c_str(iothub_host_fqdn), device_id)) == NULL)
    {
        LogError("Failed creating devices_path (STRING_new failed)");
    }
    return devices_path;
}
static STRING_HANDLE createRelativePath(IOTHUB_DEVICEMETHOD_REQUEST_MODE iotHubDeviceMethodRequestMode, const char* deviceId)
{
    STRING_HANDLE result;

    if (iotHubDeviceMethodRequestMode == IOTHUB_DEVICEMETHOD_REQUEST_INVOKE)
    {
        result = STRING_construct_sprintf(RELATIVE_PATH_FMT_DEVICEMETHOD, deviceId, URL_API_VERSION);
    }
    else
    {
        result = NULL;
    }
    return result;
}
static STRING_HANDLE create_registration_path(const char* path_format, const char* id)
{
    STRING_HANDLE registration_path;

    if (id == NULL)
    {
        registration_path = STRING_construct(path_format);
    }
    else
    {
        STRING_HANDLE encoded_id;
        if ((encoded_id = URL_EncodeString(id)) == NULL)
        {
            LogError("Unable to URL encode ID");
            registration_path = NULL;
        }
        else
        {
            registration_path = STRING_construct_sprintf(path_format, STRING_c_str(encoded_id));
            STRING_delete(encoded_id);
        }
    }

    if (registration_path == NULL)
    {
        LogError("Failed constructing base path");
    }
    else if (STRING_sprintf(registration_path, API_VERSION_QUERY_PARAM, PROVISIONING_SERVICE_API_VERSION) != 0)
    {
        LogError("Unable to add query paramters");
        STRING_delete(registration_path);
        registration_path = NULL;
    }

    return registration_path;
}
static BUFFER_HANDLE createMethodPayloadJson(const char* methodName, unsigned int timeout, const char* payload)
{
    STRING_HANDLE stringHandle;
    const char* stringHandle_c_str;
    BUFFER_HANDLE result;

    if ((stringHandle = STRING_construct_sprintf(RELATIVE_PATH_FMT_DEVIECMETHOD_PAYLOAD, methodName, timeout, payload)) == NULL)
    {
        LogError("STRING_construct_sprintf failed");
        result = NULL;
    }
    else if ((stringHandle_c_str = STRING_c_str(stringHandle)) == NULL)
    {
        LogError("STRING_c_str failed");
        STRING_delete(stringHandle);
        result = NULL;
    }
    else
    {
        result = BUFFER_create((const unsigned char*)stringHandle_c_str, strlen(stringHandle_c_str));
        STRING_delete(stringHandle);
    }
    return result;
}
char* prov_auth_construct_sas_token(PROV_AUTH_HANDLE handle, const char* token_scope, const char* key_name, size_t expiry_time)
{
    char* result;
    char expire_token[64] = { 0 };

    if (handle == NULL || token_scope == NULL || key_name == NULL)
    {
        LogError("Invalid handle parameter handle: %p, token_scope: %p, key_name: %p", handle, token_scope, key_name);
        result = NULL;
    }
    else if (handle->sec_type == PROV_AUTH_TYPE_X509)
    {
        LogError("Invalid type for operation");
        result = NULL;
    }
    else if (size_tToString(expire_token, sizeof(expire_token), expiry_time) != 0)
    {
        result = NULL;
        LogError("Failure creating expire token");
    }
    else
    {
        size_t len = strlen(token_scope) + strlen(expire_token) + 3;
        char* payload = malloc(len + 1);
        if (payload == NULL)
        {
            result = NULL;
            LogError("Failure allocating payload for sas token.");
        }
        else
        {
            unsigned char* data_value;
            size_t data_len;
            (void)sprintf(payload, "%s\n%s", token_scope, expire_token);

            /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_031: [ prov_auth_get_certificate shall import the specified cert into the client using hsm_client_get_cert secure enclave function. ] */
            if (sign_sas_data(handle, payload, &data_value, &data_len) == 0)
            {
                STRING_HANDLE urlEncodedSignature;
                STRING_HANDLE base64Signature;
                STRING_HANDLE sas_token_handle;
                if ((base64Signature = Azure_Base64_Encode_Bytes(data_value, data_len)) == NULL)
                {
                    result = NULL;
                    LogError("Failure constructing base64 encoding.");
                }
                else if ((urlEncodedSignature = URL_Encode(base64Signature)) == NULL)
                {
                    result = NULL;
                    LogError("Failure constructing url Signature.");
                    STRING_delete(base64Signature);
                }
                else
                {
                    sas_token_handle = STRING_construct_sprintf("SharedAccessSignature sr=%s&sig=%s&se=%s&skn=%s", token_scope, STRING_c_str(urlEncodedSignature), expire_token, key_name);
                    if (sas_token_handle == NULL)
                    {
                        result = NULL;
                        LogError("Failure constructing url Signature.");
                    }
                    else
                    {
                        const char* temp_sas_token = STRING_c_str(sas_token_handle);
                        if (mallocAndStrcpy_s(&result, temp_sas_token) != 0)
                        {
                            LogError("Failure allocating and copying string.");
                            result = NULL;
                        }
                        STRING_delete(sas_token_handle);
                    }
                    STRING_delete(base64Signature);
                    STRING_delete(urlEncodedSignature);
                }
                free(data_value);
            }
            else
            {
                result = NULL;
                LogError("Failure generate sas token.");
            }
            free(payload);
        }
    }
    return result;
}