[453] | 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 | }
|
---|