• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*******************************************************************************
3  * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
4  * All rights reserved.
5  *******************************************************************************/
6 
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #include <dirent.h>
10 #endif
11 
12 #include "ifapi_io.h"
13 #include "ifapi_helpers.h"
14 #include "ifapi_policy_types.h"
15 #include "ifapi_policy_store.h"
16 #include "ifapi_macros.h"
17 #define LOGMODULE fapi
18 #include "util/log.h"
19 #include "util/aux_util.h"
20 #include "ifapi_policy_json_deserialize.h"
21 #include "ifapi_policy_json_serialize.h"
22 
23 /** Compute absolute path of policy for IO.
24  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
25  */
26 static TSS2_RC
policy_rel_path_to_abs_path(IFAPI_POLICY_STORE * pstore,const char * rel_path,char ** abs_path)27 policy_rel_path_to_abs_path(
28     IFAPI_POLICY_STORE *pstore,
29     const char *rel_path,
30     char **abs_path)
31 {
32     TSS2_RC r;
33 
34     if (ifapi_path_type_p(rel_path, IFAPI_POLICY_PATH)) {
35         r = ifapi_asprintf(abs_path, "%s%s%s.json", pstore->policydir,
36                            IFAPI_FILE_DELIM, rel_path);
37     } else {
38         r = ifapi_asprintf(abs_path, "%s%s%s%s%s.json", pstore->policydir,
39                            IFAPI_FILE_DELIM, IFAPI_POLICY_PATH, IFAPI_FILE_DELIM, rel_path);
40 
41     }
42     return_if_error(r, "Create policy file name.");
43     return r;
44 }
45 /** Remove file storing a policy object.
46  *
47  * @param[in] pstore The policy directory.
48  * @param[in] path The relative name of the object be removed.
49  * @retval TSS2_RC_SUCCESS On success.
50  * @retval TSS2_FAPI_RC_MEMORY: If memory could not be allocated.
51  * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If no file is found in policy store.
52  * @retval TSS2_FAPI_RC_IO_ERROR If the file can't be removed.
53  */
54 TSS2_RC
ifapi_policy_delete(IFAPI_POLICY_STORE * pstore,char * path)55 ifapi_policy_delete(
56     IFAPI_POLICY_STORE * pstore,
57     char *path)
58 {
59     TSS2_RC r;
60     char *abs_path = NULL;
61 
62     /* Convert relative path to absolute path in policy store */
63     r = policy_rel_path_to_abs_path(pstore, path, &abs_path);
64     goto_if_error2(r, "Path %s could not be created.", cleanup, path);
65 
66     if (!ifapi_io_path_exists(abs_path)) {
67         goto_error(r, TSS2_FAPI_RC_PATH_NOT_FOUND,
68                    "Policy %s not found.", cleanup, path);
69     }
70 
71     if (remove(abs_path) != 0) {
72         LOG_WARNING("File: %s can't be deleted.", abs_path);
73     }
74 
75 cleanup:
76     SAFE_FREE(abs_path);
77     return r;
78 }
79 
80 /** Store policy store parameters in the policy store context.
81  *
82  * Also the user directory will be created if it does not exist.
83  *
84  * @param[out] pstore The keystore to be initialized.
85  * @param[in] config_policydir The configured policy directory.
86  * @retval TSS2_RC_SUCCESS If the keystore can be initialized.
87  * @retval TSS2_FAPI_RC_IO_ERROR If the policy store can't be
88  *         initialized.
89  * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated.
90  * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
91  *         the function.
92  */
93 TSS2_RC
ifapi_policy_store_initialize(IFAPI_POLICY_STORE * pstore,const char * config_policydir)94 ifapi_policy_store_initialize(
95     IFAPI_POLICY_STORE *pstore,
96     const char *config_policydir)
97 {
98     TSS2_RC r;
99     char *policy_dir = NULL;
100 
101     memset(pstore, 0, sizeof(IFAPI_POLICY_STORE));
102     strdup_check(pstore->policydir, config_policydir, r, error);
103 
104     r = ifapi_asprintf(&policy_dir, "%s%s%s", config_policydir, IFAPI_FILE_DELIM,
105                        IFAPI_POLICY_PATH);
106     goto_if_error(r, "Out of memory.", error);
107 
108     r = ifapi_io_check_create_dir(policy_dir);
109     goto_if_error2(r, "Policy directory %s can't be created.", error, policy_dir);
110 
111     SAFE_FREE(policy_dir);
112     return TSS2_RC_SUCCESS;
113 
114 error:
115     SAFE_FREE(policy_dir);
116     return r;
117 }
118 
119 /** Start loading FAPI policy from policy store.
120  *
121  * Keys objects, NV objects, and hierarchies can be loaded.
122  *
123  * @param[in] pstore The policy directory.
124  * @param[in] io  The input/output context being used for file I/O.
125  * @param[in] path The relative path of the object. For keys the path will
126  *           expanded if possible.
127  * @retval TSS2_RC_SUCCESS If the object can be read.
128  * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered.
129  * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if the file does not exist.
130  * @retval TSS2_FAPI_RC_MEMORY: if memory could not be allocated to hold the read data.
131  */
132 TSS2_RC
ifapi_policy_store_load_async(IFAPI_POLICY_STORE * pstore,IFAPI_IO * io,const char * path)133 ifapi_policy_store_load_async(
134     IFAPI_POLICY_STORE *pstore,
135     IFAPI_IO *io,
136     const char *path)
137 {
138     TSS2_RC r;
139     char *abs_path = NULL;
140 
141     LOG_TRACE("Load policy: %s", path);
142 
143     /* Free old input buffer if buffer exists */
144     SAFE_FREE(io->char_rbuffer);
145 
146     /* Convert relative path to absolute path in keystore */
147     r = policy_rel_path_to_abs_path(pstore, path, &abs_path);
148     goto_if_error2(r, "Object %s not found.", cleanup, path);
149 
150     /* Prepare read operation */
151     r = ifapi_io_read_async(io, abs_path);
152 
153 cleanup:
154     SAFE_FREE(abs_path);
155     return r;
156 }
157 
158 /** Finish loading FAPI policy from policy store.
159  *
160  *
161  * This function needs to be called repeatedly until it does not return TSS2_FAPI_RC_TRY_AGAIN.
162  *
163  * @param[in] pstore The policy context with the policy directory.
164  * @param[in,out] io The input/output context being used for file I/O.
165  * @param[in] policy The caller allocated policy which will loaded from policy store.
166  * @retval TSS2_RC_SUCCESS After successfully loading the object.
167  * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered; such as the file was not found.
168  * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet complete.
169  * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
170  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
171  * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
172  *         the function.
173  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
174  */
175 TSS2_RC
ifapi_policy_store_load_finish(IFAPI_POLICY_STORE * pstore,IFAPI_IO * io,TPMS_POLICY * policy)176 ifapi_policy_store_load_finish(
177     IFAPI_POLICY_STORE *pstore,
178     IFAPI_IO *io,
179     TPMS_POLICY *policy)
180 {
181     TSS2_RC r;
182     json_object *jso = NULL;
183     uint8_t *buffer = NULL;
184     /* ptore parameter is used to be prepared if transmission of state information
185        between async and finish will be necessary in future extensions. */
186     (void)pstore;
187 
188     r = ifapi_io_read_finish(io, &buffer, NULL);
189     return_try_again(r);
190     return_if_error(r, "keystore read_finish failed");
191 
192     /* If json objects can't be parse the object store is corrupted */
193     jso = json_tokener_parse((char *)buffer);
194     SAFE_FREE(buffer);
195     return_if_null(jso, "Policy store is corrupted (Json error).", TSS2_FAPI_RC_GENERAL_FAILURE);
196 
197     r = ifapi_json_TPMS_POLICY_deserialize(jso, policy);
198     goto_if_error(r, "Deserialize policy", cleanup);
199 
200 cleanup:
201     SAFE_FREE(buffer);
202     if (jso)
203         json_object_put(jso);
204     LOG_TRACE("Return %x", r);
205     return r;
206 
207 }
208 
209 /**  Start writing FAPI object to the key store.
210  *
211  * The relative path will be expanded, if the default policy directory (/policy)
212  * is not part of the path.
213  *
214  * @param[in] pstore The policy context with the policy directory.
215  * @param[in] io  The input/output context being used for file I/O.
216  * @param[in] path The relative path of the policy.
217  * @param[in] policy The policy to be written to the policy store.
218  * @retval TSS2_RC_SUCCESS If the policy is written successfully.
219  * @retval TSS2_FAPI_RC_IO_ERROR: If an I/O error was encountered;
220  * @retval TSS2_FAPI_RC_MEMORY: If memory could not be allocated to hold the output data.
221  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
222  * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
223  *         the function.
224  */
225 TSS2_RC
ifapi_policy_store_store_async(IFAPI_POLICY_STORE * pstore,IFAPI_IO * io,const char * path,const TPMS_POLICY * policy)226 ifapi_policy_store_store_async(
227     IFAPI_POLICY_STORE *pstore,
228     IFAPI_IO *io,
229     const char *path,
230     const TPMS_POLICY *policy)
231 {
232     TSS2_RC r;
233     char *jso_string = NULL;
234     json_object *jso = NULL;
235     char *abs_path = NULL;
236 
237     LOG_TRACE("Store policy: %s", path);
238 
239     /* Convert relative path to absolute path in the policy store */
240     r = policy_rel_path_to_abs_path(pstore, path, &abs_path);
241     goto_if_error2(r, "Path %s could not be created.", cleanup, path);
242 
243     /* Generate JSON string to be written to store */
244     r = ifapi_json_TPMS_POLICY_serialize(policy, &jso);
245     goto_if_error2(r, "Policy %s could not be serialized.", cleanup, path);
246 
247     jso_string = strdup(json_object_to_json_string_ext(jso,
248                                                        JSON_C_TO_STRING_PRETTY));
249     goto_if_null2(jso_string, "Converting json to string", r, TSS2_FAPI_RC_MEMORY,
250                   cleanup);
251 
252     /* Start writing the json string to disk */
253     r = ifapi_io_write_async(io, abs_path, (uint8_t *) jso_string, strlen(jso_string));
254     free(jso_string);
255     goto_if_error(r, "write_async failed", cleanup);
256 
257 cleanup:
258     if (jso)
259         json_object_put(jso);
260     SAFE_FREE(abs_path);
261     return r;
262 }
263 
264 /** Finish writing a FAPI policy object to the policy store.
265  *
266  * This function needs to be called repeatedly until it does not return TSS2_FAPI_RC_TRY_AGAIN.
267  *
268  * @param[in] pstore The policy context with the policy directory.
269  * @param[in,out] io The input/output context being used for file I/O.
270  * @retval TSS2_RC_SUCCESS: if the function call was a success.
271  * @retval TSS2_FAPI_RC_IO_ERROR: if an I/O error was encountered; such as the file was not found.
272  * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet complete.
273            Call this function again later.
274  */
275 TSS2_RC
ifapi_policy_store_store_finish(IFAPI_POLICY_STORE * pstore,IFAPI_IO * io)276 ifapi_policy_store_store_finish(
277     IFAPI_POLICY_STORE *pstore,
278     IFAPI_IO *io)
279 {
280     TSS2_RC r;
281 
282     /* Pstore parameter is used to be prepared if transmission of state information
283        between async and finish will be necessary in future extensions. */
284     (void)pstore;
285     /* Finish writing the policy */
286     r = ifapi_io_write_finish(io);
287     return_try_again(r);
288 
289     LOG_TRACE("Return %x", r);
290     return_if_error(r, "read_finish failed");
291 
292     return TSS2_RC_SUCCESS;
293 }
294