1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*******************************************************************************
3 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
4 * All rights reserved.
5 ******************************************************************************/
6
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include <errno.h>
15 #include <dirent.h>
16
17 #include "tss2_fapi.h"
18 #include "fapi_int.h"
19 #include "fapi_util.h"
20 #include "tss2_esys.h"
21 #include "ifapi_keystore.h"
22 #define LOGMODULE fapi
23 #include "util/log.h"
24 #include "util/aux_util.h"
25
26 /** One-Call function for Fapi_List
27 *
28 * Enumerates all objects in the metadatastore in a fiven path and returns them
29 * in a list of complete paths from the root with the values separated by
30 * colons.
31 *
32 * @param[in,out] context The FAPI_CONTEXT
33 * @param[in] searchPath The path that identifies the root of the search
34 * @param[out] pathList A colon-separated list of all objects in the root path
35 *
36 * @retval TSS2_RC_SUCCESS: if the function call was a success.
37 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, searchPath, pathlist is
38 * NULL.
39 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
40 * @retval TSS2_FAPI_RC_BAD_PATH: if searchPath does not map to a FAPI entity.
41 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
42 * operation already pending.
43 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
44 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
45 * internal operations or return parameters.
46 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
47 * during authorization.
48 */
49 TSS2_RC
Fapi_List(FAPI_CONTEXT * context,char const * searchPath,char ** pathList)50 Fapi_List(
51 FAPI_CONTEXT *context,
52 char const *searchPath,
53 char **pathList)
54 {
55 LOG_TRACE("called for context:%p", context);
56
57 TSS2_RC r;
58
59 /* Check for NULL parameters */
60 check_not_null(context);
61 check_not_null(searchPath);
62 check_not_null(pathList);
63
64 r = Fapi_List_Async(context, searchPath);
65 return_if_error_reset_state(r, "Entities_List");
66
67 do {
68 /* We wait for file I/O to be ready if the FAPI state automata
69 are in a file I/O state. */
70 r = ifapi_io_poll(&context->io);
71 return_if_error(r, "Something went wrong with IO polling");
72
73 /* Repeatedly call the finish function, until FAPI has transitioned
74 through all execution stages / states of this invocation. */
75 r = Fapi_List_Finish(context, pathList);
76 } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
77
78 return_if_error_reset_state(r, "Entities_List");
79
80 LOG_TRACE("finished");
81 return TSS2_RC_SUCCESS;
82 }
83
84 /** Asynchronous function for Fapi_List
85 *
86 * Enumerates all objects in the metadatastore in a fiven path and returns them
87 * in a list of complete paths from the root with the values separated by
88 * colons.
89 *
90 * Call Fapi_List_Finish to finish the execution of this command.
91 *
92 * @retval TSS2_RC_SUCCESS: if the function call was a success.
93 * @param[in,out] context The FAPI_CONTEXT
94 * @param[in] searchPath The path that identifies the root of the search
95 *
96 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or searchPath is
97 * NULL.
98 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
99 * @retval TSS2_FAPI_RC_BAD_PATH: if searchPath does not map to a FAPI entity.
100 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
101 * operation already pending.
102 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
103 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
104 * internal operations or return parameters.
105 */
106 TSS2_RC
Fapi_List_Async(FAPI_CONTEXT * context,char const * searchPath)107 Fapi_List_Async(
108 FAPI_CONTEXT *context,
109 char const *searchPath)
110 {
111 LOG_TRACE("called for context:%p", context);
112 LOG_TRACE("searchPath: %s", searchPath);
113
114 TSS2_RC r;
115
116 /* Check for NULL parameters */
117 check_not_null(context);
118 check_not_null(searchPath);
119
120 /* Helpful alias pointers */
121 IFAPI_Entities_List * command = &context->cmd.Entities_List;
122
123 r = ifapi_non_tpm_mode_init(context);
124 return_if_error(r, "Initialize List");
125
126 /* Copy parameters to context for use during _Finish. */
127 strdup_check(command->searchPath, searchPath, r, error_cleanup);
128
129 LOG_TRACE("finished");
130 return TSS2_RC_SUCCESS;
131
132 error_cleanup:
133 /* Cleanup duplicated input parameters that were copied before. */
134 SAFE_FREE(command->searchPath);
135 return r;
136 }
137
138 /** Asynchronous finish function for Fapi_List
139 *
140 * This function should be called after a previous Fapi_List_Async.
141 *
142 * @param[in,out] context The FAPI_CONTEXT
143 * @param[out] pathList A colon-separated list of all objects in the root path
144 *
145 * @retval TSS2_RC_SUCCESS: if the function call was a success.
146 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or pathList is NULL.
147 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
148 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
149 * operation already pending.
150 * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
151 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
152 * internal operations or return parameters.
153 * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
154 * complete. Call this function again later.
155 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
156 * during authorization.
157 */
158 TSS2_RC
Fapi_List_Finish(FAPI_CONTEXT * context,char ** pathList)159 Fapi_List_Finish(
160 FAPI_CONTEXT *context,
161 char **pathList)
162 {
163 LOG_TRACE("called for context:%p", context);
164
165 TSS2_RC r = TSS2_RC_SUCCESS;
166 size_t sizePathList = 0;
167 size_t numPaths = 0;
168 char **pathArray = NULL;
169
170 /* Check for NULL parameters */
171 check_not_null(context);
172 check_not_null(pathList);
173
174 /* Helpful alias pointers */
175 IFAPI_Entities_List * command = &context->cmd.Entities_List;
176
177 /* Retrieve the objects along the search path. */
178 r = ifapi_keystore_list_all(&context->keystore, command->searchPath,
179 &pathArray, &numPaths);
180 goto_if_error(r, "get entities.", cleanup);
181
182 if (numPaths == 0)
183 goto cleanup;
184
185 /* Determine size of char string to be returnded */
186 for (size_t i = 0; i < numPaths; i++)
187 sizePathList += strlen(pathArray[i]);
188
189 /* Allocate path list plus colon separators plus \0-terminator */
190 *pathList = malloc(sizePathList + (numPaths - 1) + 1);
191 goto_if_null2(*pathList, "Out of memory", r, TSS2_FAPI_RC_MEMORY, cleanup);
192
193 (*pathList)[0] = '\0';
194 (*pathList)[sizePathList + numPaths - 1] = '\0';
195
196 /* Concatenate the path entries to the output string. */
197 for (size_t i = 0; i < numPaths; i++) {
198 strcat(*pathList, pathArray[i]);
199 if (i < numPaths - 1)
200 strcat(*pathList, IFAPI_LIST_DELIM);
201 }
202
203 LOG_TRACE("finished");
204
205 cleanup:
206 /* Cleanup any intermediate results and state stored in the context. */
207 SAFE_FREE(command->searchPath);
208 if (numPaths == 0 && (r == TSS2_RC_SUCCESS)) {
209 LOG_ERROR("Path not found: %s", command->searchPath);
210 r = TSS2_FAPI_RC_PATH_NOT_FOUND;
211 }
212 if (numPaths > 0) {
213 for (size_t i = 0; i < numPaths; i++){
214 SAFE_FREE(pathArray[i]);
215 }
216 }
217 SAFE_FREE(pathArray);
218 return r;
219 }
220