Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addressing the Y2k38 issue for SAS tokens #1807

Merged
merged 6 commits into from
Dec 23, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions iothub_client/devdoc/requirement_docs/iothub_authorization.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ DEFINE_ENUM(IOTHUB_CREDENTIAL_TYPE, IOTHUB_CREDENTIAL_TYPE_VALUES);
MOCKABLE_FUNCTION(, IOTHUB_AUTHORIZATION_HANDLE, IoTHubClient_Auth_Create, const char*, device_key, const char*, device_id, const char*, device_sas_token);
MOCKABLE_FUNCTION(, void, IoTHubClient_Auth_Destroy, IOTHUB_AUTHORIZATION_HANDLE, handle);
MOCKABLE_FUNCTION(, IOTHUB_CREDENTIAL_TYPE, IoTHubClient_Auth_Get_Credential_Type, IOTHUB_AUTHORIZATION_HANDLE, handle);
MOCKABLE_FUNCTION(, char*, IoTHubClient_Auth_Get_SasToken, IOTHUB_AUTHORIZATION_HANDLE, handle, const char*, scope, size_t, expiry_time_relative_seconds);
MOCKABLE_FUNCTION(, char*, IoTHubClient_Auth_Get_SasToken, IOTHUB_AUTHORIZATION_HANDLE, handle, const char*, scope, uint64_t, expiry_time_relative_seconds);
MOCKABLE_FUNCTION(, const char*, IoTHubClient_Auth_Get_DeviceId, IOTHUB_AUTHORIZATION_HANDLE, handle);
MOCKABLE_FUNCTION(, const char*, IoTHubClient_Auth_Get_ModuleId, IOTHUB_AUTHORIZATION_HANDLE, handle);
MOCKABLE_FUNCTION(, bool, IoTHubClient_Auth_Is_SasToken_Valid, IOTHUB_AUTHORIZATION_HANDLE, handle);
Expand Down Expand Up @@ -69,7 +69,7 @@ extern IOTHUB_CREDENTIAL_TYPE IoTHub_Auth_Get_Credential_Type(IOTHUB_AUTHORIZATI
## IoTHubClient_Auth_Get_SasToken

```c
extern char* IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const char* scope, size_t expiry_time_relative_seconds);
extern char* IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const char* scope, uint64_t expiry_time_relative_seconds);
```

**SRS_IoTHub_Authorization_07_009: [** if `handle` or `scope` are NULL, `IoTHubClient_Auth_Get_SasToken` shall return NULL. **]**
Expand Down
6 changes: 3 additions & 3 deletions iothub_client/inc/internal/iothub_client_authorization.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ MOCKABLE_FUNCTION(, IOTHUB_AUTHORIZATION_HANDLE, IoTHubClient_Auth_CreateFromDev
MOCKABLE_FUNCTION(, void, IoTHubClient_Auth_Destroy, IOTHUB_AUTHORIZATION_HANDLE, handle);
MOCKABLE_FUNCTION(, IOTHUB_CREDENTIAL_TYPE, IoTHubClient_Auth_Set_x509_Type, IOTHUB_AUTHORIZATION_HANDLE, handle, bool, enable_x509);
MOCKABLE_FUNCTION(, IOTHUB_CREDENTIAL_TYPE, IoTHubClient_Auth_Get_Credential_Type, IOTHUB_AUTHORIZATION_HANDLE, handle);
MOCKABLE_FUNCTION(, char*, IoTHubClient_Auth_Get_SasToken, IOTHUB_AUTHORIZATION_HANDLE, handle, const char*, scope, size_t, expiry_time_relative_seconds, const char*, key_name);
MOCKABLE_FUNCTION(, char*, IoTHubClient_Auth_Get_SasToken, IOTHUB_AUTHORIZATION_HANDLE, handle, const char*, scope, uint64_t, expiry_time_relative_seconds, const char*, key_name);
MOCKABLE_FUNCTION(, int, IoTHubClient_Auth_Set_xio_Certificate, IOTHUB_AUTHORIZATION_HANDLE, handle, XIO_HANDLE, xio);
MOCKABLE_FUNCTION(, const char*, IoTHubClient_Auth_Get_DeviceId, IOTHUB_AUTHORIZATION_HANDLE, handle);
MOCKABLE_FUNCTION(, const char*, IoTHubClient_Auth_Get_ModuleId, IOTHUB_AUTHORIZATION_HANDLE, handle);
MOCKABLE_FUNCTION(, const char*, IoTHubClient_Auth_Get_DeviceKey, IOTHUB_AUTHORIZATION_HANDLE, handle);
MOCKABLE_FUNCTION(, SAS_TOKEN_STATUS, IoTHubClient_Auth_Is_SasToken_Valid, IOTHUB_AUTHORIZATION_HANDLE, handle);
MOCKABLE_FUNCTION(, int, IoTHubClient_Auth_Get_x509_info, IOTHUB_AUTHORIZATION_HANDLE, handle, char**, x509_cert, char**, x509_key);
MOCKABLE_FUNCTION(, int, IoTHubClient_Auth_Set_SasToken_Expiry, IOTHUB_AUTHORIZATION_HANDLE, handle, size_t, expiry_time_seconds);
MOCKABLE_FUNCTION(, size_t, IoTHubClient_Auth_Get_SasToken_Expiry, IOTHUB_AUTHORIZATION_HANDLE, handle);
MOCKABLE_FUNCTION(, int, IoTHubClient_Auth_Set_SasToken_Expiry, IOTHUB_AUTHORIZATION_HANDLE, handle, uint64_t, expiry_time_seconds);
MOCKABLE_FUNCTION(, uint64_t, IoTHubClient_Auth_Get_SasToken_Expiry, IOTHUB_AUTHORIZATION_HANDLE, handle);


#ifdef USE_EDGE_MODULES
Expand Down
22 changes: 11 additions & 11 deletions iothub_client/src/iothub_client_authorization.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ typedef struct IOTHUB_AUTHORIZATION_DATA_TAG
char* device_key;
char* device_id;
char* module_id;
size_t token_expiry_time_sec;
uint64_t token_expiry_time_sec;
IOTHUB_CREDENTIAL_TYPE cred_type;
#ifdef USE_PROV_MODULE
IOTHUB_SECURITY_HANDLE device_auth_handle;
#endif
} IOTHUB_AUTHORIZATION_DATA;

static int get_seconds_since_epoch(size_t* seconds)
static int get_seconds_since_epoch(uint64_t* seconds)
{
int result;
time_t current_time;
Expand All @@ -48,7 +48,7 @@ static int get_seconds_since_epoch(size_t* seconds)
}
else
{
*seconds = (size_t)get_difftime(current_time, (time_t)0);
*seconds = (uint64_t)get_difftime(current_time, (time_t)0);
result = 0;
}
return result;
Expand Down Expand Up @@ -383,7 +383,7 @@ IOTHUB_CREDENTIAL_TYPE IoTHubClient_Auth_Get_Credential_Type(IOTHUB_AUTHORIZATIO
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* IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const char* scope, uint64_t expiry_time_relative_seconds, const char* key_name)
{
char* result;
(void)expiry_time_relative_seconds;
Expand All @@ -399,7 +399,7 @@ char* IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const c
{
#ifdef USE_PROV_MODULE
DEVICE_AUTH_CREDENTIAL_INFO dev_auth_cred;
size_t sec_since_epoch;
uint64_t sec_since_epoch;

if (get_seconds_since_epoch(&sec_since_epoch) != 0)
{
Expand All @@ -409,7 +409,7 @@ char* IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const c
else
{
memset(&dev_auth_cred, 0, sizeof(DEVICE_AUTH_CREDENTIAL_INFO));
size_t expiry_time = sec_since_epoch + handle->token_expiry_time_sec;
uint64_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;
Expand Down Expand Up @@ -464,7 +464,7 @@ char* IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const c
else
{
STRING_HANDLE sas_token;
size_t sec_since_epoch;
uint64_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)
Expand All @@ -476,7 +476,7 @@ char* IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const c
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;
uint64_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. ] */
Expand Down Expand Up @@ -690,7 +690,7 @@ char* IoTHubClient_Auth_Get_TrustBundle(IOTHUB_AUTHORIZATION_HANDLE handle, cons
}
#endif

int IoTHubClient_Auth_Set_SasToken_Expiry(IOTHUB_AUTHORIZATION_HANDLE handle, size_t expiry_time_seconds)
int IoTHubClient_Auth_Set_SasToken_Expiry(IOTHUB_AUTHORIZATION_HANDLE handle, uint64_t expiry_time_seconds)
{
int result;
if (handle == NULL)
Expand All @@ -712,9 +712,9 @@ int IoTHubClient_Auth_Set_SasToken_Expiry(IOTHUB_AUTHORIZATION_HANDLE handle, si
return result;
}

size_t IoTHubClient_Auth_Get_SasToken_Expiry(IOTHUB_AUTHORIZATION_HANDLE handle)
uint64_t IoTHubClient_Auth_Get_SasToken_Expiry(IOTHUB_AUTHORIZATION_HANDLE handle)
{
size_t result;
uint64_t result;
if (handle == NULL)
{
LogError("Invalid handle value handle: NULL");
Expand Down
3 changes: 2 additions & 1 deletion iothub_client/src/iothub_client_core_ll.c
Original file line number Diff line number Diff line change
Expand Up @@ -2347,7 +2347,8 @@ IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetOption(IOTHUB_CLIENT_CORE_LL_HANDLE
// if this becomes necessary
else if (strcmp(optionName, OPTION_SAS_TOKEN_REFRESH_TIME) == 0 || strcmp(optionName, OPTION_SAS_TOKEN_LIFETIME) == 0)
{
if (IoTHubClient_Auth_Set_SasToken_Expiry(handleData->authorization_module, *(size_t*)value) != 0)
// API compat: while IoTHubClient_Auth_Set_SasToken_Expiry accepts uint64_t, we cannot change the public API.
if (IoTHubClient_Auth_Set_SasToken_Expiry(handleData->authorization_module, (uint64_t)(*(size_t*)value)) != 0)
{
LogError("Failed setting the Token Expiry time");
result = IOTHUB_CLIENT_ERROR;
Expand Down
2 changes: 1 addition & 1 deletion iothub_client/src/iothub_client_ll_uploadtoblob.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ static int IoTHubClient_LL_UploadToBlob_step1and2(IOTHUB_CLIENT_LL_UPLOADTOBLOB_
}
else
{
size_t expiry = (size_t)(difftime(curr_time, 0) + 3600);
uint64_t expiry = (uint64_t)(difftime(curr_time, 0) + 3600);
char* sas_token = IoTHubClient_Auth_Get_SasToken(upload_data->authorization_module, STRING_c_str(uri_resource), expiry, EMPTY_STRING);
if (sas_token == NULL)
{
Expand Down
8 changes: 4 additions & 4 deletions iothub_client/src/iothubtransport_amqp_cbs_auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ typedef struct AUTHENTICATION_INSTANCE_TAG
ON_AUTHENTICATION_ERROR_CALLBACK on_error_callback;
void* on_error_callback_context;

size_t cbs_request_timeout_secs;
uint64_t cbs_request_timeout_secs;

AUTHENTICATION_STATE state;
CBS_HANDLE cbs_handle;
Expand Down Expand Up @@ -88,7 +88,7 @@ static int verify_cbs_put_token_timeout(AUTHENTICATION_INSTANCE* instance, bool*
LogError("Failed verifying if cbs_put_token has timed out (get_time failed)");
}
// Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_083: [authentication_do_work() shall check for authentication timeout comparing the current time since `instance->current_sas_token_put_time` to `instance->cbs_request_timeout_secs`]
else if ((uint32_t)get_difftime(current_time, instance->current_sas_token_put_time) >= instance->cbs_request_timeout_secs)
else if ((uint64_t)get_difftime(current_time, instance->current_sas_token_put_time) >= instance->cbs_request_timeout_secs)
{
*is_timed_out = true;
result = RESULT_OK;
Expand All @@ -106,7 +106,7 @@ static int verify_cbs_put_token_timeout(AUTHENTICATION_INSTANCE* instance, bool*
static int verify_sas_token_refresh_timeout(AUTHENTICATION_INSTANCE* instance, bool* is_timed_out)
{
int result;
size_t sas_token_expiry;
uint64_t sas_token_expiry;

if (instance->current_sas_token_put_time == INDEFINITE_TIME)
{
Expand All @@ -126,7 +126,7 @@ static int verify_sas_token_refresh_timeout(AUTHENTICATION_INSTANCE* instance, b
result = MU_FAILURE;
LogError("Failed verifying if SAS token refresh timed out (get_time failed)");
}
else if ((uint32_t)get_difftime(current_time, instance->current_sas_token_put_time) >= (sas_token_expiry*SAS_REFRESH_MULTIPLIER))
else if ((uint64_t)get_difftime(current_time, instance->current_sas_token_put_time) >= (sas_token_expiry*SAS_REFRESH_MULTIPLIER))
{
*is_timed_out = true;
result = RESULT_OK;
Expand Down
2 changes: 1 addition & 1 deletion iothub_client/src/iothubtransport_mqtt_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -2641,7 +2641,7 @@ static int UpdateMqttConnectionStateIfNeeded(PMQTTTRANSPORT_HANDLE_DATA transpor
// If the credential type is not an x509 certificate then we shall renew the Sas_Token
if (cred_type != IOTHUB_CREDENTIAL_TYPE_X509 && cred_type != IOTHUB_CREDENTIAL_TYPE_X509_ECC)
{
size_t sas_token_expiry = IoTHubClient_Auth_Get_SasToken_Expiry(transport_data->authorization_module);
uint64_t sas_token_expiry = IoTHubClient_Auth_Get_SasToken_Expiry(transport_data->authorization_module);
if ((current_time - transport_data->mqtt_connect_time) / 1000 > (sas_token_expiry*SAS_REFRESH_MULTIPLIER))
{
/* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_07_058: [ If the sas token has timed out IoTHubTransport_MQTT_Common_DoWork shall disconnect from the mqtt client and destroy the transport information and wait for reconnect. ] */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#ifdef __cplusplus
#include <stdlib.h>
#include <cstdlib>
#include <cstdint>
#else
#include <stdlib.h>
#include <stdint.h>
#endif

static void* my_gballoc_malloc(size_t size)
Expand All @@ -20,6 +22,7 @@ static void my_gballoc_free(void* ptr)
#include "testrunnerswitcher.h"
#include "umock_c/umock_c.h"
#include "umock_c/umocktypes_charptr.h"
#include "umock_c/umocktypes_stdint.h"
#include "umock_c/umock_c_negative_tests.h"
#include "azure_macro_utils/macro_utils.h"

Expand Down Expand Up @@ -51,7 +54,7 @@ static const char* TEST_STRING_VALUE = "Test_string_value";
static const char* TEST_KEYNAME_VALUE = "Test_keyname_value";
static const char* TEST_REG_CERT = "Test_certificate";
static const char* TEST_REG_PK = "Test_private_key";
static size_t TEST_EXPIRY_TIME = 1;
static uint64_t TEST_EXPIRY_TIME = 1;

#define TEST_TIME_VALUE (time_t)123456

Expand All @@ -72,7 +75,7 @@ static int my_mallocAndStrcpy_s(char** destination, const char* source)
return 0;
}

static STRING_HANDLE my_SASToken_CreateString(const char* key, const char* scope, const char* keyName, size_t expiry)
static STRING_HANDLE my_SASToken_CreateString(const char* key, const char* scope, const char* keyName, uint64_t expiry)
{
(void)key;
(void)scope;
Expand Down Expand Up @@ -135,6 +138,9 @@ TEST_SUITE_INITIALIZE(suite_init)

(void)umock_c_init(on_umock_c_error);

result = umocktypes_stdint_register_types();
ASSERT_ARE_EQUAL(int, 0, result, "umocktypes_stdint_register_types");

result = umocktypes_charptr_register_types();
ASSERT_ARE_EQUAL(int, 0, result);

Expand Down Expand Up @@ -1023,7 +1029,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Set_SasToken_Expiry_handle_NULL_fail)

TEST_FUNCTION(IoTHubClient_Auth_Set_SasToken_Expiry_succeed)
{
size_t expiry_time = 4800;
uint64_t expiry_time = 4800;

//arrange
IOTHUB_AUTHORIZATION_HANDLE handle = IoTHubClient_Auth_Create(NULL, DEVICE_ID, TEST_SAS_TOKEN, NULL);
Expand All @@ -1034,7 +1040,7 @@ TEST_FUNCTION(IoTHubClient_Auth_Set_SasToken_Expiry_succeed)

//assert
ASSERT_ARE_EQUAL(int, 0, result);
ASSERT_ARE_EQUAL(size_t, expiry_time, IoTHubClient_Auth_Get_SasToken_Expiry(handle), "Sas Token Expiry time not set correctly");
ASSERT_ARE_EQUAL(uint64_t, expiry_time, IoTHubClient_Auth_Get_SasToken_Expiry(handle), "Sas Token Expiry time not set correctly");
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());

//cleanup
Expand All @@ -1046,29 +1052,29 @@ TEST_FUNCTION(IoTHubClient_Auth_Get_SasToken_Expiry_handle_NULL_fail)
//arrange

//act
size_t result = IoTHubClient_Auth_Get_SasToken_Expiry(NULL);
uint64_t result = IoTHubClient_Auth_Get_SasToken_Expiry(NULL);

//assert
ASSERT_ARE_EQUAL(size_t, 0, result);
ASSERT_ARE_EQUAL(uint64_t, 0, result);
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());

//cleanup
}

TEST_FUNCTION(IoTHubClient_Auth_Get_SasToken_Expiry_succeed)
{
size_t expiry_time = 4800;
uint64_t expiry_time = 4800;

//arrange
IOTHUB_AUTHORIZATION_HANDLE handle = IoTHubClient_Auth_Create(NULL, DEVICE_ID, TEST_SAS_TOKEN, NULL);
(void)IoTHubClient_Auth_Set_SasToken_Expiry(handle, expiry_time);
umock_c_reset_all_calls();

//act
size_t result = IoTHubClient_Auth_Get_SasToken_Expiry(handle);
uint64_t result = IoTHubClient_Auth_Get_SasToken_Expiry(handle);

//assert
ASSERT_ARE_EQUAL(size_t, expiry_time, result);
ASSERT_ARE_EQUAL(uint64_t, expiry_time, result);
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());

//cleanup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ static char* my_json_serialize_to_string(const JSON_Value* value)
return newstr;
}

static char* my_IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const char* scope, size_t expiry_time_relative_seconds, const char* key_name)
static char* my_IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const char* scope, uint64_t expiry_time_relative_seconds, const char* key_name)
{
(void)handle;
(void)expiry_time_relative_seconds;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ static void* my_gballoc_calloc(size_t nmemb, size_t size)
#include "azure_macro_utils/macro_utils.h"
#include "umock_c/umock_c.h"
#include "umock_c/umocktypes_charptr.h"
#include "umock_c/umocktypes_stdint.h"
#include "umock_c/umock_c_negative_tests.h"
#include "umock_c/umocktypes.h"
#include "umock_c/umocktypes_c.h"
Expand Down Expand Up @@ -270,7 +271,7 @@ static int my_mallocAndStrcpy_s(char** destination, const char* source)
return 0;
}

static char* my_IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const char* scope, size_t expiry_time_relative_seconds, const char* key_name)
static char* my_IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const char* scope, uint64_t expiry_time_relative_seconds, const char* key_name)
{
(void)handle;
(void)scope;
Expand Down Expand Up @@ -475,6 +476,9 @@ TEST_SUITE_INITIALIZE(TestClassInitialize)

umock_c_init(on_umock_c_error);

int result = umocktypes_stdint_register_types();
ASSERT_ARE_EQUAL(int, 0, result, "umocktypes_stdint_register_types");

umocktypes_charptr_register_types();

REGISTER_TYPE(HTTPAPI_RESULT, HTTPAPI_RESULT);
Expand Down
Loading