Azure IoT common library

Dependents:   STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more

Committer:
Azure.IoT Build
Date:
Fri Apr 08 12:01:36 2016 -0700
Revision:
0:fa2de1b79154
Child:
1:9190c0f4d23a
1.0.4

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Azure.IoT Build 0:fa2de1b79154 1 // Copyright (c) Microsoft. All rights reserved.
Azure.IoT Build 0:fa2de1b79154 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
Azure.IoT Build 0:fa2de1b79154 3
Azure.IoT Build 0:fa2de1b79154 4 #include <stdlib.h>
Azure.IoT Build 0:fa2de1b79154 5 #ifdef _CRTDBG_MAP_ALLOC
Azure.IoT Build 0:fa2de1b79154 6 #include <crtdbg.h>
Azure.IoT Build 0:fa2de1b79154 7 #endif
Azure.IoT Build 0:fa2de1b79154 8 #include "azure_c_shared_utility/gballoc.h"
Azure.IoT Build 0:fa2de1b79154 9
Azure.IoT Build 0:fa2de1b79154 10 #include <time.h>
Azure.IoT Build 0:fa2de1b79154 11 #include <stddef.h>
Azure.IoT Build 0:fa2de1b79154 12
Azure.IoT Build 0:fa2de1b79154 13 #include "azure_c_shared_utility/crt_abstractions.h"
Azure.IoT Build 0:fa2de1b79154 14 #include "azure_c_shared_utility/sastoken.h"
Azure.IoT Build 0:fa2de1b79154 15 #include "azure_c_shared_utility/urlencode.h"
Azure.IoT Build 0:fa2de1b79154 16 #include "azure_c_shared_utility/hmacsha256.h"
Azure.IoT Build 0:fa2de1b79154 17 #include "azure_c_shared_utility/base64.h"
Azure.IoT Build 0:fa2de1b79154 18 #include "azure_c_shared_utility/agenttime.h"
Azure.IoT Build 0:fa2de1b79154 19 #include "azure_c_shared_utility/strings.h"
Azure.IoT Build 0:fa2de1b79154 20 #include "azure_c_shared_utility/buffer_.h"
Azure.IoT Build 0:fa2de1b79154 21 #include "azure_c_shared_utility/iot_logging.h"
Azure.IoT Build 0:fa2de1b79154 22
Azure.IoT Build 0:fa2de1b79154 23 STRING_HANDLE SASToken_Create(STRING_HANDLE key, STRING_HANDLE scope, STRING_HANDLE keyName, size_t expiry)
Azure.IoT Build 0:fa2de1b79154 24 {
Azure.IoT Build 0:fa2de1b79154 25 STRING_HANDLE result = NULL;
Azure.IoT Build 0:fa2de1b79154 26 char tokenExpirationTime[32] = { 0 };
Azure.IoT Build 0:fa2de1b79154 27
Azure.IoT Build 0:fa2de1b79154 28 /*Codes_SRS_SASTOKEN_06_001: [If key is NULL then SASToken_Create shall return NULL.]*/
Azure.IoT Build 0:fa2de1b79154 29 /*Codes_SRS_SASTOKEN_06_003: [If scope is NULL then SASToken_Create shall return NULL.]*/
Azure.IoT Build 0:fa2de1b79154 30 /*Codes_SRS_SASTOKEN_06_007: [If keyName is NULL then SASToken_Create shall return NULL.]*/
Azure.IoT Build 0:fa2de1b79154 31 if ((key == NULL) ||
Azure.IoT Build 0:fa2de1b79154 32 (scope == NULL) ||
Azure.IoT Build 0:fa2de1b79154 33 (keyName == NULL))
Azure.IoT Build 0:fa2de1b79154 34 {
Azure.IoT Build 0:fa2de1b79154 35 LogError("Invalid Parameter to SASToken_Create. handle key: %p, handle scope: %p, handle keyName: %p\r\n", key, scope, keyName);
Azure.IoT Build 0:fa2de1b79154 36 }
Azure.IoT Build 0:fa2de1b79154 37 else
Azure.IoT Build 0:fa2de1b79154 38 {
Azure.IoT Build 0:fa2de1b79154 39 BUFFER_HANDLE decodedKey;
Azure.IoT Build 0:fa2de1b79154 40 /*Codes_SRS_SASTOKEN_06_029: [The key parameter is decoded from base64.]*/
Azure.IoT Build 0:fa2de1b79154 41 if ((decodedKey = Base64_Decoder(STRING_c_str(key))) == NULL)
Azure.IoT Build 0:fa2de1b79154 42 {
Azure.IoT Build 0:fa2de1b79154 43 /*Codes_SRS_SASTOKEN_06_030: [If there is an error in the decoding then SASToken_Create shall return NULL.]*/
Azure.IoT Build 0:fa2de1b79154 44 LogError("Unable to decode the key for generating the SAS.\r\n");
Azure.IoT Build 0:fa2de1b79154 45 }
Azure.IoT Build 0:fa2de1b79154 46 else
Azure.IoT Build 0:fa2de1b79154 47 {
Azure.IoT Build 0:fa2de1b79154 48 /*Codes_SRS_SASTOKEN_06_026: [If the conversion to string form fails for any reason then SASToken_Create shall return NULL.]*/
Azure.IoT Build 0:fa2de1b79154 49 if (size_tToString(tokenExpirationTime, sizeof(tokenExpirationTime), expiry) != 0)
Azure.IoT Build 0:fa2de1b79154 50 {
Azure.IoT Build 0:fa2de1b79154 51 LogError("For some reason converting seconds to a string failed. No SAS can be generated.\r\n");
Azure.IoT Build 0:fa2de1b79154 52 }
Azure.IoT Build 0:fa2de1b79154 53 else
Azure.IoT Build 0:fa2de1b79154 54 {
Azure.IoT Build 0:fa2de1b79154 55 STRING_HANDLE toBeHashed = NULL;
Azure.IoT Build 0:fa2de1b79154 56 BUFFER_HANDLE hash = NULL;
Azure.IoT Build 0:fa2de1b79154 57 if (((hash = BUFFER_new()) == NULL) ||
Azure.IoT Build 0:fa2de1b79154 58 ((toBeHashed = STRING_new()) == NULL) ||
Azure.IoT Build 0:fa2de1b79154 59 ((result = STRING_new()) == NULL))
Azure.IoT Build 0:fa2de1b79154 60 {
Azure.IoT Build 0:fa2de1b79154 61 LogError("Unable to allocate memory to prepare SAS token.\r\n");
Azure.IoT Build 0:fa2de1b79154 62 }
Azure.IoT Build 0:fa2de1b79154 63 else
Azure.IoT Build 0:fa2de1b79154 64 {
Azure.IoT Build 0:fa2de1b79154 65 /*Codes_SRS_SASTOKEN_06_009: [The scope is the basis for creating a STRING_HANDLE.]*/
Azure.IoT Build 0:fa2de1b79154 66 /*Codes_SRS_SASTOKEN_06_010: [A "\n" is appended to that string.]*/
Azure.IoT Build 0:fa2de1b79154 67 /*Codes_SRS_SASTOKEN_06_011: [tokenExpirationTime is appended to that string.]*/
Azure.IoT Build 0:fa2de1b79154 68 if ((STRING_concat_with_STRING(toBeHashed, scope) != 0) ||
Azure.IoT Build 0:fa2de1b79154 69 (STRING_concat(toBeHashed, "\n") != 0) ||
Azure.IoT Build 0:fa2de1b79154 70 (STRING_concat(toBeHashed, tokenExpirationTime) != 0))
Azure.IoT Build 0:fa2de1b79154 71 {
Azure.IoT Build 0:fa2de1b79154 72 LogError("Unable to build the input to the HMAC to prepare SAS token.\r\n");
Azure.IoT Build 0:fa2de1b79154 73 STRING_delete(result);
Azure.IoT Build 0:fa2de1b79154 74 result = NULL;
Azure.IoT Build 0:fa2de1b79154 75 }
Azure.IoT Build 0:fa2de1b79154 76 else
Azure.IoT Build 0:fa2de1b79154 77 {
Azure.IoT Build 0:fa2de1b79154 78 STRING_HANDLE base64Signature = NULL;
Azure.IoT Build 0:fa2de1b79154 79 STRING_HANDLE urlEncodedSignature = NULL;
Azure.IoT Build 0:fa2de1b79154 80 /*Codes_SRS_SASTOKEN_06_013: [If an error is returned from the HMAC256 function then NULL is returned from SASToken_Create.]*/
Azure.IoT Build 0:fa2de1b79154 81 /*Codes_SRS_SASTOKEN_06_012: [An HMAC256 hash is calculated using the decodedKey, over toBeHashed.]*/
Azure.IoT Build 0:fa2de1b79154 82 /*Codes_SRS_SASTOKEN_06_014: [If there are any errors from the following operations then NULL shall be returned.]*/
Azure.IoT Build 0:fa2de1b79154 83 /*Codes_SRS_SASTOKEN_06_015: [The hash is base 64 encoded.]*/
Azure.IoT Build 0:fa2de1b79154 84 /*Codes_SRS_SASTOKEN_06_028: [base64Signature shall be url encoded.]*/
Azure.IoT Build 0:fa2de1b79154 85 /*Codes_SRS_SASTOKEN_06_016: [The string "SharedAccessSignature sr=" is the first part of the result of SASToken_Create.]*/
Azure.IoT Build 0:fa2de1b79154 86 /*Codes_SRS_SASTOKEN_06_017: [The scope parameter is appended to result.]*/
Azure.IoT Build 0:fa2de1b79154 87 /*Codes_SRS_SASTOKEN_06_018: [The string "&sig=" is appended to result.]*/
Azure.IoT Build 0:fa2de1b79154 88 /*Codes_SRS_SASTOKEN_06_019: [The string urlEncodedSignature shall be appended to result.]*/
Azure.IoT Build 0:fa2de1b79154 89 /*Codes_SRS_SASTOKEN_06_020: [The string "&se=" shall be appended to result.]*/
Azure.IoT Build 0:fa2de1b79154 90 /*Codes_SRS_SASTOKEN_06_021: [tokenExpirationTime is appended to result.]*/
Azure.IoT Build 0:fa2de1b79154 91 /*Codes_SRS_SASTOKEN_06_022: [The string "&skn=" is appended to result.]*/
Azure.IoT Build 0:fa2de1b79154 92 /*Codes_SRS_SASTOKEN_06_023: [The argument keyName is appended to result.]*/
Azure.IoT Build 0:fa2de1b79154 93 if ((HMACSHA256_ComputeHash(BUFFER_u_char(decodedKey), BUFFER_length(decodedKey), (const unsigned char*)STRING_c_str(toBeHashed), STRING_length(toBeHashed), hash) != HMACSHA256_OK) ||
Azure.IoT Build 0:fa2de1b79154 94 ((base64Signature = Base64_Encode(hash)) == NULL) ||
Azure.IoT Build 0:fa2de1b79154 95 ((urlEncodedSignature = URL_Encode(base64Signature)) == NULL) ||
Azure.IoT Build 0:fa2de1b79154 96 (STRING_copy(result, "SharedAccessSignature sr=") != 0) ||
Azure.IoT Build 0:fa2de1b79154 97 (STRING_concat_with_STRING(result, scope) != 0) ||
Azure.IoT Build 0:fa2de1b79154 98 (STRING_concat(result, "&sig=") != 0) ||
Azure.IoT Build 0:fa2de1b79154 99 (STRING_concat_with_STRING(result, urlEncodedSignature) != 0) ||
Azure.IoT Build 0:fa2de1b79154 100 (STRING_concat(result, "&se=") != 0) ||
Azure.IoT Build 0:fa2de1b79154 101 (STRING_concat(result, tokenExpirationTime) != 0) ||
Azure.IoT Build 0:fa2de1b79154 102 (STRING_concat(result, "&skn=") != 0) ||
Azure.IoT Build 0:fa2de1b79154 103 (STRING_concat_with_STRING(result, keyName) != 0))
Azure.IoT Build 0:fa2de1b79154 104 {
Azure.IoT Build 0:fa2de1b79154 105 LogError("Unable to build the SAS token.\r\n");
Azure.IoT Build 0:fa2de1b79154 106 STRING_delete(result);
Azure.IoT Build 0:fa2de1b79154 107 result = NULL;
Azure.IoT Build 0:fa2de1b79154 108 }
Azure.IoT Build 0:fa2de1b79154 109 else
Azure.IoT Build 0:fa2de1b79154 110 {
Azure.IoT Build 0:fa2de1b79154 111 /* everything OK */
Azure.IoT Build 0:fa2de1b79154 112 }
Azure.IoT Build 0:fa2de1b79154 113 STRING_delete(base64Signature);
Azure.IoT Build 0:fa2de1b79154 114 STRING_delete(urlEncodedSignature);
Azure.IoT Build 0:fa2de1b79154 115 }
Azure.IoT Build 0:fa2de1b79154 116 }
Azure.IoT Build 0:fa2de1b79154 117 STRING_delete(toBeHashed);
Azure.IoT Build 0:fa2de1b79154 118 BUFFER_delete(hash);
Azure.IoT Build 0:fa2de1b79154 119 }
Azure.IoT Build 0:fa2de1b79154 120 BUFFER_delete(decodedKey);
Azure.IoT Build 0:fa2de1b79154 121 }
Azure.IoT Build 0:fa2de1b79154 122 }
Azure.IoT Build 0:fa2de1b79154 123
Azure.IoT Build 0:fa2de1b79154 124 return result;
Azure.IoT Build 0:fa2de1b79154 125 }
Azure.IoT Build 0:fa2de1b79154 126