Azure IoT common library

Fork of azure_c_shared_utility by Azure IoT

Committer:
AzureIoTClient
Date:
Wed Nov 16 21:38:39 2016 -0800
Revision:
15:956c6d205aa7
Parent:
11:77df6d7e65ae
Child:
19:2e0811512ceb
1.0.10

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 #ifdef _CRTDBG_MAP_ALLOC
Azure.IoT Build 0:fa2de1b79154 5 #include <crtdbg.h>
Azure.IoT Build 0:fa2de1b79154 6 #endif
AzureIoTClient 15:956c6d205aa7 7
Azure.IoT Build 0:fa2de1b79154 8 #include "azure_c_shared_utility/gballoc.h"
Azure.IoT Build 0:fa2de1b79154 9 #include "azure_c_shared_utility/sastoken.h"
Azure.IoT Build 0:fa2de1b79154 10 #include "azure_c_shared_utility/urlencode.h"
Azure.IoT Build 0:fa2de1b79154 11 #include "azure_c_shared_utility/hmacsha256.h"
Azure.IoT Build 0:fa2de1b79154 12 #include "azure_c_shared_utility/base64.h"
Azure.IoT Build 0:fa2de1b79154 13 #include "azure_c_shared_utility/agenttime.h"
Azure.IoT Build 0:fa2de1b79154 14 #include "azure_c_shared_utility/strings.h"
Azure.IoT Build 0:fa2de1b79154 15 #include "azure_c_shared_utility/buffer_.h"
Azure.IoT Build 6:c55b013dfc2a 16 #include "azure_c_shared_utility/xlogging.h"
AzureIoTClient 15:956c6d205aa7 17 #include "azure_c_shared_utility/crt_abstractions.h"
AzureIoTClient 15:956c6d205aa7 18
AzureIoTClient 15:956c6d205aa7 19 static double getExpiryValue(const char* expiryASCII)
AzureIoTClient 15:956c6d205aa7 20 {
AzureIoTClient 15:956c6d205aa7 21 double value = 0;
AzureIoTClient 15:956c6d205aa7 22 size_t i = 0;
AzureIoTClient 15:956c6d205aa7 23 for (i = 0; expiryASCII[i] != '\0'; i++)
AzureIoTClient 15:956c6d205aa7 24 {
AzureIoTClient 15:956c6d205aa7 25 if (expiryASCII[i] >= '0' && expiryASCII[i] <= '9')
AzureIoTClient 15:956c6d205aa7 26 {
AzureIoTClient 15:956c6d205aa7 27 value = value * 10 + (expiryASCII[i] - '0');
AzureIoTClient 15:956c6d205aa7 28 }
AzureIoTClient 15:956c6d205aa7 29 else
AzureIoTClient 15:956c6d205aa7 30 {
AzureIoTClient 15:956c6d205aa7 31 value = 0;
AzureIoTClient 15:956c6d205aa7 32 break;
AzureIoTClient 15:956c6d205aa7 33 }
AzureIoTClient 15:956c6d205aa7 34 }
AzureIoTClient 15:956c6d205aa7 35 return value;
AzureIoTClient 15:956c6d205aa7 36 }
AzureIoTClient 15:956c6d205aa7 37
AzureIoTClient 15:956c6d205aa7 38 bool SASToken_Validate(STRING_HANDLE sasToken)
AzureIoTClient 15:956c6d205aa7 39 {
AzureIoTClient 15:956c6d205aa7 40 bool result;
AzureIoTClient 15:956c6d205aa7 41 /*Codes_SRS_SASTOKEN_25_025: [**SASToken_Validate shall get the SASToken value by invoking STRING_c_str on the handle.**]***/
AzureIoTClient 15:956c6d205aa7 42 const char* sasTokenArray = STRING_c_str(sasToken);
AzureIoTClient 15:956c6d205aa7 43
AzureIoTClient 15:956c6d205aa7 44 /***Codes_SRS_SASTOKEN_25_024: [**If handle is NULL then SASToken_Validate shall return false.**] ***/
AzureIoTClient 15:956c6d205aa7 45 /*Codes_SRS_SASTOKEN_25_026: [**If STRING_c_str on handle return NULL then SASToken_Validate shall return false.**]***/
AzureIoTClient 15:956c6d205aa7 46 if (sasToken == NULL || sasTokenArray == NULL)
AzureIoTClient 15:956c6d205aa7 47 {
AzureIoTClient 15:956c6d205aa7 48 result = false;
AzureIoTClient 15:956c6d205aa7 49 }
AzureIoTClient 15:956c6d205aa7 50 else
AzureIoTClient 15:956c6d205aa7 51 {
AzureIoTClient 15:956c6d205aa7 52 int seStart = -1, seStop = -1;
AzureIoTClient 15:956c6d205aa7 53 int srStart = -1, srStop = -1;
AzureIoTClient 15:956c6d205aa7 54 int sigStart = -1, sigStop = -1;
AzureIoTClient 15:956c6d205aa7 55 int tokenLength = (int) STRING_length(sasToken);
AzureIoTClient 15:956c6d205aa7 56 int i ;
AzureIoTClient 15:956c6d205aa7 57 for (i = 0; i < tokenLength; i++)
AzureIoTClient 15:956c6d205aa7 58 {
AzureIoTClient 15:956c6d205aa7 59 if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'e' && sasTokenArray[i + 2] == '=') // Look for se=
AzureIoTClient 15:956c6d205aa7 60 {
AzureIoTClient 15:956c6d205aa7 61 seStart = i + 3;
AzureIoTClient 15:956c6d205aa7 62 if (srStart > 0 && srStop < 0)
AzureIoTClient 15:956c6d205aa7 63 {
AzureIoTClient 15:956c6d205aa7 64 if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ') // look for either & or space
AzureIoTClient 15:956c6d205aa7 65 srStop = i - 1;
AzureIoTClient 15:956c6d205aa7 66 else if (sasTokenArray[i - 1] == '&')
AzureIoTClient 15:956c6d205aa7 67 srStop = i - 2;
AzureIoTClient 15:956c6d205aa7 68 else
AzureIoTClient 15:956c6d205aa7 69 seStart = -1; // as the format is not either "&se=" or " se="
AzureIoTClient 15:956c6d205aa7 70 }
AzureIoTClient 15:956c6d205aa7 71 else if (sigStart > 0 && sigStop < 0)
AzureIoTClient 15:956c6d205aa7 72 {
AzureIoTClient 15:956c6d205aa7 73 if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
AzureIoTClient 15:956c6d205aa7 74 sigStop = i - 1;
AzureIoTClient 15:956c6d205aa7 75 else if (sasTokenArray[i - 1] == '&')
AzureIoTClient 15:956c6d205aa7 76 sigStop = i - 2;
AzureIoTClient 15:956c6d205aa7 77 else
AzureIoTClient 15:956c6d205aa7 78 seStart = -1;
AzureIoTClient 15:956c6d205aa7 79 }
AzureIoTClient 15:956c6d205aa7 80 continue;
AzureIoTClient 15:956c6d205aa7 81 }
AzureIoTClient 15:956c6d205aa7 82 if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'r' && sasTokenArray[i + 2] == '=') // Look for sr=
AzureIoTClient 15:956c6d205aa7 83 {
AzureIoTClient 15:956c6d205aa7 84 srStart = i + 3;
AzureIoTClient 15:956c6d205aa7 85 if (seStart > 0 && seStop < 0)
AzureIoTClient 15:956c6d205aa7 86 {
AzureIoTClient 15:956c6d205aa7 87 if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
AzureIoTClient 15:956c6d205aa7 88 seStop = i - 1;
AzureIoTClient 15:956c6d205aa7 89 else if (sasTokenArray[i - 1] == '&')
AzureIoTClient 15:956c6d205aa7 90 seStop = i - 2;
AzureIoTClient 15:956c6d205aa7 91 else
AzureIoTClient 15:956c6d205aa7 92 srStart = -1;
AzureIoTClient 15:956c6d205aa7 93 }
AzureIoTClient 15:956c6d205aa7 94 else if (sigStart > 0 && sigStop < 0)
AzureIoTClient 15:956c6d205aa7 95 {
AzureIoTClient 15:956c6d205aa7 96 if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
AzureIoTClient 15:956c6d205aa7 97 sigStop = i - 1;
AzureIoTClient 15:956c6d205aa7 98 else if (sasTokenArray[i - 1] == '&')
AzureIoTClient 15:956c6d205aa7 99 sigStop = i - 2;
AzureIoTClient 15:956c6d205aa7 100 else
AzureIoTClient 15:956c6d205aa7 101 srStart = -1;
AzureIoTClient 15:956c6d205aa7 102 }
AzureIoTClient 15:956c6d205aa7 103 continue;
AzureIoTClient 15:956c6d205aa7 104 }
AzureIoTClient 15:956c6d205aa7 105 if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'i' && sasTokenArray[i + 2] == 'g' && sasTokenArray[i + 3] == '=') // Look for sig=
AzureIoTClient 15:956c6d205aa7 106 {
AzureIoTClient 15:956c6d205aa7 107 sigStart = i + 4;
AzureIoTClient 15:956c6d205aa7 108 if (srStart > 0 && srStop < 0)
AzureIoTClient 15:956c6d205aa7 109 {
AzureIoTClient 15:956c6d205aa7 110 if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
AzureIoTClient 15:956c6d205aa7 111 srStop = i - 1;
AzureIoTClient 15:956c6d205aa7 112 else if (sasTokenArray[i - 1] == '&')
AzureIoTClient 15:956c6d205aa7 113 srStop = i - 2;
AzureIoTClient 15:956c6d205aa7 114 else
AzureIoTClient 15:956c6d205aa7 115 sigStart = -1;
AzureIoTClient 15:956c6d205aa7 116 }
AzureIoTClient 15:956c6d205aa7 117 else if (seStart > 0 && seStop < 0)
AzureIoTClient 15:956c6d205aa7 118 {
AzureIoTClient 15:956c6d205aa7 119 if (sasTokenArray[i - 1] != '&' && sasTokenArray[i - 1] == ' ')
AzureIoTClient 15:956c6d205aa7 120 seStop = i - 1;
AzureIoTClient 15:956c6d205aa7 121 else if (sasTokenArray[i - 1] == '&')
AzureIoTClient 15:956c6d205aa7 122 seStop = i - 2;
AzureIoTClient 15:956c6d205aa7 123 else
AzureIoTClient 15:956c6d205aa7 124 sigStart = -1;
AzureIoTClient 15:956c6d205aa7 125 }
AzureIoTClient 15:956c6d205aa7 126 continue;
AzureIoTClient 15:956c6d205aa7 127 }
AzureIoTClient 15:956c6d205aa7 128 }
AzureIoTClient 15:956c6d205aa7 129 /*Codes_SRS_SASTOKEN_25_027: [**If SASTOKEN does not obey the SASToken format then SASToken_Validate shall return false.**]***/
AzureIoTClient 15:956c6d205aa7 130 /*Codes_SRS_SASTOKEN_25_028: [**SASToken_validate shall check for the presence of sr, se and sig from the token and return false if not found**]***/
AzureIoTClient 15:956c6d205aa7 131 if (seStart < 0 || srStart < 0 || sigStart < 0)
AzureIoTClient 15:956c6d205aa7 132 {
AzureIoTClient 15:956c6d205aa7 133 result = false;
AzureIoTClient 15:956c6d205aa7 134 }
AzureIoTClient 15:956c6d205aa7 135 else
AzureIoTClient 15:956c6d205aa7 136 {
AzureIoTClient 15:956c6d205aa7 137 if (seStop < 0)
AzureIoTClient 15:956c6d205aa7 138 {
AzureIoTClient 15:956c6d205aa7 139 seStop = tokenLength;
AzureIoTClient 15:956c6d205aa7 140 }
AzureIoTClient 15:956c6d205aa7 141 else if (srStop < 0)
AzureIoTClient 15:956c6d205aa7 142 {
AzureIoTClient 15:956c6d205aa7 143 srStop = tokenLength;
AzureIoTClient 15:956c6d205aa7 144 }
AzureIoTClient 15:956c6d205aa7 145 else if (sigStop < 0)
AzureIoTClient 15:956c6d205aa7 146 {
AzureIoTClient 15:956c6d205aa7 147 sigStop = tokenLength;
AzureIoTClient 15:956c6d205aa7 148 }
AzureIoTClient 15:956c6d205aa7 149
AzureIoTClient 15:956c6d205aa7 150 if ((seStop <= seStart) ||
AzureIoTClient 15:956c6d205aa7 151 (srStop <= srStart) ||
AzureIoTClient 15:956c6d205aa7 152 (sigStop <= sigStart))
AzureIoTClient 15:956c6d205aa7 153 {
AzureIoTClient 15:956c6d205aa7 154 result = false;
AzureIoTClient 15:956c6d205aa7 155 }
AzureIoTClient 15:956c6d205aa7 156 else
AzureIoTClient 15:956c6d205aa7 157 {
AzureIoTClient 15:956c6d205aa7 158 char* expiryASCII = malloc(seStop - seStart + 1);
AzureIoTClient 15:956c6d205aa7 159 /*Codes_SRS_SASTOKEN_25_031: [**If malloc fails during validation then SASToken_Validate shall return false.**]***/
AzureIoTClient 15:956c6d205aa7 160 if (expiryASCII == NULL)
AzureIoTClient 15:956c6d205aa7 161 {
AzureIoTClient 15:956c6d205aa7 162 result = false;
AzureIoTClient 15:956c6d205aa7 163 }
AzureIoTClient 15:956c6d205aa7 164 else
AzureIoTClient 15:956c6d205aa7 165 {
AzureIoTClient 15:956c6d205aa7 166 double expiry;
AzureIoTClient 15:956c6d205aa7 167 for (i = seStart; i < seStop; i++)
AzureIoTClient 15:956c6d205aa7 168 {
AzureIoTClient 15:956c6d205aa7 169 expiryASCII[i - seStart] = sasTokenArray[i];
AzureIoTClient 15:956c6d205aa7 170 }
AzureIoTClient 15:956c6d205aa7 171 expiryASCII[seStop - seStart] = '\0';
AzureIoTClient 15:956c6d205aa7 172
AzureIoTClient 15:956c6d205aa7 173 expiry = getExpiryValue(expiryASCII);
AzureIoTClient 15:956c6d205aa7 174 /*Codes_SRS_SASTOKEN_25_029: [**SASToken_validate shall check for expiry time from token and if token has expired then would return false **]***/
AzureIoTClient 15:956c6d205aa7 175 if (expiry <= 0)
AzureIoTClient 15:956c6d205aa7 176 {
AzureIoTClient 15:956c6d205aa7 177 result = false;
AzureIoTClient 15:956c6d205aa7 178 }
AzureIoTClient 15:956c6d205aa7 179 else
AzureIoTClient 15:956c6d205aa7 180 {
AzureIoTClient 15:956c6d205aa7 181 double secSinceEpoch = get_difftime(get_time(NULL), (time_t)0);
AzureIoTClient 15:956c6d205aa7 182 if (expiry < secSinceEpoch)
AzureIoTClient 15:956c6d205aa7 183 {
AzureIoTClient 15:956c6d205aa7 184 /*Codes_SRS_SASTOKEN_25_029: [**SASToken_validate shall check for expiry time from token and if token has expired then would return false **]***/
AzureIoTClient 15:956c6d205aa7 185 result = false;
AzureIoTClient 15:956c6d205aa7 186 }
AzureIoTClient 15:956c6d205aa7 187 else
AzureIoTClient 15:956c6d205aa7 188 {
AzureIoTClient 15:956c6d205aa7 189 /*Codes_SRS_SASTOKEN_25_030: [**SASToken_validate shall return true only if the format is obeyed and the token has not yet expired **]***/
AzureIoTClient 15:956c6d205aa7 190 result = true;
AzureIoTClient 15:956c6d205aa7 191 }
AzureIoTClient 15:956c6d205aa7 192 }
AzureIoTClient 15:956c6d205aa7 193 free(expiryASCII);
AzureIoTClient 15:956c6d205aa7 194 }
AzureIoTClient 15:956c6d205aa7 195 }
AzureIoTClient 15:956c6d205aa7 196 }
AzureIoTClient 15:956c6d205aa7 197 }
AzureIoTClient 15:956c6d205aa7 198
AzureIoTClient 15:956c6d205aa7 199 return result;
AzureIoTClient 15:956c6d205aa7 200 }
Azure.IoT Build 0:fa2de1b79154 201
Azure.IoT Build 0:fa2de1b79154 202 STRING_HANDLE SASToken_Create(STRING_HANDLE key, STRING_HANDLE scope, STRING_HANDLE keyName, size_t expiry)
Azure.IoT Build 0:fa2de1b79154 203 {
Azure.IoT Build 0:fa2de1b79154 204 STRING_HANDLE result = NULL;
Azure.IoT Build 0:fa2de1b79154 205 char tokenExpirationTime[32] = { 0 };
Azure.IoT Build 0:fa2de1b79154 206
Azure.IoT Build 0:fa2de1b79154 207 /*Codes_SRS_SASTOKEN_06_001: [If key is NULL then SASToken_Create shall return NULL.]*/
Azure.IoT Build 0:fa2de1b79154 208 /*Codes_SRS_SASTOKEN_06_003: [If scope is NULL then SASToken_Create shall return NULL.]*/
Azure.IoT Build 0:fa2de1b79154 209 /*Codes_SRS_SASTOKEN_06_007: [If keyName is NULL then SASToken_Create shall return NULL.]*/
Azure.IoT Build 0:fa2de1b79154 210 if ((key == NULL) ||
Azure.IoT Build 0:fa2de1b79154 211 (scope == NULL) ||
Azure.IoT Build 0:fa2de1b79154 212 (keyName == NULL))
Azure.IoT Build 0:fa2de1b79154 213 {
AzureIoTClient 1:9190c0f4d23a 214 LogError("Invalid Parameter to SASToken_Create. handle key: %p, handle scope: %p, handle keyName: %p", key, scope, keyName);
Azure.IoT Build 0:fa2de1b79154 215 }
Azure.IoT Build 0:fa2de1b79154 216 else
Azure.IoT Build 0:fa2de1b79154 217 {
Azure.IoT Build 0:fa2de1b79154 218 BUFFER_HANDLE decodedKey;
Azure.IoT Build 0:fa2de1b79154 219 /*Codes_SRS_SASTOKEN_06_029: [The key parameter is decoded from base64.]*/
Azure.IoT Build 0:fa2de1b79154 220 if ((decodedKey = Base64_Decoder(STRING_c_str(key))) == NULL)
Azure.IoT Build 0:fa2de1b79154 221 {
Azure.IoT Build 0:fa2de1b79154 222 /*Codes_SRS_SASTOKEN_06_030: [If there is an error in the decoding then SASToken_Create shall return NULL.]*/
AzureIoTClient 1:9190c0f4d23a 223 LogError("Unable to decode the key for generating the SAS.");
Azure.IoT Build 0:fa2de1b79154 224 }
Azure.IoT Build 0:fa2de1b79154 225 else
Azure.IoT Build 0:fa2de1b79154 226 {
Azure.IoT Build 0:fa2de1b79154 227 /*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 228 if (size_tToString(tokenExpirationTime, sizeof(tokenExpirationTime), expiry) != 0)
Azure.IoT Build 0:fa2de1b79154 229 {
AzureIoTClient 1:9190c0f4d23a 230 LogError("For some reason converting seconds to a string failed. No SAS can be generated.");
Azure.IoT Build 0:fa2de1b79154 231 }
Azure.IoT Build 0:fa2de1b79154 232 else
Azure.IoT Build 0:fa2de1b79154 233 {
Azure.IoT Build 0:fa2de1b79154 234 STRING_HANDLE toBeHashed = NULL;
Azure.IoT Build 0:fa2de1b79154 235 BUFFER_HANDLE hash = NULL;
Azure.IoT Build 0:fa2de1b79154 236 if (((hash = BUFFER_new()) == NULL) ||
Azure.IoT Build 0:fa2de1b79154 237 ((toBeHashed = STRING_new()) == NULL) ||
Azure.IoT Build 0:fa2de1b79154 238 ((result = STRING_new()) == NULL))
Azure.IoT Build 0:fa2de1b79154 239 {
AzureIoTClient 1:9190c0f4d23a 240 LogError("Unable to allocate memory to prepare SAS token.");
Azure.IoT Build 0:fa2de1b79154 241 }
Azure.IoT Build 0:fa2de1b79154 242 else
Azure.IoT Build 0:fa2de1b79154 243 {
Azure.IoT Build 0:fa2de1b79154 244 /*Codes_SRS_SASTOKEN_06_009: [The scope is the basis for creating a STRING_HANDLE.]*/
Azure.IoT Build 0:fa2de1b79154 245 /*Codes_SRS_SASTOKEN_06_010: [A "\n" is appended to that string.]*/
Azure.IoT Build 0:fa2de1b79154 246 /*Codes_SRS_SASTOKEN_06_011: [tokenExpirationTime is appended to that string.]*/
Azure.IoT Build 0:fa2de1b79154 247 if ((STRING_concat_with_STRING(toBeHashed, scope) != 0) ||
Azure.IoT Build 0:fa2de1b79154 248 (STRING_concat(toBeHashed, "\n") != 0) ||
Azure.IoT Build 0:fa2de1b79154 249 (STRING_concat(toBeHashed, tokenExpirationTime) != 0))
Azure.IoT Build 0:fa2de1b79154 250 {
AzureIoTClient 1:9190c0f4d23a 251 LogError("Unable to build the input to the HMAC to prepare SAS token.");
Azure.IoT Build 0:fa2de1b79154 252 STRING_delete(result);
Azure.IoT Build 0:fa2de1b79154 253 result = NULL;
Azure.IoT Build 0:fa2de1b79154 254 }
Azure.IoT Build 0:fa2de1b79154 255 else
Azure.IoT Build 0:fa2de1b79154 256 {
Azure.IoT Build 0:fa2de1b79154 257 STRING_HANDLE base64Signature = NULL;
Azure.IoT Build 0:fa2de1b79154 258 STRING_HANDLE urlEncodedSignature = NULL;
AzureIoTClient 11:77df6d7e65ae 259 size_t inLen = STRING_length(toBeHashed);
AzureIoTClient 11:77df6d7e65ae 260 const unsigned char* inBuf = (const unsigned char*)STRING_c_str(toBeHashed);
AzureIoTClient 11:77df6d7e65ae 261 size_t outLen = BUFFER_length(decodedKey);
AzureIoTClient 11:77df6d7e65ae 262 unsigned char* outBuf = BUFFER_u_char(decodedKey);
Azure.IoT Build 0:fa2de1b79154 263 /*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 264 /*Codes_SRS_SASTOKEN_06_012: [An HMAC256 hash is calculated using the decodedKey, over toBeHashed.]*/
Azure.IoT Build 0:fa2de1b79154 265 /*Codes_SRS_SASTOKEN_06_014: [If there are any errors from the following operations then NULL shall be returned.]*/
Azure.IoT Build 0:fa2de1b79154 266 /*Codes_SRS_SASTOKEN_06_015: [The hash is base 64 encoded.]*/
Azure.IoT Build 0:fa2de1b79154 267 /*Codes_SRS_SASTOKEN_06_028: [base64Signature shall be url encoded.]*/
Azure.IoT Build 0:fa2de1b79154 268 /*Codes_SRS_SASTOKEN_06_016: [The string "SharedAccessSignature sr=" is the first part of the result of SASToken_Create.]*/
Azure.IoT Build 0:fa2de1b79154 269 /*Codes_SRS_SASTOKEN_06_017: [The scope parameter is appended to result.]*/
Azure.IoT Build 0:fa2de1b79154 270 /*Codes_SRS_SASTOKEN_06_018: [The string "&sig=" is appended to result.]*/
Azure.IoT Build 0:fa2de1b79154 271 /*Codes_SRS_SASTOKEN_06_019: [The string urlEncodedSignature shall be appended to result.]*/
Azure.IoT Build 0:fa2de1b79154 272 /*Codes_SRS_SASTOKEN_06_020: [The string "&se=" shall be appended to result.]*/
Azure.IoT Build 0:fa2de1b79154 273 /*Codes_SRS_SASTOKEN_06_021: [tokenExpirationTime is appended to result.]*/
Azure.IoT Build 0:fa2de1b79154 274 /*Codes_SRS_SASTOKEN_06_022: [The string "&skn=" is appended to result.]*/
Azure.IoT Build 0:fa2de1b79154 275 /*Codes_SRS_SASTOKEN_06_023: [The argument keyName is appended to result.]*/
AzureIoTClient 11:77df6d7e65ae 276 if ((HMACSHA256_ComputeHash(outBuf, outLen, inBuf, inLen, hash) != HMACSHA256_OK) ||
Azure.IoT Build 0:fa2de1b79154 277 ((base64Signature = Base64_Encode(hash)) == NULL) ||
Azure.IoT Build 0:fa2de1b79154 278 ((urlEncodedSignature = URL_Encode(base64Signature)) == NULL) ||
Azure.IoT Build 0:fa2de1b79154 279 (STRING_copy(result, "SharedAccessSignature sr=") != 0) ||
Azure.IoT Build 0:fa2de1b79154 280 (STRING_concat_with_STRING(result, scope) != 0) ||
Azure.IoT Build 0:fa2de1b79154 281 (STRING_concat(result, "&sig=") != 0) ||
Azure.IoT Build 0:fa2de1b79154 282 (STRING_concat_with_STRING(result, urlEncodedSignature) != 0) ||
Azure.IoT Build 0:fa2de1b79154 283 (STRING_concat(result, "&se=") != 0) ||
Azure.IoT Build 0:fa2de1b79154 284 (STRING_concat(result, tokenExpirationTime) != 0) ||
Azure.IoT Build 0:fa2de1b79154 285 (STRING_concat(result, "&skn=") != 0) ||
Azure.IoT Build 0:fa2de1b79154 286 (STRING_concat_with_STRING(result, keyName) != 0))
Azure.IoT Build 0:fa2de1b79154 287 {
AzureIoTClient 1:9190c0f4d23a 288 LogError("Unable to build the SAS token.");
Azure.IoT Build 0:fa2de1b79154 289 STRING_delete(result);
Azure.IoT Build 0:fa2de1b79154 290 result = NULL;
Azure.IoT Build 0:fa2de1b79154 291 }
Azure.IoT Build 0:fa2de1b79154 292 else
Azure.IoT Build 0:fa2de1b79154 293 {
Azure.IoT Build 0:fa2de1b79154 294 /* everything OK */
Azure.IoT Build 0:fa2de1b79154 295 }
Azure.IoT Build 0:fa2de1b79154 296 STRING_delete(base64Signature);
Azure.IoT Build 0:fa2de1b79154 297 STRING_delete(urlEncodedSignature);
Azure.IoT Build 0:fa2de1b79154 298 }
Azure.IoT Build 0:fa2de1b79154 299 }
Azure.IoT Build 0:fa2de1b79154 300 STRING_delete(toBeHashed);
Azure.IoT Build 0:fa2de1b79154 301 BUFFER_delete(hash);
Azure.IoT Build 0:fa2de1b79154 302 }
Azure.IoT Build 0:fa2de1b79154 303 BUFFER_delete(decodedKey);
Azure.IoT Build 0:fa2de1b79154 304 }
Azure.IoT Build 0:fa2de1b79154 305 }
Azure.IoT Build 0:fa2de1b79154 306
Azure.IoT Build 0:fa2de1b79154 307 return result;
Azure.IoT Build 0:fa2de1b79154 308 }
Azure.IoT Build 0:fa2de1b79154 309