1 | // Copyright (c) Microsoft. All rights reserved.
|
---|
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
---|
3 |
|
---|
4 | #include <stdlib.h>
|
---|
5 | #include "umock_c/umock_c_prod.h"
|
---|
6 | #include "azure_c_shared_utility/gballoc.h"
|
---|
7 | #include "azure_c_shared_utility/xlogging.h"
|
---|
8 | #include "azure_c_shared_utility/azure_base64.h"
|
---|
9 | #include "azure_c_shared_utility/azure_base32.h"
|
---|
10 | #include "azure_c_shared_utility/urlencode.h"
|
---|
11 | #include "azure_c_shared_utility/sha.h"
|
---|
12 | #include "azure_c_shared_utility/strings.h"
|
---|
13 | #include "azure_c_shared_utility/crt_abstractions.h"
|
---|
14 | #include "azure_c_shared_utility/sastoken.h"
|
---|
15 | #include "azure_c_shared_utility/hmacsha256.h"
|
---|
16 |
|
---|
17 | #include "azure_prov_client/internal/prov_auth_client.h"
|
---|
18 | #include "hsm_client_data.h"
|
---|
19 |
|
---|
20 | #include "azure_prov_client/prov_security_factory.h"
|
---|
21 |
|
---|
22 | typedef struct PROV_AUTH_INFO_TAG
|
---|
23 | {
|
---|
24 | HSM_CLIENT_HANDLE hsm_client_handle;
|
---|
25 |
|
---|
26 | PROV_AUTH_TYPE sec_type;
|
---|
27 |
|
---|
28 | char* registration_id;
|
---|
29 |
|
---|
30 | HSM_CLIENT_CREATE hsm_client_create;
|
---|
31 | HSM_CLIENT_DESTROY hsm_client_destroy;
|
---|
32 |
|
---|
33 | HSM_CLIENT_ACTIVATE_IDENTITY_KEY hsm_client_import_key;
|
---|
34 | HSM_CLIENT_GET_ENDORSEMENT_KEY hsm_client_get_endorsement_key;
|
---|
35 | HSM_CLIENT_GET_STORAGE_ROOT_KEY hsm_client_get_srk;
|
---|
36 | HSM_CLIENT_SIGN_WITH_IDENTITY hsm_client_sign_data;
|
---|
37 |
|
---|
38 | HSM_CLIENT_GET_CERTIFICATE hsm_client_get_cert;
|
---|
39 | HSM_CLIENT_GET_ALIAS_KEY hsm_client_get_alias_key;
|
---|
40 | HSM_CLIENT_GET_COMMON_NAME hsm_client_get_common_name;
|
---|
41 |
|
---|
42 | HSM_CLIENT_GET_SYMMETRICAL_KEY hsm_client_get_symm_key;
|
---|
43 | HSM_CLIENT_SET_SYMMETRICAL_KEY_INFO hsm_client_set_symm_key_info;
|
---|
44 | } PROV_AUTH_INFO;
|
---|
45 |
|
---|
46 | static char* encode_value(const uint8_t* msg_digest, size_t digest_len)
|
---|
47 | {
|
---|
48 | char* result;
|
---|
49 |
|
---|
50 | char* encoded_hash = Azure_Base32_Encode_Bytes(msg_digest, digest_len);
|
---|
51 | if (encoded_hash == NULL)
|
---|
52 | {
|
---|
53 | LogError("Failure encoded Base32");
|
---|
54 | result = NULL;
|
---|
55 | }
|
---|
56 | else
|
---|
57 | {
|
---|
58 | size_t encode_len = strlen(encoded_hash);
|
---|
59 | char* iterator = encoded_hash + encode_len - 1;
|
---|
60 |
|
---|
61 | while (iterator != encoded_hash)
|
---|
62 | {
|
---|
63 | if (*iterator != '=')
|
---|
64 | {
|
---|
65 | *(iterator+1) = '\0';
|
---|
66 | break;
|
---|
67 | }
|
---|
68 | iterator--;
|
---|
69 | }
|
---|
70 |
|
---|
71 | if (mallocAndStrcpy_s(&result, encoded_hash) != 0)
|
---|
72 | {
|
---|
73 | LogError("Failure allocating encoded base32 result");
|
---|
74 | result = NULL;
|
---|
75 | }
|
---|
76 | free(encoded_hash);
|
---|
77 | }
|
---|
78 | return result;
|
---|
79 | }
|
---|
80 |
|
---|
81 | static int load_registration_id(PROV_AUTH_INFO* handle)
|
---|
82 | {
|
---|
83 | int result;
|
---|
84 | if (handle->sec_type == PROV_AUTH_TYPE_TPM)
|
---|
85 | {
|
---|
86 | SHA256Context sha_ctx;
|
---|
87 | uint8_t msg_digest[SHA256HashSize];
|
---|
88 | unsigned char* endorsement_key;
|
---|
89 | size_t ek_len;
|
---|
90 |
|
---|
91 | if (handle->hsm_client_get_endorsement_key(handle->hsm_client_handle, &endorsement_key, &ek_len) != 0)
|
---|
92 | {
|
---|
93 | LogError("Failed getting device reg id");
|
---|
94 | result = MU_FAILURE;
|
---|
95 | }
|
---|
96 | else
|
---|
97 | {
|
---|
98 | if (SHA256Reset(&sha_ctx) != 0)
|
---|
99 | {
|
---|
100 | LogError("Failed sha256 reset");
|
---|
101 | result = MU_FAILURE;
|
---|
102 | }
|
---|
103 | else if (SHA256Input(&sha_ctx, endorsement_key, (unsigned int)ek_len) != 0)
|
---|
104 | {
|
---|
105 | LogError("Failed SHA256Input");
|
---|
106 | result = MU_FAILURE;
|
---|
107 | }
|
---|
108 | else if (SHA256Result(&sha_ctx, msg_digest) != 0)
|
---|
109 | {
|
---|
110 | LogError("Failed SHA256Result");
|
---|
111 | result = MU_FAILURE;
|
---|
112 | }
|
---|
113 | else
|
---|
114 | {
|
---|
115 | handle->registration_id = encode_value(msg_digest, SHA256HashSize);
|
---|
116 | if (handle->registration_id == NULL)
|
---|
117 | {
|
---|
118 | LogError("Failed allocating registration Id");
|
---|
119 | result = MU_FAILURE;
|
---|
120 | }
|
---|
121 | else
|
---|
122 | {
|
---|
123 | result = 0;
|
---|
124 | }
|
---|
125 | }
|
---|
126 | free(endorsement_key);
|
---|
127 | }
|
---|
128 | }
|
---|
129 | else
|
---|
130 | {
|
---|
131 | handle->registration_id = handle->hsm_client_get_common_name(handle->hsm_client_handle);
|
---|
132 | if (handle->registration_id == NULL)
|
---|
133 | {
|
---|
134 | LogError("Failed getting common name from certificate");
|
---|
135 | result = MU_FAILURE;
|
---|
136 | }
|
---|
137 | else
|
---|
138 | {
|
---|
139 | result = 0;
|
---|
140 | }
|
---|
141 | }
|
---|
142 | return result;
|
---|
143 | }
|
---|
144 |
|
---|
145 | static int sign_sas_data(PROV_AUTH_INFO* auth_info, const char* payload, unsigned char** output, size_t* len)
|
---|
146 | {
|
---|
147 | int result;
|
---|
148 | size_t payload_len = strlen(payload);
|
---|
149 | if (auth_info->sec_type == PROV_AUTH_TYPE_TPM)
|
---|
150 | {
|
---|
151 | if (auth_info->hsm_client_sign_data(auth_info->hsm_client_handle, (const unsigned char*)payload, strlen(payload), output, len) != 0)
|
---|
152 | {
|
---|
153 | LogError("Failed signing data");
|
---|
154 | result = MU_FAILURE;
|
---|
155 | }
|
---|
156 | else
|
---|
157 | {
|
---|
158 | result = 0;
|
---|
159 | }
|
---|
160 | }
|
---|
161 | else
|
---|
162 | {
|
---|
163 | char* symmetrical_key = auth_info->hsm_client_get_symm_key(auth_info->hsm_client_handle);
|
---|
164 | if (symmetrical_key == NULL)
|
---|
165 | {
|
---|
166 | LogError("Failed getting asymmetrical key");
|
---|
167 | result = MU_FAILURE;
|
---|
168 | }
|
---|
169 | else
|
---|
170 | {
|
---|
171 | BUFFER_HANDLE decoded_key;
|
---|
172 | BUFFER_HANDLE output_hash;
|
---|
173 | if ((decoded_key = Azure_Base64_Decode(symmetrical_key)) == NULL)
|
---|
174 | {
|
---|
175 | LogError("Failed decoding symmetrical key");
|
---|
176 | result = MU_FAILURE;
|
---|
177 | }
|
---|
178 | else if ((output_hash = BUFFER_new()) == NULL)
|
---|
179 | {
|
---|
180 | LogError("Failed allocating output hash buffer");
|
---|
181 | BUFFER_delete(decoded_key);
|
---|
182 | result = MU_FAILURE;
|
---|
183 | }
|
---|
184 | else
|
---|
185 | {
|
---|
186 | size_t decoded_key_len = BUFFER_length(decoded_key);
|
---|
187 | const unsigned char* decoded_key_bytes = BUFFER_u_char(decoded_key);
|
---|
188 |
|
---|
189 | if (HMACSHA256_ComputeHash(decoded_key_bytes, decoded_key_len, (const unsigned char*)payload, payload_len, output_hash) != HMACSHA256_OK)
|
---|
190 | {
|
---|
191 | LogError("Failed computing HMAC Hash");
|
---|
192 | result = MU_FAILURE;
|
---|
193 | }
|
---|
194 | else
|
---|
195 | {
|
---|
196 | *len = BUFFER_length(output_hash);
|
---|
197 | if ((*output = malloc(*len)) == NULL)
|
---|
198 | {
|
---|
199 | LogError("Failed allocating output buffer");
|
---|
200 | result = MU_FAILURE;
|
---|
201 | }
|
---|
202 | else
|
---|
203 | {
|
---|
204 | const unsigned char* output_data = BUFFER_u_char(output_hash);
|
---|
205 | memcpy(*output, output_data, *len);
|
---|
206 | result = 0;
|
---|
207 | }
|
---|
208 | }
|
---|
209 | BUFFER_delete(decoded_key);
|
---|
210 | BUFFER_delete(output_hash);
|
---|
211 | }
|
---|
212 | }
|
---|
213 | free(symmetrical_key);
|
---|
214 | }
|
---|
215 | return result;
|
---|
216 | }
|
---|
217 |
|
---|
218 | PROV_AUTH_HANDLE prov_auth_create(void)
|
---|
219 | {
|
---|
220 | PROV_AUTH_INFO* result;
|
---|
221 | /* Codes_SRS_PROV_AUTH_CLIENT_07_001: [ prov_auth_create shall allocate the PROV_AUTH_INFO. ] */
|
---|
222 | if ((result = (PROV_AUTH_INFO*)malloc(sizeof(PROV_AUTH_INFO))) == NULL)
|
---|
223 | {
|
---|
224 | LogError("Failed allocating PROV_AUTH_INFO.");
|
---|
225 | }
|
---|
226 | else
|
---|
227 | {
|
---|
228 | memset(result, 0, sizeof(PROV_AUTH_INFO) );
|
---|
229 | SECURE_DEVICE_TYPE sec_type = prov_dev_security_get_type();
|
---|
230 | #if defined(HSM_TYPE_SAS_TOKEN) || defined(HSM_AUTH_TYPE_CUSTOM)
|
---|
231 | if (sec_type == SECURE_DEVICE_TYPE_TPM)
|
---|
232 | {
|
---|
233 | /* Codes_SRS_PROV_AUTH_CLIENT_07_003: [ prov_auth_create shall validate the specified secure enclave interface to ensure. ] */
|
---|
234 | result->sec_type = PROV_AUTH_TYPE_TPM;
|
---|
235 | const HSM_CLIENT_TPM_INTERFACE* tpm_interface = hsm_client_tpm_interface();
|
---|
236 | if ((tpm_interface == NULL) ||
|
---|
237 | ((result->hsm_client_create = tpm_interface->hsm_client_tpm_create) == NULL) ||
|
---|
238 | ((result->hsm_client_destroy = tpm_interface->hsm_client_tpm_destroy) == NULL) ||
|
---|
239 | ((result->hsm_client_import_key = tpm_interface->hsm_client_activate_identity_key) == NULL) ||
|
---|
240 | ((result->hsm_client_get_endorsement_key = tpm_interface->hsm_client_get_ek) == NULL) ||
|
---|
241 | ((result->hsm_client_get_srk = tpm_interface->hsm_client_get_srk) == NULL) ||
|
---|
242 | ((result->hsm_client_sign_data = tpm_interface->hsm_client_sign_with_identity) == NULL)
|
---|
243 | )
|
---|
244 | {
|
---|
245 | /* Codes_SRS_PROV_AUTH_CLIENT_07_002: [ If any failure is encountered prov_auth_create shall return NULL ] */
|
---|
246 | LogError("Invalid TPM secure device interface was specified");
|
---|
247 | free(result);
|
---|
248 | result = NULL;
|
---|
249 | }
|
---|
250 | }
|
---|
251 | #endif
|
---|
252 | #if defined(HSM_TYPE_X509) || defined(HSM_AUTH_TYPE_CUSTOM)
|
---|
253 | if (sec_type == SECURE_DEVICE_TYPE_X509)
|
---|
254 | {
|
---|
255 | /* Codes_SRS_PROV_AUTH_CLIENT_07_003: [ prov_auth_create shall validate the specified secure enclave interface to ensure. ] */
|
---|
256 | result->sec_type = PROV_AUTH_TYPE_X509;
|
---|
257 | const HSM_CLIENT_X509_INTERFACE* x509_interface = hsm_client_x509_interface();
|
---|
258 | if ((x509_interface == NULL) ||
|
---|
259 | ((result->hsm_client_create = x509_interface->hsm_client_x509_create) == NULL) ||
|
---|
260 | ((result->hsm_client_destroy = x509_interface->hsm_client_x509_destroy) == NULL) ||
|
---|
261 | ((result->hsm_client_get_cert = x509_interface->hsm_client_get_cert) == NULL) ||
|
---|
262 | ((result->hsm_client_get_common_name = x509_interface->hsm_client_get_common_name) == NULL) ||
|
---|
263 | ((result->hsm_client_get_alias_key = x509_interface->hsm_client_get_key) == NULL)
|
---|
264 | )
|
---|
265 | {
|
---|
266 | LogError("Invalid x509 secure device interface was specified");
|
---|
267 | free(result);
|
---|
268 | result = NULL;
|
---|
269 | }
|
---|
270 | }
|
---|
271 | #endif
|
---|
272 | #if defined(HSM_TYPE_SYMM_KEY) || defined(HSM_AUTH_TYPE_CUSTOM)
|
---|
273 | if (sec_type == SECURE_DEVICE_TYPE_SYMMETRIC_KEY)
|
---|
274 | {
|
---|
275 | result->sec_type = PROV_AUTH_TYPE_KEY;
|
---|
276 | const HSM_CLIENT_KEY_INTERFACE* key_interface = hsm_client_key_interface();
|
---|
277 | if ((key_interface == NULL) ||
|
---|
278 | ((result->hsm_client_create = key_interface->hsm_client_key_create) == NULL) ||
|
---|
279 | ((result->hsm_client_destroy = key_interface->hsm_client_key_destroy) == NULL) ||
|
---|
280 | ((result->hsm_client_get_common_name = key_interface->hsm_client_get_registration_name) == NULL) ||
|
---|
281 | ((result->hsm_client_get_symm_key = key_interface->hsm_client_get_symm_key) == NULL) ||
|
---|
282 | ((result->hsm_client_set_symm_key_info = key_interface->hsm_client_set_symm_key_info) == NULL)
|
---|
283 | )
|
---|
284 | {
|
---|
285 | LogError("Invalid symmetric key secure device interface was specified");
|
---|
286 | free(result);
|
---|
287 | result = NULL;
|
---|
288 | }
|
---|
289 | }
|
---|
290 | #endif
|
---|
291 |
|
---|
292 | if (result == NULL)
|
---|
293 | {
|
---|
294 | LogError("Error allocating result or else unsupported security type %d", sec_type);
|
---|
295 | }
|
---|
296 | else if (result->hsm_client_create == NULL)
|
---|
297 | {
|
---|
298 | LogError("hsm_client_create is not a valid address");
|
---|
299 | free(result);
|
---|
300 | result = NULL;
|
---|
301 | }
|
---|
302 | else
|
---|
303 | {
|
---|
304 | /* Codes_SRS_PROV_AUTH_CLIENT_07_004: [ prov_auth_create shall call hsm_client_create on the secure enclave interface. ] */
|
---|
305 | if ((result->hsm_client_handle = result->hsm_client_create() ) == NULL)
|
---|
306 | {
|
---|
307 | LogError("failed create device auth module.");
|
---|
308 | free(result);
|
---|
309 | result = NULL;
|
---|
310 | }
|
---|
311 | else if (result->sec_type == PROV_AUTH_TYPE_KEY && result->hsm_client_set_symm_key_info(result->hsm_client_handle, prov_dev_get_symm_registration_name(), prov_dev_get_symmetric_key()) != 0)
|
---|
312 | {
|
---|
313 | LogError("failed create device auth module.");
|
---|
314 | result->hsm_client_destroy(result->hsm_client_handle);
|
---|
315 | free(result);
|
---|
316 | result = NULL;
|
---|
317 | }
|
---|
318 | }
|
---|
319 | }
|
---|
320 | return result;
|
---|
321 | }
|
---|
322 |
|
---|
323 | void prov_auth_destroy(PROV_AUTH_HANDLE handle)
|
---|
324 | {
|
---|
325 | /* Codes_SRS_PROV_AUTH_CLIENT_07_005: [ if handle is NULL, prov_auth_destroy shall do nothing. ] */
|
---|
326 | if (handle != NULL)
|
---|
327 | {
|
---|
328 | /* Codes_SRS_PROV_AUTH_CLIENT_07_007: [ prov_auth_destroy shall free all resources allocated in this module. ] */
|
---|
329 | free(handle->registration_id);
|
---|
330 | handle->hsm_client_destroy(handle->hsm_client_handle);
|
---|
331 | /* Codes_SRS_PROV_AUTH_CLIENT_07_006: [ prov_auth_destroy shall free the PROV_AUTH_HANDLE instance. ] */
|
---|
332 | free(handle);
|
---|
333 | }
|
---|
334 | }
|
---|
335 |
|
---|
336 | PROV_AUTH_TYPE prov_auth_get_type(PROV_AUTH_HANDLE handle)
|
---|
337 | {
|
---|
338 | PROV_AUTH_TYPE result;
|
---|
339 | /* Codes_SRS_PROV_AUTH_CLIENT_07_008: [ if handle is NULL prov_auth_get_type shall return PROV_AUTH_TYPE_UNKNOWN ] */
|
---|
340 | if (handle == NULL)
|
---|
341 | {
|
---|
342 | LogError("Invalid handle specified");
|
---|
343 | result = PROV_AUTH_TYPE_UNKNOWN;
|
---|
344 | }
|
---|
345 | else
|
---|
346 | {
|
---|
347 | /* Codes_SRS_PROV_AUTH_CLIENT_07_009: [ prov_auth_get_type shall return the PROV_AUTH_TYPE of the underlying secure enclave. ] */
|
---|
348 | result = handle->sec_type;
|
---|
349 | }
|
---|
350 | return result;
|
---|
351 | }
|
---|
352 |
|
---|
353 | char* prov_auth_get_registration_id(PROV_AUTH_HANDLE handle)
|
---|
354 | {
|
---|
355 | char* result;
|
---|
356 | if (handle == NULL)
|
---|
357 | {
|
---|
358 | /* Codes_SRS_PROV_AUTH_CLIENT_07_010: [ if handle is NULL prov_auth_get_registration_id shall return NULL. ] */
|
---|
359 | LogError("Invalid handle parameter");
|
---|
360 | result = NULL;
|
---|
361 | }
|
---|
362 | else
|
---|
363 | {
|
---|
364 | int load_result = 0;
|
---|
365 | int reg_id_allocated = 0;
|
---|
366 | if (handle->registration_id == NULL)
|
---|
367 | {
|
---|
368 | /* Codes_SRS_PROV_AUTH_CLIENT_07_011: [ prov_auth_get_registration_id shall load the registration id if it has not been previously loaded. ] */
|
---|
369 | load_result = load_registration_id(handle);
|
---|
370 | if (load_result == 0)
|
---|
371 | {
|
---|
372 | reg_id_allocated = 1;
|
---|
373 | }
|
---|
374 | }
|
---|
375 |
|
---|
376 | if (load_result != 0)
|
---|
377 | {
|
---|
378 | /* Codes_SRS_PROV_AUTH_CLIENT_07_012: [ If a failure is encountered, prov_auth_get_registration_id shall return NULL. ] */
|
---|
379 | LogError("Failed loading registration key");
|
---|
380 | result = NULL;
|
---|
381 | }
|
---|
382 | /* Codes_SRS_PROV_AUTH_CLIENT_07_013: [ Upon success prov_auth_get_registration_id shall return the registration id of the secure enclave. ] */
|
---|
383 | else if (mallocAndStrcpy_s(&result, handle->registration_id) != 0)
|
---|
384 | {
|
---|
385 | /* Codes_SRS_PROV_AUTH_CLIENT_07_012: [ If a failure is encountered, prov_auth_get_registration_id shall return NULL. ] */
|
---|
386 | LogError("Failed allocating registration key");
|
---|
387 | if (reg_id_allocated == 1)
|
---|
388 | {
|
---|
389 | free(handle->registration_id);
|
---|
390 | handle->registration_id = NULL;
|
---|
391 | }
|
---|
392 | result = NULL;
|
---|
393 | }
|
---|
394 | }
|
---|
395 | return result;
|
---|
396 | }
|
---|
397 |
|
---|
398 | int prov_auth_set_registration_id(PROV_AUTH_HANDLE handle, const char* registration_id)
|
---|
399 | {
|
---|
400 | int result;
|
---|
401 | if (handle == NULL || registration_id == NULL)
|
---|
402 | {
|
---|
403 | LogError("Invalid parameter handle: %p, registration_id: %p", handle, registration_id);
|
---|
404 | result = MU_FAILURE;
|
---|
405 | }
|
---|
406 | else
|
---|
407 | {
|
---|
408 | if (handle->registration_id != NULL)
|
---|
409 | {
|
---|
410 | LogError("Registration_id has been previously set, registration can not be changed");
|
---|
411 | result = MU_FAILURE;
|
---|
412 | }
|
---|
413 | else if (mallocAndStrcpy_s(&handle->registration_id, registration_id) != 0)
|
---|
414 | {
|
---|
415 | LogError("Failed allocating registration key");
|
---|
416 | result = MU_FAILURE;
|
---|
417 | }
|
---|
418 | else
|
---|
419 | {
|
---|
420 | result = 0;
|
---|
421 | }
|
---|
422 | }
|
---|
423 | return result;
|
---|
424 | }
|
---|
425 |
|
---|
426 | BUFFER_HANDLE prov_auth_get_endorsement_key(PROV_AUTH_HANDLE handle)
|
---|
427 | {
|
---|
428 | BUFFER_HANDLE result;
|
---|
429 | if (handle == NULL)
|
---|
430 | {
|
---|
431 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_021: [ If handle is NULL prov_auth_get_endorsement_key shall return NULL. ] */
|
---|
432 | LogError("Invalid handle parameter");
|
---|
433 | result = NULL;
|
---|
434 | }
|
---|
435 | else if (handle->sec_type != PROV_AUTH_TYPE_TPM)
|
---|
436 | {
|
---|
437 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_023: [ If the sec_type is PROV_AUTH_TYPE_X509, prov_auth_get_endorsement_key shall return NULL. ] */
|
---|
438 | LogError("Invalid type for operation");
|
---|
439 | result = NULL;
|
---|
440 | }
|
---|
441 | else
|
---|
442 | {
|
---|
443 | unsigned char* ek_value;
|
---|
444 | size_t ek_len;
|
---|
445 |
|
---|
446 | if (handle->hsm_client_get_endorsement_key(handle->hsm_client_handle, &ek_value, &ek_len) != 0)
|
---|
447 | {
|
---|
448 | LogError("Failed getting endorsement key");
|
---|
449 | result = NULL;
|
---|
450 | }
|
---|
451 | else
|
---|
452 | {
|
---|
453 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_022: [ prov_auth_get_endorsement_key shall return the endorsement key returned by the hsm_client_get_ek secure enclave function. ] */
|
---|
454 | result = BUFFER_create(ek_value, ek_len);
|
---|
455 | if (result == NULL)
|
---|
456 | {
|
---|
457 | LogError("Failed creating BUFFER HANDLE");
|
---|
458 | }
|
---|
459 | free(ek_value);
|
---|
460 | }
|
---|
461 | }
|
---|
462 | return result;
|
---|
463 | }
|
---|
464 |
|
---|
465 | BUFFER_HANDLE prov_auth_get_storage_key(PROV_AUTH_HANDLE handle)
|
---|
466 | {
|
---|
467 | BUFFER_HANDLE result;
|
---|
468 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_024: [ If handle is NULL prov_auth_get_storage_key shall return NULL. ] */
|
---|
469 | if (handle == NULL)
|
---|
470 | {
|
---|
471 | LogError("Invalid handle parameter");
|
---|
472 | result = NULL;
|
---|
473 | }
|
---|
474 | else if (handle->sec_type != PROV_AUTH_TYPE_TPM)
|
---|
475 | {
|
---|
476 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_026: [ If the sec_type is PROV_AUTH_TYPE_X509, prov_auth_get_storage_key shall return NULL. ] */
|
---|
477 | LogError("Invalid type for operation");
|
---|
478 | result = NULL;
|
---|
479 | }
|
---|
480 | else
|
---|
481 | {
|
---|
482 | unsigned char* srk_value;
|
---|
483 | size_t srk_len;
|
---|
484 |
|
---|
485 | if (handle->hsm_client_get_srk(handle->hsm_client_handle, &srk_value, &srk_len) != 0)
|
---|
486 | {
|
---|
487 | LogError("Failed getting storage root key");
|
---|
488 | result = NULL;
|
---|
489 | }
|
---|
490 | else
|
---|
491 | {
|
---|
492 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_025: [ prov_auth_get_storage_key shall return the endorsement key returned by the hsm_client_get_srk secure enclave function. ] */
|
---|
493 | result = BUFFER_create(srk_value, srk_len);
|
---|
494 | if (result == NULL)
|
---|
495 | {
|
---|
496 | LogError("Failed creating BUFFER HANDLE");
|
---|
497 | }
|
---|
498 | free(srk_value);
|
---|
499 | }
|
---|
500 | }
|
---|
501 | return result;
|
---|
502 | }
|
---|
503 |
|
---|
504 | int prov_auth_import_key(PROV_AUTH_HANDLE handle, const unsigned char* key_value, size_t key_len)
|
---|
505 | {
|
---|
506 | int result;
|
---|
507 | if (handle == NULL || key_value == NULL || key_len == 0)
|
---|
508 | {
|
---|
509 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_027: [ If handle or key are NULL prov_auth_import_key shall return a non-zero value. ] */
|
---|
510 | LogError("Invalid handle parameter");
|
---|
511 | result = MU_FAILURE;
|
---|
512 | }
|
---|
513 | else if (handle->sec_type != PROV_AUTH_TYPE_TPM)
|
---|
514 | {
|
---|
515 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_029: [ If the sec_type is not SECURE_ENCLAVE_TYPE_TPM, prov_auth_import_key shall return NULL. ] */
|
---|
516 | LogError("Invalid type for operation");
|
---|
517 | result = MU_FAILURE;
|
---|
518 | }
|
---|
519 | else
|
---|
520 | {
|
---|
521 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_028: [ prov_auth_import_key shall import the specified key into the tpm using hsm_client_import_key secure enclave function. ] */
|
---|
522 | if (handle->hsm_client_import_key(handle->hsm_client_handle, key_value, key_len) != 0)
|
---|
523 | {
|
---|
524 | /* SRS_SECURE_ENCLAVE_CLIENT_07_040: [ If hsm_client_import_key returns an error prov_auth_import_key shall return a non-zero value. ]*/
|
---|
525 | LogError("failure importing key into tpm");
|
---|
526 | result = MU_FAILURE;
|
---|
527 | }
|
---|
528 | else
|
---|
529 | {
|
---|
530 | result = 0;
|
---|
531 | }
|
---|
532 | }
|
---|
533 | return result;
|
---|
534 | }
|
---|
535 |
|
---|
536 | char* prov_auth_construct_sas_token(PROV_AUTH_HANDLE handle, const char* token_scope, const char* key_name, size_t expiry_time)
|
---|
537 | {
|
---|
538 | char* result;
|
---|
539 | char expire_token[64] = { 0 };
|
---|
540 |
|
---|
541 | if (handle == NULL || token_scope == NULL || key_name == NULL)
|
---|
542 | {
|
---|
543 | LogError("Invalid handle parameter handle: %p, token_scope: %p, key_name: %p", handle, token_scope, key_name);
|
---|
544 | result = NULL;
|
---|
545 | }
|
---|
546 | else if (handle->sec_type == PROV_AUTH_TYPE_X509)
|
---|
547 | {
|
---|
548 | LogError("Invalid type for operation");
|
---|
549 | result = NULL;
|
---|
550 | }
|
---|
551 | else if (size_tToString(expire_token, sizeof(expire_token), expiry_time) != 0)
|
---|
552 | {
|
---|
553 | result = NULL;
|
---|
554 | LogError("Failure creating expire token");
|
---|
555 | }
|
---|
556 | else
|
---|
557 | {
|
---|
558 | size_t len = strlen(token_scope) + strlen(expire_token) + 3;
|
---|
559 | char* payload = malloc(len + 1);
|
---|
560 | if (payload == NULL)
|
---|
561 | {
|
---|
562 | result = NULL;
|
---|
563 | LogError("Failure allocating payload for sas token.");
|
---|
564 | }
|
---|
565 | else
|
---|
566 | {
|
---|
567 | unsigned char* data_value;
|
---|
568 | size_t data_len;
|
---|
569 | (void)sprintf(payload, "%s\n%s", token_scope, expire_token);
|
---|
570 |
|
---|
571 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_031: [ prov_auth_get_certificate shall import the specified cert into the client using hsm_client_get_cert secure enclave function. ] */
|
---|
572 | if (sign_sas_data(handle, payload, &data_value, &data_len) == 0)
|
---|
573 | {
|
---|
574 | STRING_HANDLE urlEncodedSignature;
|
---|
575 | STRING_HANDLE base64Signature;
|
---|
576 | STRING_HANDLE sas_token_handle;
|
---|
577 | if ((base64Signature = Azure_Base64_Encode_Bytes(data_value, data_len)) == NULL)
|
---|
578 | {
|
---|
579 | result = NULL;
|
---|
580 | LogError("Failure constructing base64 encoding.");
|
---|
581 | }
|
---|
582 | else if ((urlEncodedSignature = URL_Encode(base64Signature)) == NULL)
|
---|
583 | {
|
---|
584 | result = NULL;
|
---|
585 | LogError("Failure constructing url Signature.");
|
---|
586 | STRING_delete(base64Signature);
|
---|
587 | }
|
---|
588 | else
|
---|
589 | {
|
---|
590 | sas_token_handle = STRING_construct_sprintf("SharedAccessSignature sr=%s&sig=%s&se=%s&skn=%s", token_scope, STRING_c_str(urlEncodedSignature), expire_token, key_name);
|
---|
591 | if (sas_token_handle == NULL)
|
---|
592 | {
|
---|
593 | result = NULL;
|
---|
594 | LogError("Failure constructing url Signature.");
|
---|
595 | }
|
---|
596 | else
|
---|
597 | {
|
---|
598 | const char* temp_sas_token = STRING_c_str(sas_token_handle);
|
---|
599 | if (mallocAndStrcpy_s(&result, temp_sas_token) != 0)
|
---|
600 | {
|
---|
601 | LogError("Failure allocating and copying string.");
|
---|
602 | result = NULL;
|
---|
603 | }
|
---|
604 | STRING_delete(sas_token_handle);
|
---|
605 | }
|
---|
606 | STRING_delete(base64Signature);
|
---|
607 | STRING_delete(urlEncodedSignature);
|
---|
608 | }
|
---|
609 | free(data_value);
|
---|
610 | }
|
---|
611 | else
|
---|
612 | {
|
---|
613 | result = NULL;
|
---|
614 | LogError("Failure generate sas token.");
|
---|
615 | }
|
---|
616 | free(payload);
|
---|
617 | }
|
---|
618 | }
|
---|
619 | return result;
|
---|
620 | }
|
---|
621 |
|
---|
622 | char* prov_auth_get_certificate(PROV_AUTH_HANDLE handle)
|
---|
623 | {
|
---|
624 | char* result;
|
---|
625 | if (handle == NULL)
|
---|
626 | {
|
---|
627 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_030: [ If handle or key are NULL prov_auth_get_certificate shall return a non-zero value. ] */
|
---|
628 | LogError("Invalid handle parameter");
|
---|
629 | result = NULL;
|
---|
630 | }
|
---|
631 | else if (handle->sec_type != PROV_AUTH_TYPE_X509)
|
---|
632 | {
|
---|
633 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_032: [ If the sec_type is not PROV_AUTH_TYPE_X509, prov_auth_get_certificate shall return NULL. ] */
|
---|
634 | LogError("Invalid type for operation");
|
---|
635 | result = NULL;
|
---|
636 | }
|
---|
637 | else
|
---|
638 | {
|
---|
639 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_031: [ prov_auth_get_certificate shall import the specified cert into the client using hsm_client_get_cert secure enclave function. ] */
|
---|
640 | result = handle->hsm_client_get_cert(handle->hsm_client_handle);
|
---|
641 | }
|
---|
642 | return result;
|
---|
643 | }
|
---|
644 |
|
---|
645 | char* prov_auth_get_alias_key(PROV_AUTH_HANDLE handle)
|
---|
646 | {
|
---|
647 | char* result;
|
---|
648 | if (handle == NULL)
|
---|
649 | {
|
---|
650 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_033: [ If handle or key are NULL prov_auth_get_alias_key shall return a non-zero value. ] */
|
---|
651 | LogError("Invalid handle parameter");
|
---|
652 | result = NULL;
|
---|
653 | }
|
---|
654 | else if (handle->sec_type != PROV_AUTH_TYPE_X509)
|
---|
655 | {
|
---|
656 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_035: [ If the sec_type is not PROV_AUTH_TYPE_X509, prov_auth_get_alias_key shall return NULL. ] */
|
---|
657 | LogError("Invalid type for operation");
|
---|
658 | result = NULL;
|
---|
659 | }
|
---|
660 | else
|
---|
661 | {
|
---|
662 | /* Codes_SRS_SECURE_ENCLAVE_CLIENT_07_034: [ prov_auth_get_alias_key shall import the specified alias key into the client using hsm_client_get_ak secure enclave function. ] */
|
---|
663 | result = handle->hsm_client_get_alias_key(handle->hsm_client_handle);
|
---|
664 | }
|
---|
665 | return result;
|
---|
666 | }
|
---|