Azure IoT common library
Fork of azure_c_shared_utility by
sastoken.c@6:c55b013dfc2a, 2016-07-01 (annotated)
- Committer:
- Azure.IoT Build
- Date:
- Fri Jul 01 10:43:23 2016 -0700
- Revision:
- 6:c55b013dfc2a
- Parent:
- 1:9190c0f4d23a
- Child:
- 11:77df6d7e65ae
1.0.10
Who changed what in which revision?
User | Revision | Line number | New 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 | 6:c55b013dfc2a | 21 | #include "azure_c_shared_utility/xlogging.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 | { |
AzureIoTClient | 1:9190c0f4d23a | 35 | LogError("Invalid Parameter to SASToken_Create. handle key: %p, handle scope: %p, handle keyName: %p", 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.]*/ |
AzureIoTClient | 1:9190c0f4d23a | 44 | LogError("Unable to decode the key for generating the SAS."); |
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 | { |
AzureIoTClient | 1:9190c0f4d23a | 51 | LogError("For some reason converting seconds to a string failed. No SAS can be generated."); |
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 | { |
AzureIoTClient | 1:9190c0f4d23a | 61 | LogError("Unable to allocate memory to prepare SAS token."); |
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 | { |
AzureIoTClient | 1:9190c0f4d23a | 72 | LogError("Unable to build the input to the HMAC to prepare SAS token."); |
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 | { |
AzureIoTClient | 1:9190c0f4d23a | 105 | LogError("Unable to build the SAS token."); |
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 |