Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Committer:
XinZhangMS
Date:
Thu Aug 23 06:52:14 2018 +0000
Revision:
0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI

Who changed what in which revision?

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