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