1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*******************************************************************************
3 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
4 * All rights reserved.
5 *******************************************************************************/
6
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #include <dirent.h>
10 #include <ctype.h>
11 #endif
12
13 #include "ifapi_io.h"
14 #include "ifapi_helpers.h"
15 #include "ifapi_keystore.h"
16 #define LOGMODULE fapi
17 #include "util/log.h"
18 #include "util/aux_util.h"
19 #include "ifapi_json_deserialize.h"
20 #include "ifapi_json_serialize.h"
21
22
23 /** Check whether pathname is valid.
24 *
25 * Every key pathname will be checked whether the name contains only
26 * valid character.
27 * @param[in] path The pathname.
28 * @retval TSS2_RC_SUCCESS If the pathname is ok.
29 * @retval TSS2_FAPI_RC_BAD_PATH If not valid characters are detected.
30 */
31 TSS2_RC
ifapi_check_valid_path(const char * path)32 ifapi_check_valid_path(
33 const char *path)
34 {
35 for (size_t i = 0; i < strlen(path); i++) {
36 if (!(isalnum(path[i]) ||
37 path[i] == '_' ||
38 path[i] == '-' ||
39 path[i] == '/')) {
40 LOG_ERROR("Invalid character %c in path %s", path[i], path);
41 return TSS2_FAPI_RC_BAD_PATH;
42 }
43 }
44 return TSS2_RC_SUCCESS;
45 }
46
47 /** Initialize the linked list for an explicit key path.
48 *
49 * An implicit key path will be expanded to a key path starting with the profile
50 * directory. Missing parts will be added if possible.
51 * A linked list of the directories of the explicit path will be returned.
52 *
53 * @param[in] context_profile The profile name used for expansion of the
54 * implicit key path.
55 * @param[in] ipath the implicit key path which has to be expanded.
56 * @param[out] list_node1 The first directory of the implicit list.
57 * @param[out] current_list_node The tail of the path list after the path
58 * which was expanded.
59 * @param[out] result The list of directories as linked list.
60 * @retval TSS2_RC_SUCCESS If the explicit path was created.
61 * @retval TSS2_FAPI_RC_MEMORY: If memory for the path list could not be allocated.
62 * @retval TSS2_FAPI_RC_BAD_VALUE If no explicit path can be derived from the
63 * implicit path.
64 * @retval TSS2_FAPI_RC_BAD_PATH if no valid key path could be created.
65 */
66 static TSS2_RC
initialize_explicit_key_path(const char * context_profile,const char * ipath,NODE_STR_T ** list_node1,NODE_STR_T ** current_list_node,NODE_STR_T ** result)67 initialize_explicit_key_path(
68 const char *context_profile,
69 const char *ipath,
70 NODE_STR_T **list_node1,
71 NODE_STR_T **current_list_node,
72 NODE_STR_T **result)
73 {
74 *list_node1 = split_string(ipath, IFAPI_FILE_DELIM);
75 NODE_STR_T *list_node = *list_node1;
76 char const *profile;
77 char *hierarchy = NULL;
78 TSS2_RC r = TSS2_RC_SUCCESS;
79
80 *result = NULL;
81 if (list_node == NULL) {
82 LOG_ERROR("Invalid path");
83 free_string_list(*list_node1);
84 return TSS2_FAPI_RC_BAD_VALUE;
85 }
86 /* Check whether profile is part of the implicit path. */
87 if (strncmp("P_", list_node->str, 2) == 0) {
88 profile = list_node->str;
89 list_node = list_node->next;
90 } else {
91 profile = context_profile;
92 }
93 /* Create the initial node of the linked list. */
94 *result = init_string_list(profile);
95 if (*result == NULL) {
96 free_string_list(*list_node1);
97 LOG_ERROR("Out of memory");
98 return TSS2_FAPI_RC_MEMORY;
99 }
100 if (strcmp(list_node->str, "HN") == 0 ||
101 strcmp(list_node->str, "HS") == 0 ||
102 strcmp(list_node->str, "HE") == 0 ||
103 strcmp(list_node->str, "HN") == 0) {
104 hierarchy = list_node->str;
105 list_node = list_node->next;
106 } else if (strcmp(list_node->str, "LOCKOUT") == 0) {
107 if (list_node->next) {
108 LOG_ERROR("No objects allowed in the lockout hierarchy.");
109 r = TSS2_FAPI_RC_BAD_VALUE;
110 goto error;
111 }
112 } else if (strcmp(list_node->str, "EK") == 0) {
113 /* The hierarchy for an endorsement key will be added. */
114 hierarchy = "HE";
115 } else if (list_node->str != NULL &&
116 strcmp(list_node->str, "SRK") == 0) {
117 /* The storage hierachy will be added. */
118 hierarchy = "HS";
119 } else {
120 LOG_ERROR("Hierarchy cannot be determined.");
121 r = TSS2_FAPI_RC_BAD_PATH;
122 goto error;
123 }
124 /* Add the used hierarchy to the linked list. */
125 if (hierarchy && !add_string_to_list(*result, hierarchy)) {
126 LOG_ERROR("Out of memory");
127 r = TSS2_FAPI_RC_MEMORY;
128 goto error;
129 }
130 if (list_node == NULL) {
131 goto_error(r, TSS2_FAPI_RC_BAD_PATH, "Explicit path can't be determined.",
132 error);
133 }
134
135 /* Add the primary directory to the linked list. */
136 if (!add_string_to_list(*result, list_node->str)) {
137 LOG_ERROR("Out of memory");
138 r = TSS2_FAPI_RC_MEMORY;
139 goto error;
140 }
141
142 if (hierarchy && strcmp(hierarchy, "HS") == 0 && strcmp(list_node->str, "EK") == 0) {
143 LOG_ERROR("Key EK cannot be created in the storage hierarchy.");
144 r = TSS2_FAPI_RC_BAD_PATH;
145 goto error;
146 }
147
148 if (hierarchy && strcmp(hierarchy, "HE") == 0 && strcmp(list_node->str, "SRK") == 0) {
149 LOG_ERROR("Key EK cannot be create in the endorsement hierarchy.");
150 r = TSS2_FAPI_RC_BAD_PATH;
151 goto error;
152 }
153
154 if (hierarchy && strcmp(hierarchy, "HN") == 0 &&
155 (strcmp(list_node->str, "SRK") == 0 || strcmp(list_node->str, "EK") == 0)) {
156 LOG_ERROR("Key EK and SRK cannot be created in NULL hierarchy.");
157 r = TSS2_FAPI_RC_BAD_PATH;
158 goto error;
159 }
160
161 /* Return the rest of the path. */
162 *current_list_node = list_node->next;
163 return TSS2_RC_SUCCESS;
164
165 error:
166 free_string_list(*result);
167 *result = NULL;
168 free_string_list(*list_node1);
169 *list_node1 = NULL;
170 return r;
171 }
172
173 /** Get explicit key path as linked list.
174 *
175 * An implicit key path will be expanded to a key path starting with the profile
176 * directory. Missing parts will be added if possible.
177 * A linked list of the directories of the explicit path will be returned.
178 * @param[in] keystore The key directories and default profile.
179 * @param[in] ipath the implicit key path which has to be expanded.
180 * @param[out] result The list of directories as linked list.
181 * @retval TSS2_RC_SUCCESS If the explicit path was created.
182 * @retval TSS2_FAPI_RC_MEMORY: If memory for the path list could not be allocated.
183 * @retval TSS2_FAPI_RC_BAD_VALUE If no explicit path can be derived from the
184 * implicit path.
185 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
186 * or contains illegal characters.
187 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
188 * during authorization.
189 */
190 static TSS2_RC
get_explicit_key_path(IFAPI_KEYSTORE * keystore,const char * ipath,NODE_STR_T ** result)191 get_explicit_key_path(
192 IFAPI_KEYSTORE *keystore,
193 const char *ipath,
194 NODE_STR_T **result)
195 {
196 NODE_STR_T *list_node1 = NULL;
197 NODE_STR_T *list_node = NULL;
198 TSS2_RC r = initialize_explicit_key_path(keystore->defaultprofile, ipath,
199 &list_node1, &list_node, result);
200 goto_if_error(r, "init_explicit_key_path", error);
201
202 while (list_node != NULL) {
203 /* Add tail of path list to expanded head of the path list. */
204 if (!add_string_to_list(*result, list_node->str)) {
205 LOG_ERROR("Out of memory");
206 r = TSS2_FAPI_RC_MEMORY;
207 goto error;
208 }
209 list_node = list_node->next;
210 }
211 free_string_list(list_node1);
212 return TSS2_RC_SUCCESS;
213
214 error:
215 if (*result)
216 free_string_list(*result);
217 if (list_node1)
218 free_string_list(list_node1);
219 return r;
220 }
221
222 /** Convert full FAPI path to relative path.
223 *
224 * The relative path will be copied directly into the passed object.
225 *
226 * @param[in] keystore The key directories and default profile.
227 * @param[in,out] path The absolute path.
228 */
229 void
full_path_to_fapi_path(IFAPI_KEYSTORE * keystore,char * path)230 full_path_to_fapi_path(IFAPI_KEYSTORE *keystore, char *path)
231 {
232 unsigned int start_pos, end_pos, i;
233 const unsigned int path_length = strlen(path);
234 size_t keystore_length = strlen(keystore->userdir);
235 char fapi_path_delim;
236
237 start_pos = 0;
238
239 /* Check type of path, user or system */
240 if (strncmp(&path[0], keystore->userdir, keystore_length) == 0) {
241 start_pos = strlen(keystore->userdir);
242 } else {
243 keystore_length = strlen(keystore->systemdir);
244 if (strncmp(&path[0], keystore->systemdir, keystore_length) == 0)
245 start_pos = strlen(keystore->systemdir);
246 }
247
248 if (!start_pos)
249 /* relative path was passed */
250 return;
251
252 /* Move relative path */
253 end_pos = path_length - start_pos;
254 memmove(&path[0], &path[start_pos], end_pos);
255 size_t ip = 0;
256 size_t lp = strlen(path);
257
258 /* Remove double / */
259 while (ip < lp) {
260 if (strncmp(&path[ip], "//", 2) == 0) {
261 memmove(&path[ip], &path[ip+1], lp-ip);
262 lp -= 1;
263 } else {
264 ip += 1;
265 }
266 }
267
268 /* A relative policy path will end before the file extension.
269 For other objects only the directory name will be uses as
270 relative name. */
271 if (ifapi_path_type_p(path, IFAPI_POLICY_PATH))
272 fapi_path_delim = '.';
273 else
274 fapi_path_delim = IFAPI_FILE_DELIM_CHAR;
275
276 for (i = end_pos - 2; i > 0; i--) {
277 if (path[i] == fapi_path_delim) {
278 path[i] = '\0';
279 break;
280 }
281 }
282 }
283
284 /** Expand key store path.
285 *
286 * Depending on the type of the passed path the path will be expanded. For hierarchies
287 * the profile directory will be added. For keys the implicit path will
288 * be expanded to an explicit path with all directories.
289 * @param[in] keystore The key directories and default profile.
290 * @param[in] path the implicit path which has to be expanded if possible.
291 * @param[out] file_name The explicit path (callee-allocated)
292 * @retval TSS2_RC_SUCCESS If the explicit path was created.
293 * @retval TSS2_FAPI_RC_MEMORY: If memory for the path list could not be allocated.
294 * @retval TSS2_FAPI_RC_BAD_VALUE If no explicit path can be derived from the
295 * implicit path.
296 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
297 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
298 * or contains illegal characters.
299 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
300 * during authorization.
301 */
302 static TSS2_RC
expand_path(IFAPI_KEYSTORE * keystore,const char * path,char ** file_name)303 expand_path(IFAPI_KEYSTORE *keystore, const char *path, char **file_name)
304 {
305 TSS2_RC r;
306 NODE_STR_T *node_list = NULL;
307 size_t pos = 0;
308 *file_name = NULL;
309
310 check_not_null(path);
311
312 /* First it will be checked whether the only valid characters occur in the path. */
313 r = ifapi_check_valid_path(path);
314 return_if_error(r, "Invalid path.");
315
316 if (ifapi_hierarchy_path_p(path)) {
317 if (strncmp(path, "P_", 2) == 0 || strncmp(path, "/P_", 3) == 0) {
318 *file_name = strdup(path);
319 return_if_null(*file_name, "Out of memory", TSS2_FAPI_RC_MEMORY);
320 } else {
321 if (strncmp("/", path, 1) == 0)
322 pos = 1;
323 r = ifapi_asprintf(file_name, "/%s%s%s", keystore->defaultprofile,
324 IFAPI_FILE_DELIM, &path[pos]);
325 return_if_error(r, "Out of memory.");
326 }
327 } else if (ifapi_path_type_p(path, IFAPI_NV_PATH)
328 || ifapi_path_type_p(path, IFAPI_POLICY_PATH)
329 || ifapi_path_type_p(path, IFAPI_EXT_PATH)
330 || strncmp(path, "/P_", 3) == 0 || strncmp(path, "P_", 2) == 0) {
331 *file_name = strdup(path);
332 return_if_null(*file_name, "Out of memory", TSS2_FAPI_RC_MEMORY);
333
334 } else {
335 r = get_explicit_key_path(keystore, path, &node_list);
336 return_if_error(r, "Explicit key path cannot be determined.");
337
338 r = ifapi_path_string(file_name, NULL, node_list, NULL);
339 goto_if_error(r, "Out of memory", error);
340
341 free_string_list(node_list);
342 }
343
344 /* Normalize the pathname. '/' at the beginning no '/' at the end. */
345 if (strncmp(&(*file_name)[strlen(*file_name) - 1], "/", 1) == 0)
346 (*file_name)[strlen(*file_name) - 1] = '\0';
347 if (strncmp(&(*file_name)[0], "/", 1) != 0) {
348 char *aux_str = NULL;
349 aux_str = malloc(strlen(*file_name) + 2);
350 goto_if_null(aux_str, "Out of memory", TSS2_FAPI_RC_MEMORY, error);
351
352 aux_str[0] = '/';
353 memcpy(&aux_str[1], &(*file_name)[0], strlen(*file_name)+1);
354 SAFE_FREE(*file_name);
355 *file_name = aux_str;
356 }
357
358 return TSS2_RC_SUCCESS;
359
360 error:
361 SAFE_FREE(*file_name);
362 free_string_list(node_list);
363 return r;
364 }
365 /** Expand FAPI path to object path.
366 *
367 * The object file name will be appended and the implicit path will be expanded
368 * if possible.
369 * FAPI object path names correspond to directories of the key store. The
370 * objects are stored in a certain file in this directory. This function
371 * appends the name of the object file to the FAPI directory to prepare file IO.
372 * @retval TSS2_RC_SUCCESS If the object file path can be created.
373 * @retval TSS2_FAPI_RC_MEMORY: If memory for the path name cannot allocated.
374 * @retval TSS2_FAPI_RC_BAD_VALUE If no explicit path can be derived from the
375 * implicit path.
376 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
377 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
378 * or contains illegal characters.
379 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
380 * during authorization.
381 */
382 static TSS2_RC
expand_path_to_object(IFAPI_KEYSTORE * keystore,const char * path,const char * dir,char ** file_name)383 expand_path_to_object(
384 IFAPI_KEYSTORE *keystore,
385 const char *path,
386 const char *dir,
387 char **file_name)
388 {
389
390 TSS2_RC r;
391 char *expanded_path = NULL;
392
393 /* Expand implicit path to explicit path. */
394 r = expand_path(keystore, path, &expanded_path);
395 return_if_error(r, "Expand path");
396
397 /* Append object file. */
398 r = ifapi_asprintf(file_name, "%s/%s/%s", dir, expanded_path, IFAPI_OBJECT_FILE);
399 SAFE_FREE(expanded_path);
400 return r;
401 }
402
403 /** Store keystore parameters in the keystore context.
404 *
405 * Also the user directory will be created if it does not exist.
406 *
407 * @param[out] keystore The keystore to be initialized.
408 * @param[in] config_systemdir The configured system directory.
409 * @param[in] config_userdir The configured user directory.
410 * @param[in] config_defaultprofile The configured profile.
411 *
412 * @retval TSS2_RC_SUCCESS If the keystore can be initialized.
413 * @retval TSS2_FAPI_RC_IO_ERROR If the user part of the keystore can't be
414 * initialized.
415 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated.
416 * @retval TSS2_FAPI_RC_BAD_PATH if the home directory of the user
417 * cannot be determined.
418 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
419 * the function.
420 */
421 TSS2_RC
ifapi_keystore_initialize(IFAPI_KEYSTORE * keystore,const char * config_systemdir,const char * config_userdir,const char * config_defaultprofile)422 ifapi_keystore_initialize(
423 IFAPI_KEYSTORE *keystore,
424 const char *config_systemdir,
425 const char *config_userdir,
426 const char *config_defaultprofile)
427 {
428 TSS2_RC r;
429
430 memset(keystore, 0, sizeof(IFAPI_KEYSTORE));
431
432 /* Create user directory if necessary */
433 r = ifapi_io_check_create_dir(config_userdir, FAPI_WRITE);
434 goto_if_error2(r, "User directory %s can't be created.", error, keystore->userdir);
435
436 keystore->userdir = strdup(config_userdir);
437 goto_if_null2(keystore->userdir, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
438 error);
439
440 keystore->systemdir = strdup(config_systemdir);
441 goto_if_null2(keystore->systemdir, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
442 error);
443
444 keystore->defaultprofile = strdup(config_defaultprofile);
445 goto_if_null2(keystore->defaultprofile, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
446 error);
447
448 return TSS2_RC_SUCCESS;
449
450 error:
451 SAFE_FREE(keystore->defaultprofile);
452 SAFE_FREE(keystore->userdir);
453 SAFE_FREE(keystore->systemdir);
454 return r;
455 }
456
457 /** Get absolute object path for FAPI relative path and check whether file exists.
458 *
459 * It will be checked whether object exists in user directory, if no
460 * the path in system directory will be returnde
461 *
462 * @param[in] keystore The key directories and default profile.
463 * @param[in] rel_path The relative path of the object. For keys the path will
464 * expanded if possible.
465 * @param[out] abs_path The absolute path of the object.
466 * @retval TSS2_RC_SUCCESS If the object can be read.
467 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if the file does not exist (for key objects).
468 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if the file does not exist (for NV and hierarchy objects).
469 * @retval TSS2_FAPI_RC_IO_ERROR: If the file could not be read by the IO module.
470 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the read data.
471 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
472 * the function.
473 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
474 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
475 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
476 * or contains illegal characters.
477 */
478 static TSS2_RC
rel_path_to_abs_path(IFAPI_KEYSTORE * keystore,const char * rel_path,char ** abs_path)479 rel_path_to_abs_path(
480 IFAPI_KEYSTORE *keystore,
481 const char *rel_path,
482 char **abs_path)
483 {
484 TSS2_RC r;
485 char *directory = NULL;
486 bool provision_check_ok;
487
488 /* First expand path in user directory */
489 r = expand_path(keystore, rel_path, &directory);
490 goto_if_error(r, "Expand path", cleanup);
491
492 r = expand_path_to_object(keystore, directory,
493 keystore->userdir, abs_path);
494 goto_if_error2(r, "Object path %s could not be created.", cleanup, directory);
495
496
497 if (!ifapi_io_path_exists(*abs_path)) {
498 /* Second try system directory if object not found in user directory */
499 SAFE_FREE(*abs_path);
500 r = expand_path_to_object(keystore, directory,
501 keystore->systemdir, abs_path);
502 goto_if_error2(r, "Object path %s could not be created.", cleanup, directory);
503
504 if (ifapi_io_path_exists(*abs_path)) {
505 r = TSS2_RC_SUCCESS;
506 goto cleanup;
507 }
508
509 /* Check whether provisioning was made for the path profile. */
510 r = ifapi_check_provisioned(keystore, rel_path, &provision_check_ok);
511 goto_if_error(r, "Provisioning check.", cleanup);
512
513 if (!provision_check_ok) {
514 goto_error(r, TSS2_FAPI_RC_NOT_PROVISIONED,
515 "FAPI not provisioned for path: %s.",
516 cleanup, rel_path);
517 }
518
519 /* Check type of object which does not exist. */
520 if (ifapi_path_type_p(rel_path, IFAPI_NV_PATH)) {
521 /* NV directory does not exist. */
522 goto_error(r, TSS2_FAPI_RC_PATH_NOT_FOUND,
523 "File %s does not exist.",
524 cleanup, rel_path);
525 } else if (ifapi_hierarchy_path_p(rel_path)) {
526 /* Hierarchy which should be created during provisioning could not be loaded. */
527 goto_error(r, TSS2_FAPI_RC_PATH_NOT_FOUND,
528 "Hierarchy file %s does not exist.",
529 cleanup, rel_path);
530 } else {
531 /* Object file for key does not exist in keystore */
532 goto_error(r, TSS2_FAPI_RC_KEY_NOT_FOUND,
533 "Key %s not found.", cleanup, rel_path);
534 }
535 }
536
537 cleanup:
538 SAFE_FREE(directory);
539 return r;
540 }
541
542 /** Start loading FAPI object from key store.
543 *
544 * Keys objects, NV objects, and hierarchies can be loaded.
545 *
546 * @param[in] keystore The key directories and default profile.
547 * @param[in] io The input/output context being used for file I/O.
548 * @param[in] path The relative path of the object. For keys the path will
549 * expanded if possible.
550 * @retval TSS2_RC_SUCCESS If the object can be read.
551 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered.
552 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if the file does not exist.
553 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the read data.
554 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
555 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
556 * the function.
557 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
558 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
559 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
560 * or contains illegal characters.
561 */
562 TSS2_RC
ifapi_keystore_load_async(IFAPI_KEYSTORE * keystore,IFAPI_IO * io,const char * path)563 ifapi_keystore_load_async(
564 IFAPI_KEYSTORE *keystore,
565 IFAPI_IO *io,
566 const char *path)
567 {
568 TSS2_RC r;
569 char *abs_path = NULL;
570
571 LOG_TRACE("Load object: %s", path);
572
573 /* Free old input buffer if buffer exists */
574 SAFE_FREE(io->char_rbuffer);
575
576 /* Save relative directory path for storing in the object. */
577 strdup_check(keystore->rel_path, path, r, error_cleanup);
578
579 /* Convert relative path to absolute path in keystore */
580 r = rel_path_to_abs_path(keystore, path, &abs_path);
581 goto_if_error2(r, "Object %s not found.", error_cleanup, path);
582
583 /* Prepare read operation */
584 r = ifapi_io_read_async(io, abs_path);
585 goto_if_error2(r, "Read object %s", error_cleanup, path);
586 SAFE_FREE(abs_path);
587 return r;
588
589 error_cleanup:
590 SAFE_FREE(abs_path);
591 SAFE_FREE(keystore->rel_path);
592 return r;
593 }
594
595 /** Finish loading FAPI object from key store.
596 *
597 * This function needs to be called repeatedly until it does not return TSS2_FAPI_RC_TRY_AGAIN.
598 *
599 * @param[in] keystore The key directories and default profile.
600 * @param[in,out] io The input/output context being used for file I/O.
601 * @param[in] object The caller allocated object which will loaded from keystore.
602 * @retval TSS2_RC_SUCCESS After successfully loading the object.
603 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered; such as the file was not found.
604 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet complete.
605 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
606 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
607 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
608 * the function.
609 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
610 */
611 TSS2_RC
ifapi_keystore_load_finish(IFAPI_KEYSTORE * keystore MAYBE_UNUSED,IFAPI_IO * io,IFAPI_OBJECT * object)612 ifapi_keystore_load_finish(
613 IFAPI_KEYSTORE *keystore MAYBE_UNUSED,
614 IFAPI_IO *io,
615 IFAPI_OBJECT *object)
616 {
617 TSS2_RC r;
618 json_object *jso = NULL;
619 uint8_t *buffer = NULL;
620
621 r = ifapi_io_read_finish(io, &buffer, NULL);
622 return_try_again(r);
623 return_if_error(r, "keystore read_finish failed");
624
625 /* If json objects can't be parse the object store is corrupted */
626 jso = json_tokener_parse((char *)buffer);
627 SAFE_FREE(buffer);
628 goto_if_null2(jso, "Keystore is corrupted (Json error).", r, TSS2_FAPI_RC_GENERAL_FAILURE,
629 error_cleanup);
630
631 r = ifapi_json_IFAPI_OBJECT_deserialize(jso, object);
632 goto_if_error(r, "Deserialize object.", error_cleanup);
633
634 object->rel_path = keystore->rel_path;
635 SAFE_FREE(buffer);
636 if (jso)
637 json_object_put(jso);
638 LOG_TRACE("Return %x", r);
639 return r;
640
641 error_cleanup:
642 SAFE_FREE(buffer);
643 if (jso)
644 json_object_put(jso);
645 LOG_TRACE("Return %x", r);
646 SAFE_FREE(keystore->rel_path);
647 return r;
648 }
649
650 /** Start writing FAPI object to the key store.
651 *
652 * Keys objects, NV objects, and hierarchies can be written.
653 *
654 * @param[in] keystore The key directories and default profile.
655 * @param[in] io The input/output context being used for file I/O.
656 * @param[in] path The relative path of the object. For keys the path will
657 * expanded if possible.
658 * @param[in] object The object to be written to the keystore.
659 * @retval TSS2_RC_SUCCESS if the object is written successfully.
660 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered;
661 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the output data.
662 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
663 * the function.
664 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
665 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
666 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
667 * or contains illegal characters.
668 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
669 * during authorization.
670 */
671 TSS2_RC
ifapi_keystore_store_async(IFAPI_KEYSTORE * keystore,IFAPI_IO * io,const char * path,const IFAPI_OBJECT * object)672 ifapi_keystore_store_async(
673 IFAPI_KEYSTORE *keystore,
674 IFAPI_IO *io,
675 const char *path,
676 const IFAPI_OBJECT *object)
677 {
678 TSS2_RC r;
679 char *directory = NULL;
680 char *file = NULL;
681 char *jso_string = NULL;
682 json_object *jso = NULL;
683
684 LOG_TRACE("Store object: %s", path);
685
686 /* Prepare write operation: Create directories and valid object path */
687 r = expand_path(keystore, path, &directory);
688 goto_if_error(r, "Expand path", cleanup);
689
690 if (object->system) {
691 r = ifapi_create_dirs(keystore->systemdir, directory);
692 goto_if_error2(r, "Directory %s could not be created.", cleanup, directory);
693
694 r = expand_path_to_object(keystore, directory,
695 keystore->systemdir, &file);
696 } else {
697 r = ifapi_create_dirs(keystore->userdir, directory);
698 goto_if_error2(r, "Directory %s could not be created.", cleanup, directory);
699
700 r = expand_path_to_object(keystore, directory,
701 keystore->userdir, &file);
702 }
703 goto_if_error2(r, "Object path %s could not be created.", cleanup, directory);
704
705 /* Generate JSON string to be written to store */
706 r = ifapi_json_IFAPI_OBJECT_serialize(object, &jso);
707 goto_if_error2(r, "Object for %s could not be serialized.", cleanup, file);
708
709 jso_string = strdup(json_object_to_json_string_ext(jso,
710 JSON_C_TO_STRING_PRETTY));
711 goto_if_null2(jso_string, "Converting json to string", r, TSS2_FAPI_RC_MEMORY,
712 cleanup);
713
714 /* Start writing the json string to disk */
715 r = ifapi_io_write_async(io, file, (uint8_t *) jso_string, strlen(jso_string));
716 free(jso_string);
717 goto_if_error(r, "write_async failed", cleanup);
718
719 cleanup:
720 if (jso)
721 json_object_put(jso);
722 SAFE_FREE(directory);
723 SAFE_FREE(file);
724 return r;
725 }
726
727 /** Check whether the key path for a new object does not exist in key store.
728 *
729 * To prevent overwriting of objects the functions returns an error
730 * if the object is already stored in key store.
731 * The FAPI path will be expanded to absolute path appropriate for
732 * the object to be checked.
733 *
734 * @param[in] keystore The key directories and default profile.
735 * @param[in] path The relative path of the object. For keys the path will
736 * expanded if possible.
737 * @param[in] object The object to be checked.
738 * @retval TSS2_RC_SUCCESS if the object does not exist and a new object
739 * can be written.
740 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS: if the object exists in key store.
741 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the output data.
742 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
743 * the function.
744 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
745 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
746 * or contains illegal characters.
747 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
748 * during authorization.
749 */
750 TSS2_RC
ifapi_keystore_object_does_not_exist(IFAPI_KEYSTORE * keystore,const char * path,const IFAPI_OBJECT * object)751 ifapi_keystore_object_does_not_exist(
752 IFAPI_KEYSTORE *keystore,
753 const char *path,
754 const IFAPI_OBJECT *object)
755 {
756 TSS2_RC r;
757 char *directory = NULL;
758 char *file = NULL;
759
760 LOG_TRACE("Store object: %s", path);
761
762 /* Prepare write operation: Create directories and valid object path */
763 r = expand_path(keystore, path, &directory);
764 goto_if_error(r, "Expand path", cleanup);
765
766 if (object->system) {
767 r = expand_path_to_object(keystore, directory,
768 keystore->systemdir, &file);
769 } else {
770 r = expand_path_to_object(keystore, directory,
771 keystore->userdir, &file);
772 }
773
774 goto_if_error2(r, "Object path %s could not be created.", cleanup, directory);
775
776 if (ifapi_io_path_exists(file)) {
777 goto_error(r, TSS2_FAPI_RC_PATH_ALREADY_EXISTS, "File %s already exists.", cleanup, file);
778 }
779
780 cleanup:
781 SAFE_FREE(directory);
782 SAFE_FREE(file);
783 return r;
784 }
785
786 /** Finish writing a FAPI object to the keystore.
787 *
788 * This function needs to be called repeatedly until it does not return TSS2_FAPI_RC_TRY_AGAIN.
789 *
790 * @param[in,out] io The input/output context being used for file I/O.
791 * @retval TSS2_RC_SUCCESS: if the function call was a success.
792 * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered; such as the file was not found.
793 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet complete.
794 * Call this function again later.
795 */
796 TSS2_RC
ifapi_keystore_store_finish(IFAPI_IO * io)797 ifapi_keystore_store_finish(
798 IFAPI_IO *io)
799 {
800 TSS2_RC r;
801
802 /* Finish writing the object */
803 r = ifapi_io_write_finish(io);
804 return_try_again(r);
805
806 LOG_TRACE("Return %x", r);
807 return_if_error(r, "read_finish failed");
808
809 return TSS2_RC_SUCCESS;
810 }
811
812 /** Create a list of all files in a certain directory.
813 *
814 * The list will be created in form of absolute pathnames.
815 *
816 * @param[in] keystore The key directories and default profile.
817 * @param[in] searchpath The sub directory in key store used for the
818 * creation of the file list.
819 * @param[out] results The array of all absolute pathnames.
820 * @param[out] numresults The number of files.
821 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
822 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
823 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
824 * or contains illegal characters.
825 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
826 * the function.
827 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
828 * during authorization.
829 */
830 static TSS2_RC
keystore_list_all_abs(IFAPI_KEYSTORE * keystore,const char * searchpath,char *** results,size_t * numresults)831 keystore_list_all_abs(
832 IFAPI_KEYSTORE *keystore,
833 const char *searchpath,
834 char ***results,
835 size_t *numresults)
836 {
837 TSS2_RC r;
838 char *expanded_search_path = NULL, *full_search_path = NULL;
839 size_t num_paths_system, num_paths_user, i, j;
840 char **file_ary, **file_ary_system, **file_ary_user;
841
842 *numresults = 0;
843 file_ary_user = NULL;
844 file_ary_system = NULL;
845
846 if (!searchpath || strcmp(searchpath, "") == 0 || strcmp(searchpath, "/") == 0) {
847 /* The complete keystore will be listed, no path expansion */
848 expanded_search_path = NULL;
849 } else {
850 r = expand_path(keystore, searchpath, &expanded_search_path);
851 return_if_error(r, "Expand path.");
852 }
853
854 /* Get the objects from system store */
855 r = ifapi_asprintf(&full_search_path, "%s%s", keystore->systemdir,
856 expanded_search_path ? expanded_search_path : "");
857 goto_if_error(r, "Out of memory.", cleanup);
858
859 r = ifapi_io_dirfiles_all(full_search_path, &file_ary_system, &num_paths_system);
860 goto_if_error(r, "Get all files in directory.", cleanup);
861 SAFE_FREE(full_search_path);
862
863 /* Get the objects from user store */
864 r = ifapi_asprintf(&full_search_path, "%s%s", keystore->userdir,
865 expanded_search_path ? expanded_search_path : "");
866 goto_if_error(r, "Out of memory.", cleanup);
867
868 r = ifapi_io_dirfiles_all(full_search_path, &file_ary_user, &num_paths_user);
869
870 *numresults = num_paths_system + num_paths_user;
871 SAFE_FREE(full_search_path);
872
873 if (*numresults > 0) {
874
875 /* Move file names from list to combined array */
876 file_ary = calloc(*numresults, sizeof(char *));
877 goto_if_null(file_ary, "Out of memory.", TSS2_FAPI_RC_MEMORY,
878 cleanup);
879 i = 0;
880 for (j = 0; j < num_paths_system; j++)
881 file_ary[i++] = file_ary_system[j];
882 for (j = 0; j < num_paths_user; j++)
883 file_ary[i++] = file_ary_user[j];
884
885 SAFE_FREE(file_ary_system);
886 SAFE_FREE(file_ary_user);
887 SAFE_FREE(expanded_search_path);
888 *results = file_ary;
889 }
890
891 cleanup:
892 SAFE_FREE(file_ary_system);
893 SAFE_FREE(file_ary_user);
894 SAFE_FREE(expanded_search_path);
895 SAFE_FREE(full_search_path);
896 return r;
897 }
898
899 /** Create a list of of objects in a certain search path.
900 *
901 * A vector of relative paths will be computed.
902 *
903 * @param[in] keystore The key directories, the default profile.
904 * @param[in] searchpath The relative search path in key store.
905 * @param[out] results The array with pointers to the relative object paths.
906 * @param[out] numresults The number of found objects.
907 * @retval TSS2_RC_SUCCESS on success.
908 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated.
909 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
910 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
911 * or contains illegal characters.
912 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
913 * the function.
914 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
915 * during authorization.
916 */
917 TSS2_RC
ifapi_keystore_list_all(IFAPI_KEYSTORE * keystore,const char * searchpath,char *** results,size_t * numresults)918 ifapi_keystore_list_all(
919 IFAPI_KEYSTORE *keystore,
920 const char *searchpath,
921 char ***results,
922 size_t *numresults)
923 {
924 TSS2_RC r;
925 size_t i;
926
927 r = keystore_list_all_abs(keystore, searchpath, results, numresults);
928 return_if_error(r, "Get all keystore objects.");
929
930 if (*numresults > 0) {
931 /* Convert absolute path to relative path */
932 for (i = 0; i < *numresults; i++) {
933 full_path_to_fapi_path(keystore, (*results)[i]);
934 }
935 }
936 return r;
937 }
938
939 /** Remove file storing a keystore object.
940 *
941 * @param[in] keystore The key directories, the default profile.
942 * @param[in] path The relative name of the object be removed.
943 * @retval TSS2_RC_SUCCESS On success.
944 * @retval TSS2_FAPI_RC_MEMORY: If memory could not be allocated.
945 * @retval TSS2_FAPI_RC_IO_ERROR If the file can't be removed.
946 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
947 * during authorization.
948 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
949 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
950 * the function.
951 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
952 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
953 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
954 * or contains illegal characters.
955 */
956 TSS2_RC
ifapi_keystore_delete(IFAPI_KEYSTORE * keystore,char * path)957 ifapi_keystore_delete(
958 IFAPI_KEYSTORE * keystore,
959 char *path)
960 {
961 TSS2_RC r;
962 char *abs_path = NULL;
963
964 /* Convert relative path to absolute path in keystore */
965 r = rel_path_to_abs_path(keystore, path, &abs_path);
966 goto_if_error2(r, "Object %s not found.", cleanup, path);
967
968 r = ifapi_io_remove_file(abs_path);
969
970 cleanup:
971 SAFE_FREE(abs_path);
972 return r;
973 }
974
975 /** Expand directory name.
976 *
977 * Depending on the directory type the path will be expanded. For hierarchies
978 * the profile directory will be added. For keys the implicit path will
979 * be expanded to an explicit path with all directories.
980 * @param[in] keystore The key directories and default profile.
981 * @param[in] path the implicit path which has to be expanded if possible.
982 * @param[out] directory_name The explicit path (callee-allocated)
983 * @retval TSS2_RC_SUCCESS If the explicit path was created.
984 * @retval TSS2_FAPI_RC_MEMORY: If memory for the path list could not be allocated.
985 * @retval TSS2_FAPI_RC_BAD_VALUE If no explicit path can be derived from the
986 * implicit path.
987 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
988 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
989 * or contains illegal characters.
990 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
991 * during authorization.
992 */
993 static TSS2_RC
expand_directory(IFAPI_KEYSTORE * keystore,const char * path,char ** directory_name)994 expand_directory(IFAPI_KEYSTORE *keystore, const char *path, char **directory_name)
995 {
996 TSS2_RC r;
997
998 if (path && strcmp(path, "") != 0 && strcmp(path, "/") != 0) {
999 size_t start_pos = 0;
1000 if (path[0] == IFAPI_FILE_DELIM_CHAR)
1001 start_pos = 1;
1002 if ((strncmp(&path[start_pos], "HS", 2) == 0 ||
1003 strncmp(&path[start_pos], "HN", 2) == 0 ||
1004 strncmp(&path[start_pos], "HE", 2) == 0) &&
1005 strlen(&path[start_pos]) <= 3) {
1006 /* Root directory is hierarchy */
1007 r = ifapi_asprintf(directory_name, "/%s/%s/", keystore->defaultprofile,
1008 &path[start_pos]);
1009 return_if_error(r, "Out of memory.");
1010
1011 } else {
1012 /* Try to expand a key path */
1013 r = expand_path(keystore, path, directory_name);
1014 return_if_error(r, "Expand path.");
1015 }
1016 } else {
1017 *directory_name = NULL;
1018 }
1019 return TSS2_RC_SUCCESS;
1020 }
1021
1022 /** Remove directories in keystore.
1023 *
1024 * If the expanded directory exists in userdir and systemdir both will be deleted.
1025 *
1026 * @param[in] keystore The key directories, the default profile.
1027 * @param[in] dir_name The relative name of the directory to be removed.
1028 * @retval TSS2_RC_SUCCESS on success.
1029 * @retval TSS2_FAPI_RC_MEMORY: If memory could not be allocated.
1030 * @retval TSS2_FAPI_RC_IO_ERROR If directory can't be deleted.
1031 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1032 * the function.
1033 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1034 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
1035 * or contains illegal characters.
1036 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
1037 * during authorization.
1038 */
1039 TSS2_RC
ifapi_keystore_remove_directories(IFAPI_KEYSTORE * keystore,const char * dir_name)1040 ifapi_keystore_remove_directories(IFAPI_KEYSTORE *keystore, const char *dir_name)
1041 {
1042 TSS2_RC r = TSS2_RC_SUCCESS;
1043 char *absolute_dir_path = NULL;
1044 char *exp_dir_name = NULL;
1045 struct stat fbuffer;
1046 size_t pos;
1047
1048 r = expand_directory(keystore, dir_name, &exp_dir_name);
1049 return_if_error(r, "Expand path string.");
1050
1051 /* Cleanup user part of the store */
1052 if (keystore->userdir[strlen(keystore->userdir) - 1] == '/')
1053 pos = 1;
1054 else
1055 pos = 0;
1056 r = ifapi_asprintf(&absolute_dir_path, "%s%s", keystore->userdir,
1057 exp_dir_name ? &exp_dir_name[pos] : "");
1058 goto_if_error(r, "Out of memory.", cleanup);
1059
1060 if (stat(absolute_dir_path, &fbuffer) == 0) {
1061 r = ifapi_io_remove_directories(absolute_dir_path, keystore->userdir, NULL);
1062 goto_if_error2(r, "Could not remove: %s", cleanup, absolute_dir_path);
1063 }
1064 SAFE_FREE(absolute_dir_path);
1065
1066 /* Cleanup system part of the store */
1067 if (keystore->systemdir[strlen(keystore->systemdir) - 1] == '/')
1068 /* For a final slash in system dir the startin slash of the
1069 expanded path will be ignored. */
1070 pos = 1;
1071 else
1072 pos = 0;
1073 r = ifapi_asprintf(&absolute_dir_path, "%s%s", keystore->systemdir,
1074 exp_dir_name ? &exp_dir_name[pos] : "");
1075 goto_if_error(r, "Out of memory.", cleanup);
1076
1077 if (stat(absolute_dir_path, &fbuffer) == 0) {
1078 r = ifapi_io_remove_directories(absolute_dir_path, keystore->systemdir,
1079 "/" IFAPI_POLICY_DIR);
1080 goto_if_error2(r, "%s cannot be deleted.", cleanup, absolute_dir_path);
1081 }
1082
1083 cleanup:
1084 SAFE_FREE(absolute_dir_path);
1085 SAFE_FREE(exp_dir_name);
1086 return r;
1087 }
1088
1089 /** Predicate used as function parameter for object searching in keystore.
1090 *
1091 * @param[in] object The object from keystore which has to be compared.
1092 * @param[in] cmp_object The object which will used for the comparison,
1093 * by the function with this signature.
1094 * @retval true if the comparison is successful.
1095 * @retval true if the comparison is not successful.
1096 */
1097 typedef TSS2_RC (*ifapi_keystore_object_cmp) (
1098 IFAPI_OBJECT *object,
1099 void *cmp_object,
1100 bool *equal);
1101
1102 /** Search object with a certain propoerty in keystore.
1103 *
1104 * @param[in,out] keystore The key directories, the default profile, and the
1105 * state information for the asynchronous search.
1106 * @param[in] io The input/output context being used for file I/O.
1107 * @param[in] name The name of the searched key.
1108 * @param[out] found_path The relative path of the found key.
1109 * @retval TSS2_RC_SUCCESS on success.
1110 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated.
1111 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND If the key was not found in keystore.
1112 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
1113 * during authorization.
1114 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1115 * this function needs to be called again.
1116 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1117 * operation already pending.
1118 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1119 * the function.
1120 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
1121 * object store.
1122 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1123 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1124 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
1125 * or contains illegal characters.
1126 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
1127 */
1128 static TSS2_RC
keystore_search_obj(IFAPI_KEYSTORE * keystore,IFAPI_IO * io,void * cmp_object,ifapi_keystore_object_cmp cmp_function,char ** found_path)1129 keystore_search_obj(
1130 IFAPI_KEYSTORE *keystore,
1131 IFAPI_IO *io,
1132 void *cmp_object,
1133 ifapi_keystore_object_cmp cmp_function,
1134 char **found_path)
1135 {
1136 TSS2_RC r;
1137 UINT32 path_idx;
1138 char *path;
1139 IFAPI_OBJECT object;
1140 size_t i;
1141
1142 switch (keystore->key_search.state) {
1143 statecase(keystore->key_search.state, KSEARCH_INIT)
1144 r = ifapi_keystore_list_all(keystore,
1145 "/", /**< search keys and NV objects in store */
1146 &keystore->key_search.pathlist,
1147 &keystore->key_search.numPaths);
1148 goto_if_error2(r, "Get entities.", cleanup);
1149
1150 keystore->key_search.path_idx = keystore->key_search.numPaths;
1151 fallthrough;
1152
1153 statecase(keystore->key_search.state, KSEARCH_SEARCH_OBJECT)
1154 /* Use the next object in the path list */
1155 if (keystore->key_search.path_idx == 0) {
1156 goto_error(r, TSS2_FAPI_RC_PATH_NOT_FOUND, "Key not found.", cleanup);
1157 }
1158 keystore->key_search.path_idx -= 1;
1159 path_idx = keystore->key_search.path_idx;
1160 path = keystore->key_search.pathlist[path_idx];
1161 LOG_TRACE("Check file: %s %zu", path, keystore->key_search.path_idx);
1162
1163 /* Skip policy files. */
1164 if (ifapi_path_type_p(path, IFAPI_POLICY_PATH)) {
1165 return TSS2_FAPI_RC_TRY_AGAIN;
1166 }
1167
1168 r = ifapi_keystore_load_async(keystore, io, path);
1169 return_if_error2(r, "Could not open: %s", path);
1170
1171 fallthrough;
1172
1173 statecase(keystore->key_search.state, KSEARCH_READ)
1174 r = ifapi_keystore_load_finish(keystore, io, &object);
1175 return_try_again(r);
1176 goto_if_error(r, "read_finish failed", cleanup);
1177
1178 /* Check whether the key has the passed name */
1179 bool keys_equal;
1180 r = cmp_function(&object, cmp_object, &keys_equal);
1181 ifapi_cleanup_ifapi_object(&object);
1182 goto_if_error(r, "Invalid object.", cleanup);
1183
1184 if (!keys_equal) {
1185 /* Try next key */
1186 keystore->key_search.state = KSEARCH_SEARCH_OBJECT;
1187 return TSS2_FAPI_RC_TRY_AGAIN;
1188 }
1189 /* Key found, the absolute path will be converted to relative path. */
1190 path_idx = keystore->key_search.path_idx;
1191 *found_path = strdup(keystore->key_search.pathlist[path_idx]);
1192 goto_if_null(*found_path, "Out of memory.",
1193 TSS2_FAPI_RC_MEMORY, cleanup);
1194 full_path_to_fapi_path(keystore, *found_path);
1195 break;
1196
1197 statecasedefault(keystore->key_search.state);
1198 }
1199 cleanup:
1200 for (i = 0; i < keystore->key_search.numPaths; i++)
1201 free(keystore->key_search.pathlist[i]);
1202 free(keystore->key_search.pathlist);
1203 if (!*found_path) {
1204 LOG_ERROR("Object not found");
1205 r = TSS2_FAPI_RC_KEY_NOT_FOUND;
1206 }
1207 keystore->key_search.state = KSEARCH_INIT;
1208 return r;
1209 }
1210
1211 /** Search object with a certain name in keystore.
1212 *
1213 * @param[in,out] keystore The key directories, the default profile, and the
1214 * state information for the asynchronous search.
1215 * @param[in] io The input/output context being used for file I/O.
1216 * @param[in] name The name of the searched object.
1217 * @param[out] found_path The relative path of the found key.
1218 * @retval TSS2_RC_SUCCESS on success.
1219 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated.
1220 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND If the key was not found in keystore.
1221 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
1222 * during authorization.
1223 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1224 * this function needs to be called again.
1225 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1226 * operation already pending.
1227 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1228 * the function.
1229 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
1230 * object store.
1231 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1232 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1233 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
1234 * or contains illegal characters.
1235 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
1236 */
1237 TSS2_RC
ifapi_keystore_search_obj(IFAPI_KEYSTORE * keystore,IFAPI_IO * io,TPM2B_NAME * name,char ** found_path)1238 ifapi_keystore_search_obj(
1239 IFAPI_KEYSTORE *keystore,
1240 IFAPI_IO *io,
1241 TPM2B_NAME *name,
1242 char **found_path)
1243 {
1244 return keystore_search_obj(keystore, io, name,
1245 ifapi_object_cmp_name, found_path);
1246 }
1247
1248 /** Search nv object with a certain nv_index (from nv_public) in keystore.
1249 *
1250 * @param[in,out] keystore The key directories, the default profile, and the
1251 * state information for the asynchronous search.
1252 * @param[in] io The input/output context being used for file I/O.
1253 * @param[in] nv_public The public data of the searched nv object.
1254 * @param[out] found_path The relative path of the found key.
1255 * @retval TSS2_RC_SUCCESS on success.
1256 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated.
1257 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND If the key was not found in keystore.
1258 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1259 * the function.
1260 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
1261 * during authorization.
1262 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
1263 * this function needs to be called again.
1264 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
1265 * operation already pending.
1266 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
1267 * object store.
1268 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
1269 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1270 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS if the object already exists in object store.
1271 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
1272 * or contains illegal characters.
1273 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
1274 */
1275 TSS2_RC
ifapi_keystore_search_nv_obj(IFAPI_KEYSTORE * keystore,IFAPI_IO * io,TPM2B_NV_PUBLIC * nv_public,char ** found_path)1276 ifapi_keystore_search_nv_obj(
1277 IFAPI_KEYSTORE *keystore,
1278 IFAPI_IO *io,
1279 TPM2B_NV_PUBLIC *nv_public,
1280 char **found_path)
1281 {
1282 return keystore_search_obj(keystore, io, nv_public,
1283 ifapi_object_cmp_nv_public, found_path);
1284 }
1285
1286 /** Check whether keystore object already exists.
1287 *
1288 * The passed relative path will be expanded for user store and system store.
1289 *
1290 * @param[in] keystore The key directories and default profile.
1291 * @param[in] path The relative path of the object. For keys the path will
1292 * expanded if possible.
1293 * @retval TSS2_RC_SUCCESS if the object does not exist.
1294 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS if the file exists in the keystore.
1295 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the output data.
1296 */
1297 TSS2_RC
ifapi_keystore_check_overwrite(IFAPI_KEYSTORE * keystore,const char * path)1298 ifapi_keystore_check_overwrite(
1299 IFAPI_KEYSTORE *keystore,
1300 const char *path)
1301 {
1302 TSS2_RC r;
1303 char *directory = NULL;
1304 char *file = NULL;
1305
1306 /* Expand relative path */
1307 r = expand_path(keystore, path, &directory);
1308 goto_if_error(r, "Expand path", cleanup);
1309
1310 /* Expand absolute path for user and system directory */
1311 r = expand_path_to_object(keystore, directory,
1312 keystore->systemdir, &file);
1313 goto_if_error(r, "Expand path to object", cleanup);
1314
1315 if (ifapi_io_path_exists(file)) {
1316 goto_error(r, TSS2_FAPI_RC_PATH_ALREADY_EXISTS,
1317 "Object %s already exists.", cleanup, path);
1318 }
1319 SAFE_FREE(file);
1320 r = expand_path_to_object(keystore, directory,
1321 keystore->userdir, &file);
1322 goto_if_error(r, "Expand path to object", cleanup);
1323
1324 if (ifapi_io_path_exists(file)) {
1325 goto_error(r, TSS2_FAPI_RC_PATH_ALREADY_EXISTS,
1326 "Object %s already exists.", cleanup, path);
1327 }
1328 r = TSS2_RC_SUCCESS;
1329
1330 cleanup:
1331 SAFE_FREE(directory);
1332 SAFE_FREE(file);
1333 return r;
1334 }
1335
1336 /** Check whether keystore object is writeable.
1337 *
1338 * The passed relative path will be expanded first for user store, second for
1339 * system store if the file does not exist in system store.
1340 *
1341 * Keys objects, NV objects, and hierarchies can be written.
1342 *
1343 * @param[in] keystore The key directories and default profile.
1344 * @param[in] path The relative path of the object. For keys the path will
1345 * expanded if possible.
1346 * @retval TSS2_RC_SUCCESS if the object does not exist.
1347 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS if the file in objects exists.
1348 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the output data.
1349 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
1350 * the function.
1351 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
1352 * object store.
1353 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1354 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
1355 * or contains illegal characters.
1356 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
1357 * during authorization.
1358 */
1359 TSS2_RC
ifapi_keystore_check_writeable(IFAPI_KEYSTORE * keystore,const char * path)1360 ifapi_keystore_check_writeable(
1361 IFAPI_KEYSTORE *keystore,
1362 const char *path)
1363 {
1364 TSS2_RC r;
1365 char *directory = NULL;
1366 char *file = NULL;
1367
1368 /* Expand relative path */
1369 r = expand_path(keystore, path, &directory);
1370 goto_if_error(r, "Expand path", cleanup);
1371
1372 /* Expand absolute path for user and system directory */
1373 r = expand_path_to_object(keystore, directory,
1374 keystore->userdir, &file);
1375 goto_if_error(r, "Expand path to object", cleanup);
1376
1377 if (ifapi_io_path_exists(file)) {
1378 r = ifapi_io_check_file_writeable(file);
1379 goto_if_error2(r, "Object %s is not writable.", cleanup, path);
1380
1381 /* File can be written */
1382 goto cleanup;
1383 } else {
1384 SAFE_FREE(file);
1385 r = expand_path_to_object(keystore, directory,
1386 keystore->systemdir, &file);
1387 goto_if_error(r, "Expand path to object", cleanup);
1388
1389 if (ifapi_io_path_exists(file)) {
1390 r = ifapi_io_check_file_writeable(file);
1391 goto_if_error2(r, "Object %s is not writable.", cleanup, path);
1392
1393 /* File can be written */
1394 goto cleanup;
1395 }
1396 }
1397
1398 cleanup:
1399 SAFE_FREE(directory);
1400 SAFE_FREE(file);
1401 return r;
1402 }
1403
1404 /** Create a copy of a an UINT8 array..
1405 *
1406 * @param[out] dest The caller allocated array which will be the
1407 * destination of the copy operation.
1408 * @param[in] src The source array.
1409 *
1410 * @retval TSS2_RC_SUCCESS if the function call was a success.
1411 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1412 */
1413 static TSS2_RC
copy_uint8_ary(UINT8_ARY * dest,const UINT8_ARY * src)1414 copy_uint8_ary(UINT8_ARY *dest, const UINT8_ARY * src) {
1415 TSS2_RC r = TSS2_RC_SUCCESS;
1416
1417 /* Check the parameters if they are valid */
1418 if (src == NULL || dest == NULL) {
1419 return TSS2_FAPI_RC_BAD_REFERENCE;
1420 }
1421
1422 /* Initialize the object variables for a possible error cleanup */
1423 dest->buffer = NULL;
1424
1425 /* Create the copy */
1426 dest->size = src->size;
1427 dest->buffer = malloc(dest->size);
1428 goto_if_null(dest->buffer, "Out of memory.", r, error_cleanup);
1429 memcpy(dest->buffer, src->buffer, dest->size);
1430
1431 return r;
1432
1433 error_cleanup:
1434 SAFE_FREE(dest->buffer);
1435 return r;
1436 }
1437
1438 /** Create a copy of a an ifapi key.
1439 *
1440 * @param[out] dest The caller allocated key object which will be the
1441 * destination of the copy operation.
1442 * @param[in] src The source key.
1443 *
1444 * @retval TSS2_RC_SUCCESS if the function call was a success.
1445 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1446 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1447 */
1448 TSS2_RC
ifapi_copy_ifapi_key(IFAPI_KEY * dest,const IFAPI_KEY * src)1449 ifapi_copy_ifapi_key(IFAPI_KEY * dest, const IFAPI_KEY * src) {
1450 TSS2_RC r = TSS2_RC_SUCCESS;
1451
1452 /* Check the parameters if they are valid */
1453 if (src == NULL || dest == NULL) {
1454 return TSS2_FAPI_RC_BAD_REFERENCE;
1455 }
1456
1457 /* Initialize the object variables for a possible error cleanup */
1458 dest->private.buffer = NULL;
1459 dest->serialization.buffer = NULL;
1460 dest->appData.buffer = NULL;
1461 dest->policyInstance = NULL;
1462 dest->description = NULL;
1463
1464 /* Create the copy */
1465
1466 r = copy_uint8_ary(&dest->private, &src->private);
1467 goto_if_error(r, "Could not copy private", error_cleanup);
1468 r = copy_uint8_ary(&dest->serialization, &src->serialization);
1469 goto_if_error(r, "Could not copy serialization", error_cleanup);
1470 r = copy_uint8_ary(&dest->appData, &src->appData);
1471 goto_if_error(r, "Could not copy appData", error_cleanup);
1472
1473 strdup_check(dest->policyInstance, src->policyInstance, r, error_cleanup);
1474 strdup_check(dest->description, src->description, r, error_cleanup);
1475 strdup_check(dest->certificate, src->certificate, r, error_cleanup);
1476
1477 dest->persistent_handle = src->persistent_handle;
1478 dest->public = src->public;
1479 dest->creationData = src->creationData;
1480 dest->creationTicket = src->creationTicket;
1481 dest->signing_scheme = src->signing_scheme;
1482 dest->name = src->name;
1483 dest->with_auth = src->with_auth;
1484
1485 return r;
1486
1487 error_cleanup:
1488 ifapi_cleanup_ifapi_key(dest);
1489 return r;
1490 }
1491
1492 /** Create a copy of a an ifapi hierarchy.
1493 *
1494 * @param[out] dest The caller allocated hierarchy object which will be the
1495 * destination of the copy operation.
1496 * @param[in] src The source hierarchy.
1497 *
1498 * @retval TSS2_RC_SUCCESS if the function call was a success.
1499 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1500 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1501 */
1502 TSS2_RC
ifapi_copy_ifapi_hierarchy(IFAPI_HIERARCHY * dest,const IFAPI_HIERARCHY * src)1503 ifapi_copy_ifapi_hierarchy(IFAPI_HIERARCHY * dest, const IFAPI_HIERARCHY * src) {
1504 TSS2_RC r = TSS2_RC_SUCCESS;
1505
1506 /* Check the parameters if they are valid */
1507 if (src == NULL || dest == NULL) {
1508 return TSS2_FAPI_RC_BAD_REFERENCE;
1509 }
1510
1511 /* Initialize the object variables for a possible error cleanup */
1512 dest->description = NULL;
1513
1514 strdup_check(dest->description, src->description, r, error_cleanup);
1515 dest->with_auth = src->with_auth;
1516 dest->authPolicy = src->authPolicy;
1517
1518 return r;
1519
1520 error_cleanup:
1521 ifapi_cleanup_ifapi_hierarchy(dest);
1522 return r;
1523 }
1524
1525 /** Free memory allocated during deserialization of a key object.
1526 *
1527 * The key will not be freed (might be declared on the stack).
1528 *
1529 * @param[in] key The key object to be cleaned up.
1530 *
1531 */
1532 void
ifapi_cleanup_ifapi_key(IFAPI_KEY * key)1533 ifapi_cleanup_ifapi_key(IFAPI_KEY * key) {
1534 if (key != NULL) {
1535 SAFE_FREE(key->policyInstance);
1536 SAFE_FREE(key->serialization.buffer);
1537 SAFE_FREE(key->private.buffer);
1538 SAFE_FREE(key->description);
1539 SAFE_FREE(key->certificate);
1540 SAFE_FREE(key->appData.buffer);
1541 }
1542 }
1543
1544 /** Free memory allocated during deserialization of a pubkey object.
1545 *
1546 * The pubkey will not be freed (might be declared on the stack).
1547 *
1548 * @param[in] key The pubkey object to be cleaned up.
1549 */
1550 void
ifapi_cleanup_ifapi_ext_pub_key(IFAPI_EXT_PUB_KEY * key)1551 ifapi_cleanup_ifapi_ext_pub_key(IFAPI_EXT_PUB_KEY * key) {
1552 if (key != NULL) {
1553 SAFE_FREE(key->pem_ext_public);
1554 SAFE_FREE(key->certificate);
1555 }
1556 }
1557
1558 /** Free memory allocated during deserialization of a hierarchy object.
1559 *
1560 * The hierarchy object will not be freed (might be declared on the stack).
1561 *
1562 * @param[in] hierarchy The hierarchy object to be cleaned up.
1563 */
1564 void
ifapi_cleanup_ifapi_hierarchy(IFAPI_HIERARCHY * hierarchy)1565 ifapi_cleanup_ifapi_hierarchy(IFAPI_HIERARCHY * hierarchy) {
1566 if (hierarchy != NULL) {
1567 SAFE_FREE(hierarchy->description);
1568 }
1569 }
1570
1571 /** Free memory allocated during deserialization of a nv object.
1572 *
1573 * The nv object will not be freed (might be declared on the stack).
1574 *
1575 * @param[in] nv The nv object to be cleaned up.
1576 */
1577 void
ifapi_cleanup_ifapi_nv(IFAPI_NV * nv)1578 ifapi_cleanup_ifapi_nv(IFAPI_NV * nv) {
1579 if (nv != NULL) {
1580 SAFE_FREE(nv->serialization.buffer);
1581 SAFE_FREE(nv->appData.buffer);
1582 SAFE_FREE(nv->policyInstance);
1583 SAFE_FREE(nv->description);
1584 SAFE_FREE(nv->event_log);
1585 }
1586 }
1587
1588 /** Free memory allocated during deserialization of a duplicate object.
1589 *
1590 * The duplicate object will not be freed (might be declared on the stack).
1591 *
1592 * @param[in] duplicate The duplicate object to be cleaned up.
1593 */
1594 void
ifapi_cleanup_ifapi_duplicate(IFAPI_DUPLICATE * duplicate)1595 ifapi_cleanup_ifapi_duplicate(IFAPI_DUPLICATE * duplicate) {
1596 if (duplicate != NULL) {
1597 SAFE_FREE(duplicate->certificate);
1598 }
1599 }
1600
1601 /** Free keystore related memory allocated during FAPI initialization.
1602 *
1603 * The keystore object will not be freed (might be declared on the stack).
1604 *
1605 * @param[in] keystore The kystore object to be cleaned up.
1606 */
1607 void
ifapi_cleanup_ifapi_keystore(IFAPI_KEYSTORE * keystore)1608 ifapi_cleanup_ifapi_keystore(IFAPI_KEYSTORE * keystore) {
1609 if (keystore != NULL) {
1610 SAFE_FREE(keystore->systemdir);
1611 SAFE_FREE(keystore->userdir);
1612 SAFE_FREE(keystore->defaultprofile);
1613 }
1614 }
1615
1616 /** Create a copy of a an ifapi object storing a key.
1617 *
1618 * The key together with the policy of the key will be copied.
1619 *
1620 * @param[out] dest The caller allocated key object which will be the
1621 * destination of the copy operation.
1622 * @param[in] src The source key.
1623 *
1624 * @retval TSS2_RC_SUCCESS if the function call was a success.
1625 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if the source is not of type key.
1626 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1627 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1628 */
1629 TSS2_RC
ifapi_copy_ifapi_key_object(IFAPI_OBJECT * dest,const IFAPI_OBJECT * src)1630 ifapi_copy_ifapi_key_object(IFAPI_OBJECT * dest, const IFAPI_OBJECT * src) {
1631 TSS2_RC r = TSS2_RC_SUCCESS;
1632
1633 /* Check the parameters if they are valid */
1634 if (src == NULL || dest == NULL) {
1635 return TSS2_FAPI_RC_BAD_REFERENCE;
1636 }
1637
1638 if (src->objectType != IFAPI_KEY_OBJ) {
1639 LOG_ERROR("Bad object type");
1640 return TSS2_FAPI_RC_GENERAL_FAILURE;
1641 }
1642
1643 /* Initialize the object variables for a possible error cleanup */
1644
1645 /* Create the copy */
1646 dest->policy = ifapi_copy_policy(src->policy);
1647 strdup_check(dest->rel_path, src->rel_path, r, error_cleanup);
1648
1649 r = ifapi_copy_ifapi_key(&dest->misc.key, &src->misc.key);
1650 goto_if_error(r, "Could not copy key", error_cleanup);
1651
1652 dest->objectType = src->objectType;
1653 dest->system = src->system;
1654 dest->handle = src->handle;
1655 dest->authorization_state = src->authorization_state;
1656
1657 return r;
1658
1659 error_cleanup:
1660 ifapi_cleanup_ifapi_object(dest);
1661 return r;
1662 }
1663
1664 /** Create a copy of a an ifapi object storing a hierarchy.
1665 *
1666 * The hierarchy together with the policy of the hierarchy will be copied.
1667 *
1668 * @param[out] dest The caller allocated hierarchy object which will be the
1669 * destination of the copy operation.
1670 * @param[in] src The source hieararchy.
1671 *
1672 * @retval TSS2_RC_SUCCESS if the function call was a success.
1673 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if the source is not of type key.
1674 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
1675 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
1676 */
1677 TSS2_RC
ifapi_copy_ifapi_hierarchy_object(IFAPI_OBJECT * dest,const IFAPI_OBJECT * src)1678 ifapi_copy_ifapi_hierarchy_object(IFAPI_OBJECT * dest, const IFAPI_OBJECT * src) {
1679 TSS2_RC r = TSS2_RC_SUCCESS;
1680
1681 /* Check the parameters if they are valid */
1682 if (src == NULL || dest == NULL) {
1683 return TSS2_FAPI_RC_BAD_REFERENCE;
1684 }
1685
1686 if (src->objectType != IFAPI_HIERARCHY_OBJ) {
1687 LOG_ERROR("Bad object type");
1688 return TSS2_FAPI_RC_GENERAL_FAILURE;
1689 }
1690
1691 /* Create the copy */
1692 dest->policy = ifapi_copy_policy(src->policy);
1693 strdup_check(dest->rel_path, src->rel_path, r, error_cleanup);
1694
1695 r = ifapi_copy_ifapi_hierarchy(&dest->misc.hierarchy, &src->misc.hierarchy);
1696 goto_if_error(r, "Could not copy key", error_cleanup);
1697
1698 dest->objectType = src->objectType;
1699 dest->system = src->system;
1700 dest->handle = src->handle;
1701 dest->authorization_state = src->authorization_state;
1702
1703 return r;
1704
1705 error_cleanup:
1706 ifapi_cleanup_ifapi_object(dest);
1707 return r;
1708 }
1709
1710 /** Free memory allocated during deserialization of object.
1711 *
1712 * The object will not be freed (might be declared on the stack).
1713 *
1714 * @param[in] object The object to be cleaned up.
1715 *
1716 */
1717 void
ifapi_cleanup_ifapi_object(IFAPI_OBJECT * object)1718 ifapi_cleanup_ifapi_object(
1719 IFAPI_OBJECT * object)
1720 {
1721 if (object != NULL) {
1722 if (object->objectType != IFAPI_OBJ_NONE) {
1723 if (object->objectType == IFAPI_KEY_OBJ) {
1724 ifapi_cleanup_ifapi_key(&object->misc.key);
1725 } else if (object->objectType == IFAPI_NV_OBJ) {
1726 ifapi_cleanup_ifapi_nv(&object->misc.nv);
1727 } else if (object->objectType == IFAPI_DUPLICATE_OBJ) {
1728 ifapi_cleanup_ifapi_duplicate(&object->misc.key_tree);
1729 } else if (object->objectType == IFAPI_EXT_PUB_KEY_OBJ) {
1730 ifapi_cleanup_ifapi_ext_pub_key(&object->misc.ext_pub_key);
1731 } else if (object->objectType == IFAPI_HIERARCHY_OBJ) {
1732 ifapi_cleanup_ifapi_hierarchy(&object->misc.hierarchy);
1733 }
1734 ifapi_cleanup_policy(object->policy);
1735 SAFE_FREE(object->rel_path);
1736 SAFE_FREE(object->policy);
1737 object->objectType = IFAPI_OBJ_NONE;
1738 }
1739 }
1740 }
1741
1742 /** Check whether profile directory exists for a fapi path.
1743 *
1744 * It will be checked whether a profile directory exists for a path which starts
1745 * with a profile name after fapi pathname expansion.
1746 *
1747 * @param[in] keystore The key directories and default profile.
1748 * @param[in] rel_path The relative path to be checked.
1749 * @param[out] ok The boolean value whether the check ok.
1750 * @retval TSS2_RC_SUCCESS if the check could be made.
1751 * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to compute
1752 * the absolute paths.
1753 */
1754 TSS2_RC
ifapi_check_provisioned(IFAPI_KEYSTORE * keystore,const char * rel_path,bool * ok)1755 ifapi_check_provisioned(
1756 IFAPI_KEYSTORE *keystore,
1757 const char *rel_path,
1758 bool *ok)
1759 {
1760 TSS2_RC r = TSS2_RC_SUCCESS;
1761 char *directory = NULL;
1762 char *profile_dir = NULL;
1763 char *end_profile;
1764
1765 *ok = false;
1766
1767 /* First expand path in user directory */
1768 r = expand_path(keystore, rel_path, &directory);
1769 goto_if_error(r, "Expand path", cleanup);
1770
1771 /* Check whether the path starts with a profile. */
1772 if (directory && (strncmp(directory, "P_", 2) != 0 || strncmp(directory, "/P_", 2) != 0)) {
1773 end_profile = strchr(&directory[1], '/');
1774 if (end_profile) {
1775 end_profile[0] = '\0';
1776 }
1777 /* Compute user path of the profile. */
1778 r = ifapi_asprintf(&profile_dir, "%s/%s", keystore->userdir, directory);
1779 goto_if_error2(r, "Profile path could not be created.", cleanup);
1780
1781 if (ifapi_io_path_exists(profile_dir)) {
1782 *ok = true;
1783 goto cleanup;
1784 }
1785 /* Compute system path of the profile. */
1786 SAFE_FREE(profile_dir);
1787 r = ifapi_asprintf(&profile_dir, "%s/%s", keystore->systemdir, directory);
1788 goto_if_error2(r, "Profile path could not be created.", cleanup);
1789
1790 if (ifapi_io_path_exists(profile_dir)) {
1791 *ok = true;
1792 goto cleanup;
1793 }
1794 } else {
1795 /* No check needed because no profile found in the path. */
1796 *ok = true;
1797 }
1798 cleanup:
1799 SAFE_FREE(profile_dir);
1800 SAFE_FREE(directory);
1801 return r;
1802 }
1803