xref: /aosp_15_r20/external/tpm2-tss/src/tss2-fapi/api/Fapi_ExportPolicy.c (revision 758e9fba6fc9adbf15340f70c73baee7b168b1c9)
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 "tss2_fapi.h"
12 #include "fapi_int.h"
13 #include "fapi_util.h"
14 #include "tss2_esys.h"
15 #include "fapi_policy.h"
16 #define LOGMODULE fapi
17 #include "util/log.h"
18 #include "util/aux_util.h"
19 
20 /** One-Call function for Fapi_ExportPolicy
21  *
22  * Exports a policy to a JSON encoded byte buffer.
23  *
24  * @param[in,out] context The FAPI_CONTEXT
25  * @param[in] path The path to the policy that is to be exported
26  * @param[out] jsonPolicy The JSON-encoded policy. jsonPolicy MUST NOT be NULL.
27  *
28  * @retval TSS2_RC_SUCCESS: if the function call was a success.
29  * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context, path or jsonPolicy is NULL.
30  * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
31  * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI policy.
32  * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
33  *         operation already pending.
34  * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
35  * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
36  *         internal operations or return parameters.
37  * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
38  *         config file.
39  * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
40  *         this function needs to be called again.
41  * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
42  * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
43  *         the function.
44  * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
45  *         during authorization.
46  * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
47  * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
48  */
49 TSS2_RC
Fapi_ExportPolicy(FAPI_CONTEXT * context,char const * path,char ** jsonPolicy)50 Fapi_ExportPolicy(
51     FAPI_CONTEXT *context,
52     char   const *path,
53     char        **jsonPolicy)
54 {
55     LOG_TRACE("called for context:%p", context);
56 
57     TSS2_RC r, r2;
58 
59     /* Check for NULL parameters */
60     check_not_null(context);
61     check_not_null(path);
62     check_not_null(jsonPolicy);
63 
64     /* Check whether TCTI and ESYS are initialized */
65     return_if_null(context->esys, "Command can't be executed in none TPM mode.",
66                    TSS2_FAPI_RC_NO_TPM);
67 
68     /* If the async state automata of FAPI shall be tested, then we must not set
69        the timeouts of ESYS to blocking mode.
70        During testing, the mssim tcti will ensure multiple re-invocations.
71        Usually however the synchronous invocations of FAPI shall instruct ESYS
72        to block until a result is available. */
73 #ifndef TEST_FAPI_ASYNC
74     r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK);
75     return_if_error_reset_state(r, "Set Timeout to blocking");
76 #endif /* TEST_FAPI_ASYNC */
77 
78     r = Fapi_ExportPolicy_Async(context, path);
79     return_if_error_reset_state(r, "PolicyExport");
80 
81     do {
82         /* We wait for file I/O to be ready if the FAPI state automata
83            are in a file I/O state. */
84         r = ifapi_io_poll(&context->io);
85         return_if_error(r, "Something went wrong with IO polling");
86 
87         /* Repeatedly call the finish function, until FAPI has transitioned
88            through all execution stages / states of this invocation. */
89         r = Fapi_ExportPolicy_Finish(context, jsonPolicy);
90     } while ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN);
91 
92     /* Reset the ESYS timeout to non-blocking, immediate response. */
93     r2 = Esys_SetTimeout(context->esys, 0);
94     return_if_error(r2, "Set Timeout to non-blocking");
95 
96     return_if_error_reset_state(r, "PolicyExport");
97 
98     return TSS2_RC_SUCCESS;
99 
100 }
101 
102 /** Asynchronous function for Fapi_ExportPolicy
103  *
104  * Exports a policy to a JSON encoded byte buffer.
105  *
106  * Call Fapi_ExportPolicy_Finish to finish the execution of this command.
107  *
108  * @param[in,out] context The FAPI_CONTEXT
109  * @param[in] path The path to the policy that is to be exported
110  *
111  * @retval TSS2_RC_SUCCESS: if the function call was a success.
112  * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or path is NULL.
113  * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
114  * @retval TSS2_FAPI_RC_BAD_PATH: if path does not map to a FAPI policy.
115  * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
116  *         operation already pending.
117  * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
118  * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
119  *         internal operations or return parameters.
120  * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
121  *         config file.
122  */
123 TSS2_RC
Fapi_ExportPolicy_Async(FAPI_CONTEXT * context,char const * path)124 Fapi_ExportPolicy_Async(
125     FAPI_CONTEXT *context,
126     char   const *path)
127 {
128     LOG_TRACE("called for context:%p", context);
129     LOG_TRACE("path: %s", path);
130 
131     TSS2_RC r;
132 
133     /* Check for NULL parameters */
134     check_not_null(context);
135     check_not_null(path);
136 
137     /* Helpful alias pointers */
138     IFAPI_ExportPolicy * command = &context->cmd.ExportPolicy;
139 
140     /* Reset all context-internal session state information. */
141     r = ifapi_session_init(context);
142     return_if_error(r, "Initialize PolicyExport");
143 
144     /* Initialize the context state for this operation. */
145     if (ifapi_path_type_p(path, IFAPI_POLICY_PATH)) {
146         context->state = POLICY_EXPORT_READ_POLICY;
147     } else {
148         context->state = POLICY_EXPORT_READ_OBJECT;
149     }
150 
151     /* Copy parameters to context for use during _Finish. */
152     strdup_check(command->path, path, r ,error_cleanup);
153     memset(&command->object, 0, sizeof(IFAPI_OBJECT));
154 
155     LOG_TRACE("finished");
156     return TSS2_RC_SUCCESS;
157 
158 error_cleanup:
159     /* Cleanup duplicated input parameters that were copied before. */
160     SAFE_FREE(command->path);
161     return r;
162 }
163 
164 /** Asynchronous finish function for Fapi_ExportPolicy
165  *
166  * This function should be called after a previous Fapi_ExportPolicy_Async.
167  *
168  * @param[in,out] context The FAPI_CONTEXT
169  * @param[out] jsonPolicy The JSON-encoded policy. jsonPolicy MUST NOT be NULL.
170  *
171  * @retval TSS2_RC_SUCCESS: if the function call was a success.
172  * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or jsonPolicy is NULL.
173  * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
174  * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has an asynchronous
175  *         operation already pending.
176  * @retval TSS2_FAPI_RC_IO_ERROR: if the data cannot be saved.
177  * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
178  *         internal operations or return parameters.
179  * @retval TSS2_FAPI_RC_TRY_AGAIN: if the asynchronous operation is not yet
180  *         complete. Call this function again later.
181  * @retval TSS2_FAPI_RC_BAD_PATH if the used path in inappropriate-
182  * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
183  * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
184  *         the function.
185  * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
186  *         during authorization.
187  * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
188  */
189 TSS2_RC
Fapi_ExportPolicy_Finish(FAPI_CONTEXT * context,char ** jsonPolicy)190 Fapi_ExportPolicy_Finish(
191     FAPI_CONTEXT *context,
192     char        **jsonPolicy)
193 {
194     LOG_TRACE("called for context:%p", context);
195 
196     TPMS_POLICY policy = {0};
197     json_object *jso = NULL;
198     TSS2_RC r;
199 
200     /* Check for NULL parameters */
201     check_not_null(context);
202     check_not_null(jsonPolicy);
203 
204     /* Helpful alias pointers */
205     IFAPI_ExportPolicy * command = &context->cmd.ExportPolicy;
206 
207     switch (context->state) {
208         statecase(context->state, POLICY_EXPORT_READ_POLICY);
209             /* This is the entry point if a policy from the policy store shall
210                be exported. */
211             /* Load the policy to be exported from the policy store. */
212             r = ifapi_policy_store_load_async(&context->pstore, &context->io,
213                                               command->path);
214             goto_if_error2(r, "Can't open: %s", error_cleanup,
215                     command->path);
216             fallthrough;
217 
218         statecase(context->state, POLICY_EXPORT_READ_POLICY_FINISH);
219             r = ifapi_policy_store_load_finish(&context->pstore, &context->io, &policy);
220             return_try_again(r);
221             return_if_error_reset_state(r, "read_finish failed");
222 
223             /* Serialize the policy to JSON. */
224             r = ifapi_json_TPMS_POLICY_serialize(&policy, &jso);
225             goto_if_error(r, "Serialize policy", error_cleanup);
226 
227             /* Duplicate the JSON string to be returned to the caller. */
228             strdup_check(*jsonPolicy,
229                     json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY),
230                     r, error_cleanup);
231 
232             break;
233         statecase(context->state, POLICY_EXPORT_READ_OBJECT);
234             /* This is the entry point if a policy for a key from the key store
235                shall be exported. */
236             memset(&command->object, 0, sizeof(IFAPI_OBJECT));
237             /* Load the key meta data from the keystore. */
238             r = ifapi_keystore_load_async(&context->keystore, &context->io,
239                                           command->path);
240             return_if_error2(r, "Could not open: %s", command->path);
241             fallthrough;
242 
243         statecase(context->state, POLICY_EXPORT_READ_OBJECT_FINISH);
244             r = ifapi_keystore_load_finish(&context->keystore, &context->io,
245                                            &command->object);
246             return_try_again(r);
247             return_if_error_reset_state(r, "read_finish failed");
248 
249             goto_if_null2(command->object.policy,
250                           "Object has no policy",
251                           r, TSS2_FAPI_RC_BAD_PATH, error_cleanup);
252 
253             /* Serialize the policy to JSON. */
254             r = ifapi_json_TPMS_POLICY_serialize(context->
255                 cmd.ExportPolicy.object.policy, &jso);
256             goto_if_error(r, "Serialize policy", error_cleanup);
257 
258             /* Duplicate the JSON string to be returned to the caller. */
259             strdup_check(*jsonPolicy,
260                     json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY),
261                     r, error_cleanup);
262             break;
263 
264         statecasedefault(context->state);
265     }
266 
267     /* Cleanup any intermediate results and state stored in the context. */
268     context->state = _FAPI_STATE_INIT;
269     if (jso)
270         json_object_put(jso);
271     ifapi_cleanup_ifapi_object(&command->object);
272     ifapi_cleanup_policy(&policy);
273     ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
274     ifapi_cleanup_ifapi_object(context->loadKey.key_object);
275     ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
276     SAFE_FREE(command->path);
277     LOG_TRACE("finished");
278     return TSS2_RC_SUCCESS;
279 
280 error_cleanup:
281     /* Cleanup any intermediate results and state stored in the context. */
282     if (command->object.objectType)
283         ifapi_cleanup_ifapi_object(&command->object);
284     if (jso)
285         json_object_put(jso);
286     ifapi_cleanup_policy(&policy);
287     ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
288     ifapi_cleanup_ifapi_object(context->loadKey.key_object);
289     ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
290     SAFE_FREE(command->path);
291     context->state = _FAPI_STATE_INIT;
292     return r;
293 }
294