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