Microsoft Azure IoTHub client libraries

Dependents:   sht15_remote_monitoring RobotArmDemo iothub_client_sample_amqp f767zi_mqtt ... more

This library implements the Microsoft Azure IoTHub client library. The code is replicated from https://github.com/Azure/azure-iot-sdks

Revision:
75:86205ca63a59
Parent:
63:1bf1c2d60aab
Child:
76:943524fee0b7
--- a/iothub_client_authorization.c	Fri Aug 25 11:22:43 2017 -0700
+++ b/iothub_client_authorization.c	Mon Sep 11 09:22:55 2017 -0700
@@ -10,6 +10,11 @@
 #include "azure_c_shared_utility/xlogging.h"
 #include "azure_c_shared_utility/strings.h"
 #include "azure_c_shared_utility/sastoken.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+
+#ifdef USE_DPS_MODULE
+#include "azure_hub_modules/iothub_device_auth.h"
+#endif
 
 #include "iothub_client_authorization.h"
 
@@ -23,6 +28,9 @@
     char* device_id;
     size_t token_expiry_time_sec;
     IOTHUB_CREDENTIAL_TYPE cred_type;
+#ifdef USE_DPS_MODULE
+    IOTHUB_SECURITY_HANDLE device_auth_handle;
+#endif
 } IOTHUB_AUTHORIZATION_DATA;
 
 static int get_seconds_since_epoch(size_t* seconds)
@@ -32,7 +40,7 @@
     if ((current_time = get_time(NULL)) == INDEFINITE_TIME)
     {
         LogError("Failed getting the current local time (get_time() failed)");
-        result = __LINE__;
+        result = __FAILURE__;
     }
     else
     {
@@ -48,7 +56,7 @@
     /* Codes_SRS_IoTHub_Authorization_07_001: [if device_id is NULL IoTHubClient_Auth_Create, shall return NULL. ] */
     if (device_id == NULL)
     {
-        LogError("Invalid Parameter device_id: %p", device_key, device_id);
+        LogError("Invalid Parameter device_id: %p", device_id);
         result = NULL;
     }
     else
@@ -114,6 +122,60 @@
     return result;
 }
 
+IOTHUB_AUTHORIZATION_HANDLE IoTHubClient_Auth_CreateFromDeviceAuth(const char* device_id)
+{
+    IOTHUB_AUTHORIZATION_DATA* result;
+    if (device_id == NULL)
+    {
+        LogError("Invalid Parameter device_id: %p", device_id);
+        result = NULL;
+    }
+    else
+    {
+#ifdef USE_DPS_MODULE
+        result = (IOTHUB_AUTHORIZATION_DATA*)malloc(sizeof(IOTHUB_AUTHORIZATION_DATA));
+        if (result == NULL)
+        {
+            LogError("Failed allocating IOTHUB_AUTHORIZATION_DATA");
+            result = NULL;
+        }
+        else
+        {
+            memset(result, 0, sizeof(IOTHUB_AUTHORIZATION_DATA));
+
+            result->device_auth_handle = iothub_device_auth_create();
+            if (result->device_auth_handle == NULL)
+            {
+                LogError("Failed allocating IOTHUB_AUTHORIZATION_DATA");
+                free(result);
+                result = NULL;
+            }
+            else if (mallocAndStrcpy_s(&result->device_id, device_id) != 0)
+            {
+                LogError("Failed allocating device_key");
+                iothub_device_auth_destroy(result->device_auth_handle);
+                free(result);
+                result = NULL;
+            }
+            else
+            {
+                if (iothub_device_auth_get_auth_type(result->device_auth_handle) == AUTH_TYPE_SAS)
+                {
+                    result->cred_type = IOTHUB_CREDENTIAL_TYPE_DEVICE_AUTH;
+                }
+                else
+                {
+                    result->cred_type = IOTHUB_CREDENTIAL_TYPE_X509_ECC;
+                }
+            }
+        }
+#else
+        LogError("Failed DPS module is not supported");
+        result = NULL;
+#endif
+    }
+    return result;
+}
 
 void IoTHubClient_Auth_Destroy(IOTHUB_AUTHORIZATION_HANDLE handle)
 {
@@ -121,6 +183,9 @@
     if (handle != NULL)
     {
         /* Codes_SRS_IoTHub_Authorization_07_006: [ IoTHubClient_Auth_Destroy shall free all resources associated with the IOTHUB_AUTHORIZATION_HANDLE handle. ] */
+#ifdef USE_DPS_MODULE
+        iothub_device_auth_destroy(handle->device_auth_handle);
+#endif
         free(handle->device_key);
         free(handle->device_id);
         free(handle->device_sas_token);
@@ -160,6 +225,54 @@
     return result;
 }
 
+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_DPS_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 DPS module is not supported");
+        result = __FAILURE__;
+#endif
+    }
+    return result;
+}
+
 IOTHUB_CREDENTIAL_TYPE IoTHubClient_Auth_Get_Credential_Type(IOTHUB_AUTHORIZATION_HANDLE handle)
 {
     IOTHUB_CREDENTIAL_TYPE result;
@@ -188,57 +301,113 @@
     }
     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 (handle->cred_type == IOTHUB_CREDENTIAL_TYPE_DEVICE_AUTH)
         {
-            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;
+#ifdef USE_DPS_MODULE
+            DEVICE_AUTH_CREDENTIAL_INFO dev_auth_cred;
             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)
+                dev_auth_cred.sas_info.expiry_seconds = expiry_time;
+                dev_auth_cred.sas_info.token_scope = scope;
+                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)
                 {
-                    /* Codes_SRS_IoTHub_Authorization_07_020: [ If any error is encountered IoTHubClient_Auth_Get_ConnString shall return NULL. ] */
-                    LogError("Failed creating sas_token");
+                    LogError("failure getting credentials from device auth module");
                     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)
+                    if (mallocAndStrcpy_s(&result, cred_result->auth_cred_result.sas_result.sas_token) != 0)
+                    {
+                        LogError("failure allocating Sas Token");
+                        result = NULL;
+                    }
+                    free(cred_result->auth_cred_result.sas_result.sas_token);
+                    free(cred_result);
+                }
+            }
+#else
+            LogError("Failed DPS 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
+            {
+                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 copying result");
+                        LogError("Failed creating sas_token");
                         result = NULL;
                     }
-                    STRING_delete(sas_token);
+                    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;
 }