xref: /aosp_15_r20/external/tpm2-tss/src/tss2-fapi/ifapi_policy_instantiate.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 #endif
10*758e9fbaSOystein Eftevaag 
11*758e9fbaSOystein Eftevaag #include <string.h>
12*758e9fbaSOystein Eftevaag #include <stdlib.h>
13*758e9fbaSOystein Eftevaag 
14*758e9fbaSOystein Eftevaag #include "tss2_mu.h"
15*758e9fbaSOystein Eftevaag #include "fapi_util.h"
16*758e9fbaSOystein Eftevaag #include "fapi_crypto.h"
17*758e9fbaSOystein Eftevaag //#include "fapi_policy.h"
18*758e9fbaSOystein Eftevaag #include "ifapi_helpers.h"
19*758e9fbaSOystein Eftevaag #include "ifapi_policy_instantiate.h"
20*758e9fbaSOystein Eftevaag #include "ifapi_json_deserialize.h"
21*758e9fbaSOystein Eftevaag #include "tpm_json_deserialize.h"
22*758e9fbaSOystein Eftevaag #define LOGMODULE fapi
23*758e9fbaSOystein Eftevaag #include "util/log.h"
24*758e9fbaSOystein Eftevaag #include "util/aux_util.h"
25*758e9fbaSOystein Eftevaag 
26*758e9fbaSOystein Eftevaag static TSS2_RC
27*758e9fbaSOystein Eftevaag get_policy_elements(TPML_POLICYELEMENTS *policy, NODE_OBJECT_T **policy_element_list);
28*758e9fbaSOystein Eftevaag 
29*758e9fbaSOystein Eftevaag /** Compute linked list with a list of policy elements which could be instantiated.
30*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
31*758e9fbaSOystein Eftevaag  */
32*758e9fbaSOystein Eftevaag static TSS2_RC
get_policy_elements(TPML_POLICYELEMENTS * policy,NODE_OBJECT_T ** policy_element_list)33*758e9fbaSOystein Eftevaag get_policy_elements(TPML_POLICYELEMENTS *policy, NODE_OBJECT_T **policy_element_list)
34*758e9fbaSOystein Eftevaag {
35*758e9fbaSOystein Eftevaag     TSS2_RC r = TSS2_RC_SUCCESS;
36*758e9fbaSOystein Eftevaag     size_t i, j;
37*758e9fbaSOystein Eftevaag 
38*758e9fbaSOystein Eftevaag     for (i = 0; i < policy->count; i++) {
39*758e9fbaSOystein Eftevaag         if (policy->elements[i].type == POLICYOR) {
40*758e9fbaSOystein Eftevaag             /* Policy with sub policies */
41*758e9fbaSOystein Eftevaag             TPML_POLICYBRANCHES *branches = policy->elements[i].element.PolicyOr.branches;
42*758e9fbaSOystein Eftevaag             for (j = 0; j < branches->count; j++) {
43*758e9fbaSOystein Eftevaag                 r = get_policy_elements(branches->authorizations[j].policy,
44*758e9fbaSOystein Eftevaag                                         policy_element_list);
45*758e9fbaSOystein Eftevaag                 goto_if_error(r, "Get policy elements.", error_cleanup);
46*758e9fbaSOystein Eftevaag             }
47*758e9fbaSOystein Eftevaag         } else {
48*758e9fbaSOystein Eftevaag             r = push_object_to_list(&policy->elements[i], policy_element_list);
49*758e9fbaSOystein Eftevaag             goto_if_error(r, "Get policy elements.", error_cleanup);
50*758e9fbaSOystein Eftevaag         }
51*758e9fbaSOystein Eftevaag     }
52*758e9fbaSOystein Eftevaag     return r;
53*758e9fbaSOystein Eftevaag 
54*758e9fbaSOystein Eftevaag error_cleanup:
55*758e9fbaSOystein Eftevaag     ifapi_free_node_list(*policy_element_list);
56*758e9fbaSOystein Eftevaag     return r;
57*758e9fbaSOystein Eftevaag }
58*758e9fbaSOystein Eftevaag 
59*758e9fbaSOystein Eftevaag /** Prepare instantiation a policy template.
60*758e9fbaSOystein Eftevaag  *
61*758e9fbaSOystein Eftevaag  * Parts of policies which are referenced by object paths will be replaced with
62*758e9fbaSOystein Eftevaag  * the appropriate values of the referenced objects.
63*758e9fbaSOystein Eftevaag  *
64*758e9fbaSOystein Eftevaag  * @param[in] context The context storing information for re-entry after try again.
65*758e9fbaSOystein Eftevaag  * @param[in] policy The policy to be instantiated.
66*758e9fbaSOystein Eftevaag  * @param[in] callbacks The needed callback functions with the corresponding user data
67*758e9fbaSOystein Eftevaag  *           which will be passed to the callback.
68*758e9fbaSOystein Eftevaag  * @retval TSS2_RC_SUCCESS on success.
69*758e9fbaSOystein Eftevaag  * @retval FAPI error codes on failure
70*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
71*758e9fbaSOystein Eftevaag  */
72*758e9fbaSOystein Eftevaag TSS2_RC
ifapi_policyeval_instantiate_async(IFAPI_POLICY_EVAL_INST_CTX * context,TPMS_POLICY * policy,ifapi_policyeval_INST_CB * callbacks)73*758e9fbaSOystein Eftevaag ifapi_policyeval_instantiate_async(
74*758e9fbaSOystein Eftevaag     IFAPI_POLICY_EVAL_INST_CTX *context, /* For re-entry after try_again for offsets and such */
75*758e9fbaSOystein Eftevaag     TPMS_POLICY *policy, /* in */
76*758e9fbaSOystein Eftevaag     ifapi_policyeval_INST_CB *callbacks)
77*758e9fbaSOystein Eftevaag {
78*758e9fbaSOystein Eftevaag     TSS2_RC r;
79*758e9fbaSOystein Eftevaag 
80*758e9fbaSOystein Eftevaag     /* Store callbacks and their parameters in context */
81*758e9fbaSOystein Eftevaag     context->callbacks = *callbacks;
82*758e9fbaSOystein Eftevaag 
83*758e9fbaSOystein Eftevaag     /* Compute list of all policy elements which have to be instantiated */
84*758e9fbaSOystein Eftevaag     if (context->policy_elements) {
85*758e9fbaSOystein Eftevaag         ifapi_free_object_list(context->policy_elements);
86*758e9fbaSOystein Eftevaag         context->policy_elements = NULL;
87*758e9fbaSOystein Eftevaag     }
88*758e9fbaSOystein Eftevaag     r = get_policy_elements(policy->policy, &context->policy_elements);
89*758e9fbaSOystein Eftevaag     return r;
90*758e9fbaSOystein Eftevaag }
91*758e9fbaSOystein Eftevaag 
92*758e9fbaSOystein Eftevaag /** Compute name and public information format a PEM key.
93*758e9fbaSOystein Eftevaag  *
94*758e9fbaSOystein Eftevaag  * @param[in]  keyPEM The key in PEM format.
95*758e9fbaSOystein Eftevaag  * @param[out] keyPublic The public information of the PEM key.
96*758e9fbaSOystein Eftevaag  * @param[out] name the name computed from the public information.
97*758e9fbaSOystein Eftevaag  * @param[in]  hash_alg The name alg of the key has to passed.
98*758e9fbaSOystein Eftevaag  * @retval TSS2_RC_SUCCESS on success.
99*758e9fbaSOystein Eftevaag  */
100*758e9fbaSOystein Eftevaag static TSS2_RC
set_pem_key_param(const char * keyPEM,TPMT_PUBLIC * keyPublic,TPM2B_NAME * name,TPMI_ALG_HASH hash_alg)101*758e9fbaSOystein Eftevaag set_pem_key_param(
102*758e9fbaSOystein Eftevaag     const char *keyPEM,
103*758e9fbaSOystein Eftevaag     TPMT_PUBLIC *keyPublic,
104*758e9fbaSOystein Eftevaag     TPM2B_NAME *name,
105*758e9fbaSOystein Eftevaag     TPMI_ALG_HASH hash_alg)
106*758e9fbaSOystein Eftevaag {
107*758e9fbaSOystein Eftevaag     TSS2_RC r;
108*758e9fbaSOystein Eftevaag     TPM2B_PUBLIC public;
109*758e9fbaSOystein Eftevaag 
110*758e9fbaSOystein Eftevaag     if (!keyPEM || strlen(keyPEM) == 0) {
111*758e9fbaSOystein Eftevaag         /* No PEM key used. Parameters are already set in policy. */
112*758e9fbaSOystein Eftevaag         return TSS2_RC_SUCCESS;
113*758e9fbaSOystein Eftevaag     }
114*758e9fbaSOystein Eftevaag 
115*758e9fbaSOystein Eftevaag     /* Use PEM key to compute public information and name */
116*758e9fbaSOystein Eftevaag     name->size = 0;
117*758e9fbaSOystein Eftevaag 
118*758e9fbaSOystein Eftevaag     TPM2_ALG_ID rsaOrEcc = ifapi_get_signature_algorithm_from_pem(keyPEM);
119*758e9fbaSOystein Eftevaag     r = ifapi_initialize_sign_public(rsaOrEcc, &public);
120*758e9fbaSOystein Eftevaag     return_if_error(r, "Could not initialize public info of key");
121*758e9fbaSOystein Eftevaag 
122*758e9fbaSOystein Eftevaag     r = ifapi_get_tpm2b_public_from_pem(keyPEM, &public);
123*758e9fbaSOystein Eftevaag     return_if_error(r, "Invalid PEM key.");
124*758e9fbaSOystein Eftevaag 
125*758e9fbaSOystein Eftevaag     *keyPublic = public.publicArea;
126*758e9fbaSOystein Eftevaag     keyPublic->nameAlg = hash_alg;
127*758e9fbaSOystein Eftevaag     r = ifapi_get_name(&public.publicArea, name);
128*758e9fbaSOystein Eftevaag     return_if_error(r, "Compute key name.");
129*758e9fbaSOystein Eftevaag 
130*758e9fbaSOystein Eftevaag     return TSS2_RC_SUCCESS;
131*758e9fbaSOystein Eftevaag }
132*758e9fbaSOystein Eftevaag 
133*758e9fbaSOystein Eftevaag #define CHECK_TEMPLATE_PATH(path, template) \
134*758e9fbaSOystein Eftevaag      if (!path) { \
135*758e9fbaSOystein Eftevaag          return_error2(TSS2_FAPI_RC_BAD_TEMPLATE, "No path for policy %s", template); \
136*758e9fbaSOystein Eftevaag      }
137*758e9fbaSOystein Eftevaag 
138*758e9fbaSOystein Eftevaag /** Finalize  instantiation a policy template.
139*758e9fbaSOystein Eftevaag  *
140*758e9fbaSOystein Eftevaag  * All needed asyncroous callbacks will be executed for all policy elements offset
141*758e9fbaSOystein Eftevaag  * The policy.
142*758e9fbaSOystein Eftevaag  *
143*758e9fbaSOystein Eftevaag  * @param[in] context The context storing information for re-entry after try again.
144*758e9fbaSOystein Eftevaag  * @retval TSS2_RC_SUCCESS on success.
145*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_TEMPLATE If the templayte is not complete for instantiation.
146*758e9fbaSOystein Eftevaag  * @retval FAPI error codes on failure
147*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
148*758e9fbaSOystein Eftevaag  *         this function needs to be called again.
149*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
150*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
151*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
152*758e9fbaSOystein Eftevaag  *         the function.
153*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
154*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
155*758e9fbaSOystein Eftevaag  *         operation already pending.
156*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
157*758e9fbaSOystein Eftevaag  *         during authorization.
158*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
159*758e9fbaSOystein Eftevaag  * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
160*758e9fbaSOystein Eftevaag  *         object store.
161*758e9fbaSOystein Eftevaag  * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
162*758e9fbaSOystein Eftevaag  */
163*758e9fbaSOystein Eftevaag TSS2_RC
ifapi_policyeval_instantiate_finish(IFAPI_POLICY_EVAL_INST_CTX * context)164*758e9fbaSOystein Eftevaag ifapi_policyeval_instantiate_finish(
165*758e9fbaSOystein Eftevaag     IFAPI_POLICY_EVAL_INST_CTX *context)
166*758e9fbaSOystein Eftevaag {
167*758e9fbaSOystein Eftevaag     TSS2_RC r = TSS2_RC_SUCCESS;
168*758e9fbaSOystein Eftevaag     NODE_OBJECT_T *first_in_pol_list = context->policy_elements;
169*758e9fbaSOystein Eftevaag     size_t i_last;
170*758e9fbaSOystein Eftevaag 
171*758e9fbaSOystein Eftevaag     /* While not all policy elements are instantiated */
172*758e9fbaSOystein Eftevaag     while (first_in_pol_list) {
173*758e9fbaSOystein Eftevaag         TPMT_POLICYELEMENT *pol_element = first_in_pol_list->object;
174*758e9fbaSOystein Eftevaag         switch (pol_element->type) {
175*758e9fbaSOystein Eftevaag         case POLICYSIGNED:
176*758e9fbaSOystein Eftevaag             if (pol_element->element.PolicySigned.keyPublic.type) {
177*758e9fbaSOystein Eftevaag                 /* Public info found in template, key path will not be needed. */
178*758e9fbaSOystein Eftevaag                 SAFE_FREE(pol_element->element.PolicySigned.keyPath);
179*758e9fbaSOystein Eftevaag                 break;
180*758e9fbaSOystein Eftevaag             }
181*758e9fbaSOystein Eftevaag 
182*758e9fbaSOystein Eftevaag             if (pol_element->element.PolicySigned.keyPEM &&
183*758e9fbaSOystein Eftevaag                 strlen(pol_element->element.PolicySigned.keyPEM) > 0) {
184*758e9fbaSOystein Eftevaag                 /* Determine name and public info for PEM key. */
185*758e9fbaSOystein Eftevaag                 r = set_pem_key_param(pol_element->element.PolicySigned.keyPEM,
186*758e9fbaSOystein Eftevaag                                       &pol_element->element.PolicySigned.keyPublic,
187*758e9fbaSOystein Eftevaag                                       &pol_element->element.PolicySigned.publicKey,
188*758e9fbaSOystein Eftevaag                                       pol_element->element.PolicySigned.keyPEMhashAlg);
189*758e9fbaSOystein Eftevaag                 return_if_error(r, "Set parameter of pem key.");
190*758e9fbaSOystein Eftevaag 
191*758e9fbaSOystein Eftevaag                 /* Clear pem key, will be recreated during execution. */
192*758e9fbaSOystein Eftevaag                 SAFE_FREE(pol_element->element.PolicySigned.keyPEM);
193*758e9fbaSOystein Eftevaag 
194*758e9fbaSOystein Eftevaag                 break;
195*758e9fbaSOystein Eftevaag             }
196*758e9fbaSOystein Eftevaag             CHECK_TEMPLATE_PATH(pol_element->element.PolicySigned.keyPath, "PolicySigned");
197*758e9fbaSOystein Eftevaag 
198*758e9fbaSOystein Eftevaag             /* Public info will be added to policy. */
199*758e9fbaSOystein Eftevaag             r = context->callbacks.cbpublic(pol_element->element.PolicySigned.keyPath,
200*758e9fbaSOystein Eftevaag                                             &pol_element->element.PolicySigned.keyPublic,
201*758e9fbaSOystein Eftevaag                                             context->callbacks.cbpublic_userdata);
202*758e9fbaSOystein Eftevaag             return_try_again(r);
203*758e9fbaSOystein Eftevaag             return_if_error(r, "read_finish failed");
204*758e9fbaSOystein Eftevaag             /* Clear keypath, only public data will be needed */
205*758e9fbaSOystein Eftevaag             SAFE_FREE(pol_element->element.PolicySigned.keyPath);
206*758e9fbaSOystein Eftevaag 
207*758e9fbaSOystein Eftevaag             break;
208*758e9fbaSOystein Eftevaag 
209*758e9fbaSOystein Eftevaag         case POLICYNAMEHASH:
210*758e9fbaSOystein Eftevaag             /* Set index of last name to be computed. */
211*758e9fbaSOystein Eftevaag             i_last = pol_element->element.PolicyNameHash.count - 1;
212*758e9fbaSOystein Eftevaag             while (!pol_element->element.PolicyNameHash.objectNames[i_last].size) {
213*758e9fbaSOystein Eftevaag                 /* Not all object names have been computed or were initialized */
214*758e9fbaSOystein Eftevaag                 size_t i = pol_element->element.PolicyNameHash.i;
215*758e9fbaSOystein Eftevaag                 r = context->callbacks.cbname(pol_element->element.PolicyNameHash.namePaths[i],
216*758e9fbaSOystein Eftevaag                                               &pol_element->element.PolicyNameHash.objectNames[i],
217*758e9fbaSOystein Eftevaag                                               context->callbacks.cbname_userdata);
218*758e9fbaSOystein Eftevaag                 return_try_again(r);
219*758e9fbaSOystein Eftevaag                 return_if_error(r, "get object name.");
220*758e9fbaSOystein Eftevaag                 pol_element->element.PolicyNameHash.i++;
221*758e9fbaSOystein Eftevaag                 SAFE_FREE(pol_element->element.PolicyNameHash.namePaths[i]);
222*758e9fbaSOystein Eftevaag             }
223*758e9fbaSOystein Eftevaag             break;
224*758e9fbaSOystein Eftevaag 
225*758e9fbaSOystein Eftevaag         case POLICYSECRET:
226*758e9fbaSOystein Eftevaag             if (pol_element->element.PolicySecret.objectName.size) {
227*758e9fbaSOystein Eftevaag                 /* Name found in template, object path will not be needed. */
228*758e9fbaSOystein Eftevaag                 SAFE_FREE(pol_element->element.PolicySecret.objectPath);
229*758e9fbaSOystein Eftevaag                 break;
230*758e9fbaSOystein Eftevaag             }
231*758e9fbaSOystein Eftevaag             CHECK_TEMPLATE_PATH(pol_element->element.PolicySecret.objectPath, "PolicySecret");
232*758e9fbaSOystein Eftevaag             /* Object name will be added to policy. */
233*758e9fbaSOystein Eftevaag             r = context->callbacks.cbname(pol_element->element.PolicySecret.objectPath,
234*758e9fbaSOystein Eftevaag                                           &pol_element->element.PolicySecret.objectName,
235*758e9fbaSOystein Eftevaag                                           context->callbacks.cbname_userdata);
236*758e9fbaSOystein Eftevaag             return_try_again(r);
237*758e9fbaSOystein Eftevaag             return_if_error(r, "read_finish failed");
238*758e9fbaSOystein Eftevaag             SAFE_FREE(pol_element->element.PolicySecret.objectPath);
239*758e9fbaSOystein Eftevaag             break;
240*758e9fbaSOystein Eftevaag 
241*758e9fbaSOystein Eftevaag         case POLICYPCR:
242*758e9fbaSOystein Eftevaag             if (pol_element->element.PolicyPCR.pcrs &&
243*758e9fbaSOystein Eftevaag                 pol_element->element.PolicyPCR.pcrs->count) {
244*758e9fbaSOystein Eftevaag                 /* PCR values already defined */
245*758e9fbaSOystein Eftevaag                 break;
246*758e9fbaSOystein Eftevaag             }
247*758e9fbaSOystein Eftevaag             /* Current values of PCRs will be used for policy */
248*758e9fbaSOystein Eftevaag             r = context->callbacks.cbpcr(&pol_element->element.PolicyPCR.currentPCRs,
249*758e9fbaSOystein Eftevaag                                          &pol_element->element.PolicyPCR.currentPCRandBanks,
250*758e9fbaSOystein Eftevaag                                          &pol_element->element.PolicyPCR.pcrs,
251*758e9fbaSOystein Eftevaag                                          context->callbacks.cbpcr_userdata);
252*758e9fbaSOystein Eftevaag             return_try_again(r);
253*758e9fbaSOystein Eftevaag             return_if_error(r, "read_finish failed");
254*758e9fbaSOystein Eftevaag 
255*758e9fbaSOystein Eftevaag             pol_element->element.PolicyPCR.currentPCRs.sizeofSelect = 0;
256*758e9fbaSOystein Eftevaag             pol_element->element.PolicyPCR.currentPCRandBanks.count = 0;
257*758e9fbaSOystein Eftevaag             break;
258*758e9fbaSOystein Eftevaag 
259*758e9fbaSOystein Eftevaag         case POLICYNV:
260*758e9fbaSOystein Eftevaag             if (pol_element->element.PolicyNV.nvPublic.nvPublic.nvIndex) {
261*758e9fbaSOystein Eftevaag                 /* nvIndex is already set in policy. Path will not be needed */
262*758e9fbaSOystein Eftevaag                 pol_element->element.PolicyNV.nvIndex
263*758e9fbaSOystein Eftevaag                     = pol_element->element.PolicyNV.nvPublic.nvPublic.nvIndex;
264*758e9fbaSOystein Eftevaag                 SAFE_FREE(pol_element->element.PolicyNV.nvPath);
265*758e9fbaSOystein Eftevaag                 break;
266*758e9fbaSOystein Eftevaag             }
267*758e9fbaSOystein Eftevaag 
268*758e9fbaSOystein Eftevaag             CHECK_TEMPLATE_PATH(pol_element->element.PolicyNV.nvPath, "PolicyNv");
269*758e9fbaSOystein Eftevaag             /* Object name will be added to policy. */
270*758e9fbaSOystein Eftevaag             r = context->callbacks.cbnvpublic(pol_element->element.PolicyNV.nvPath,
271*758e9fbaSOystein Eftevaag                                               &pol_element->element.PolicyNV.nvPublic,
272*758e9fbaSOystein Eftevaag                                               context->callbacks.cbnvpublic_userdata);
273*758e9fbaSOystein Eftevaag             return_try_again(r);
274*758e9fbaSOystein Eftevaag             return_if_error(r, "read_finish failed");
275*758e9fbaSOystein Eftevaag 
276*758e9fbaSOystein Eftevaag             pol_element->element.PolicyNV.nvIndex
277*758e9fbaSOystein Eftevaag                 = pol_element->element.PolicyNV.nvPublic.nvPublic.nvIndex;
278*758e9fbaSOystein Eftevaag 
279*758e9fbaSOystein Eftevaag             /* Clear NV path, only public data will be needed */
280*758e9fbaSOystein Eftevaag             SAFE_FREE(pol_element->element.PolicyNV.nvPath);
281*758e9fbaSOystein Eftevaag             break;
282*758e9fbaSOystein Eftevaag 
283*758e9fbaSOystein Eftevaag         case POLICYDUPLICATIONSELECT:
284*758e9fbaSOystein Eftevaag             if (pol_element->element.PolicyDuplicationSelect.newParentPublic.publicArea.type) {
285*758e9fbaSOystein Eftevaag                 /* public data is already set in policy. Path will not be needed. */
286*758e9fbaSOystein Eftevaag                 SAFE_FREE(pol_element->element.PolicyDuplicationSelect.newParentPath);
287*758e9fbaSOystein Eftevaag                 break;
288*758e9fbaSOystein Eftevaag             }
289*758e9fbaSOystein Eftevaag 
290*758e9fbaSOystein Eftevaag             CHECK_TEMPLATE_PATH(pol_element->element.PolicyDuplicationSelect.newParentPath,
291*758e9fbaSOystein Eftevaag                                 "PolicyDuplicationselect");
292*758e9fbaSOystein Eftevaag 
293*758e9fbaSOystein Eftevaag             /* Public info will be added to policy. */
294*758e9fbaSOystein Eftevaag             r = context->callbacks.cbpublic(
295*758e9fbaSOystein Eftevaag                      pol_element->element.PolicyDuplicationSelect.newParentPath,
296*758e9fbaSOystein Eftevaag                      &pol_element->element.PolicyDuplicationSelect.newParentPublic.publicArea,
297*758e9fbaSOystein Eftevaag                      context->callbacks.cbpublic_userdata);
298*758e9fbaSOystein Eftevaag             return_try_again(r);
299*758e9fbaSOystein Eftevaag             return_if_error(r, "read_finish failed");
300*758e9fbaSOystein Eftevaag 
301*758e9fbaSOystein Eftevaag             r = ifapi_get_name(
302*758e9fbaSOystein Eftevaag                      &pol_element->element.PolicyDuplicationSelect.newParentPublic.publicArea,
303*758e9fbaSOystein Eftevaag                      &pol_element->element.PolicyDuplicationSelect.newParentName);
304*758e9fbaSOystein Eftevaag             return_if_error(r, "Compute key name");
305*758e9fbaSOystein Eftevaag 
306*758e9fbaSOystein Eftevaag             /* Clear keypath, only public data will be needed */
307*758e9fbaSOystein Eftevaag             SAFE_FREE(pol_element->element.PolicyDuplicationSelect.newParentPath);
308*758e9fbaSOystein Eftevaag             break;
309*758e9fbaSOystein Eftevaag 
310*758e9fbaSOystein Eftevaag         case POLICYAUTHORIZENV:
311*758e9fbaSOystein Eftevaag             if (pol_element->element.PolicyAuthorizeNv.nvPublic.nvPublic.nvIndex) {
312*758e9fbaSOystein Eftevaag                 /* nvIndex is already set in policy. Path will not be needed */
313*758e9fbaSOystein Eftevaag                 SAFE_FREE(pol_element->element.PolicyAuthorizeNv.nvPath);
314*758e9fbaSOystein Eftevaag                 break;
315*758e9fbaSOystein Eftevaag             }
316*758e9fbaSOystein Eftevaag 
317*758e9fbaSOystein Eftevaag             CHECK_TEMPLATE_PATH(pol_element->element.PolicyAuthorizeNv.nvPath,
318*758e9fbaSOystein Eftevaag                                 "PolicyAuthorizeNv");
319*758e9fbaSOystein Eftevaag             /* Object name will be added to policy. */
320*758e9fbaSOystein Eftevaag             r = context->callbacks.cbnvpublic(pol_element->element.PolicyAuthorizeNv.nvPath,
321*758e9fbaSOystein Eftevaag                                               &pol_element->element.PolicyAuthorizeNv.nvPublic,
322*758e9fbaSOystein Eftevaag                                               context->callbacks.cbnvpublic_userdata);
323*758e9fbaSOystein Eftevaag             return_try_again(r);
324*758e9fbaSOystein Eftevaag             return_if_error(r, "read_finish failed");
325*758e9fbaSOystein Eftevaag             /* Clear NV path, only public data will be needed */
326*758e9fbaSOystein Eftevaag             SAFE_FREE(pol_element->element.PolicyAuthorizeNv.nvPath);
327*758e9fbaSOystein Eftevaag             break;
328*758e9fbaSOystein Eftevaag 
329*758e9fbaSOystein Eftevaag         case POLICYAUTHORIZE:
330*758e9fbaSOystein Eftevaag             if (pol_element->element.PolicyAuthorize.keyPublic.type) {
331*758e9fbaSOystein Eftevaag                 /* Public info found in template, key path will not be needed. */
332*758e9fbaSOystein Eftevaag                 SAFE_FREE(pol_element->element.PolicyAuthorize.keyPath);
333*758e9fbaSOystein Eftevaag                 r = ifapi_get_name(&pol_element->element.PolicyAuthorize.keyPublic,
334*758e9fbaSOystein Eftevaag                                    &pol_element->element.PolicyAuthorize.keyName);
335*758e9fbaSOystein Eftevaag                 return_if_error(r, "Compute key name");
336*758e9fbaSOystein Eftevaag 
337*758e9fbaSOystein Eftevaag                 break;
338*758e9fbaSOystein Eftevaag             }
339*758e9fbaSOystein Eftevaag 
340*758e9fbaSOystein Eftevaag             if (pol_element->element.PolicyAuthorize.keyPEM &&
341*758e9fbaSOystein Eftevaag                 strlen(pol_element->element.PolicyAuthorize.keyPEM) > 0) {
342*758e9fbaSOystein Eftevaag                 /* Determine name and public info for PEM key. */
343*758e9fbaSOystein Eftevaag                 r = set_pem_key_param(pol_element->element.PolicyAuthorize.keyPEM,
344*758e9fbaSOystein Eftevaag                                       &pol_element->element.PolicyAuthorize.keyPublic,
345*758e9fbaSOystein Eftevaag                                       &pol_element->element.PolicyAuthorize.keyName,
346*758e9fbaSOystein Eftevaag                                       pol_element->element.PolicyAuthorize.keyPEMhashAlg);
347*758e9fbaSOystein Eftevaag                 return_if_error(r, "Set parameter of pem key.");
348*758e9fbaSOystein Eftevaag 
349*758e9fbaSOystein Eftevaag                 pol_element->element.PolicyAuthorize.keyPEM = NULL;
350*758e9fbaSOystein Eftevaag 
351*758e9fbaSOystein Eftevaag                 break;
352*758e9fbaSOystein Eftevaag             }
353*758e9fbaSOystein Eftevaag 
354*758e9fbaSOystein Eftevaag             CHECK_TEMPLATE_PATH(pol_element->element.PolicyAuthorize.keyPath, "PolicyAuthorize");
355*758e9fbaSOystein Eftevaag 
356*758e9fbaSOystein Eftevaag             /* Object public data will be added to policy. */
357*758e9fbaSOystein Eftevaag             r = context->callbacks.cbpublic(pol_element->element.PolicyAuthorize.keyPath,
358*758e9fbaSOystein Eftevaag                                             &pol_element->element.PolicyAuthorize.keyPublic,
359*758e9fbaSOystein Eftevaag                                             context->callbacks.cbpublic_userdata);
360*758e9fbaSOystein Eftevaag             return_try_again(r);
361*758e9fbaSOystein Eftevaag             return_if_error(r, "read_finish failed");
362*758e9fbaSOystein Eftevaag 
363*758e9fbaSOystein Eftevaag             /* Compute key name from public info */
364*758e9fbaSOystein Eftevaag             r = ifapi_get_name(&pol_element->element.PolicyAuthorize.keyPublic,
365*758e9fbaSOystein Eftevaag                                &pol_element->element.PolicyAuthorize.keyName);
366*758e9fbaSOystein Eftevaag             return_if_error(r, "Compute key name");
367*758e9fbaSOystein Eftevaag 
368*758e9fbaSOystein Eftevaag             /* Clear key path, only public data will be needed */
369*758e9fbaSOystein Eftevaag             SAFE_FREE(pol_element->element.PolicyAuthorize.keyPath);
370*758e9fbaSOystein Eftevaag             break;
371*758e9fbaSOystein Eftevaag         }
372*758e9fbaSOystein Eftevaag         /* Cleanup head of list and use next policy element */
373*758e9fbaSOystein Eftevaag         context->policy_elements = first_in_pol_list->next;
374*758e9fbaSOystein Eftevaag         SAFE_FREE(first_in_pol_list);
375*758e9fbaSOystein Eftevaag     }
376*758e9fbaSOystein Eftevaag     return r;
377*758e9fbaSOystein Eftevaag }
378