• 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 #endif
10 
11 #include <stdio.h>
12 #include <string.h>
13 
14 #include "tpm_json_deserialize.h"
15 #include "ifapi_json_deserialize.h"
16 #include "fapi_policy.h"
17 #include "ifapi_config.h"
18 #define LOGMODULE fapijson
19 #include "util/log.h"
20 #include "util/aux_util.h"
21 
22 static char *tss_const_prefixes[] = { "TPM2_ALG_", "TPM2_", "TPM_", "TPMA_", "POLICY", NULL };
23 
24 /** Get the index of a sub string after a certain prefix.
25  *
26  * The prefixes from table tss_const_prefixes will be used for case
27  * insensitive comparison.
28  *
29  * param[in] token the token with a potential prefix.
30  * @retval the position of the sub string after the prefix.
31  * @retval 0 if no prefix is found.
32  */
33 static int
get_token_start_idx(const char * token)34 get_token_start_idx(const char *token)
35 {
36     int itoken = 0;
37     char *entry;
38     int i;
39 
40     for (i = 0, entry = tss_const_prefixes[0]; entry != NULL;
41             i++, entry = tss_const_prefixes[i]) {
42         if (strncasecmp(token, entry, strlen(entry)) == 0) {
43             itoken += strlen(entry);
44             break;
45         }
46     }
47     return itoken;
48 }
49 
50 /** Get number from a string.
51  *
52  * A string which represents a number or hex number (prefix 0x) is converted
53  * to an int64 number.
54  *
55  * param[in] token the string representing the number.
56  * param[out] num the converted number.
57  * @retval true if token represents a number
58  * @retval false if token does not represent a number.
59  */
60 static bool
get_number(const char * token,int64_t * num)61 get_number(const char *token, int64_t *num)
62 {
63     int itoken = 0;
64     int pos = 0;
65     if (strncmp(token, "0x", 2) == 0) {
66         itoken = 2;
67         sscanf(&token[itoken], "%"PRIx64"%n", num, &pos);
68     } else {
69         sscanf(&token[itoken], "%"PRId64"%n", num, &pos);
70     }
71     if ((size_t)pos == strlen(token) - itoken)
72         return true;
73     else
74         return false;
75 }
76 
77 /** Deserialize a character string.
78  *
79  * @param[in] jso json string object.
80  * @param[out] out the pointer to the created string.
81  * @retval TSS2_RC_SUCCESS if the function call was a success.
82  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
83  */
84 TSS2_RC
ifapi_json_char_deserialize(json_object * jso,char ** out)85 ifapi_json_char_deserialize(
86     json_object *jso,
87     char **out)
88 {
89     *out = strdup(json_object_get_string(jso));
90     return_if_null(*out, "Out of memory.", TSS2_FAPI_RC_MEMORY);
91     return TSS2_RC_SUCCESS;
92 }
93 
94 /** Deserialize a IFAPI_KEY json object.
95  *
96  * @param[in]  jso the json object to be deserialized.
97  * @param[out] out the deserialzed binary object.
98  * @retval TSS2_RC_SUCCESS if the function call was a success.
99  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
100  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
101  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
102  */
103 TSS2_RC
ifapi_json_IFAPI_KEY_deserialize(json_object * jso,IFAPI_KEY * out)104 ifapi_json_IFAPI_KEY_deserialize(json_object *jso,  IFAPI_KEY *out)
105 {
106     json_object *jso2;
107     TSS2_RC r;
108     LOG_TRACE("call");
109     return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
110 
111 
112     if (!ifapi_get_sub_object(jso, "persistent_handle", &jso2)) {
113         LOG_ERROR("Bad value");
114         return TSS2_FAPI_RC_BAD_VALUE;
115     }
116     r = ifapi_json_UINT32_deserialize(jso2, &out->persistent_handle);
117     return_if_error(r, "BAD VALUE");
118 
119     if (ifapi_get_sub_object(jso, "with_auth", &jso2)) {
120         r = ifapi_json_TPMI_YES_NO_deserialize(jso2, &out->with_auth);
121         return_if_error(r, "BAD VALUE");
122 
123     } else {
124         out->with_auth = TPM2_NO;
125     }
126 
127     if (!ifapi_get_sub_object(jso, "public", &jso2)) {
128         LOG_ERROR("Bad value");
129         return TSS2_FAPI_RC_BAD_VALUE;
130     }
131     r = ifapi_json_TPM2B_PUBLIC_deserialize(jso2, &out->public);
132     return_if_error(r, "BAD VALUE");
133 
134     if (!ifapi_get_sub_object(jso, "serialization", &jso2)) {
135         LOG_ERROR("Bad value");
136         return TSS2_FAPI_RC_BAD_VALUE;
137     }
138     r = ifapi_json_UINT8_ARY_deserialize(jso2, &out->serialization);
139     return_if_error(r, "BAD VALUE");
140 
141     if (!ifapi_get_sub_object(jso, "private", &jso2)) {
142         memset(&out->private, 0, sizeof(UINT8_ARY));
143     } else {
144         r = ifapi_json_UINT8_ARY_deserialize(jso2, &out->private);
145         return_if_error(r, "BAD VALUE");
146     }
147 
148     if (!ifapi_get_sub_object(jso, "appData", &jso2)) {
149         memset(&out->appData, 0, sizeof(UINT8_ARY));
150     } else {
151         r = ifapi_json_UINT8_ARY_deserialize(jso2, &out->appData);
152         return_if_error(r, "BAD VALUE");
153     }
154 
155     if (!ifapi_get_sub_object(jso, "policyInstance", &jso2)) {
156         LOG_ERROR("Bad value");
157         return TSS2_FAPI_RC_BAD_VALUE;
158     }
159     r = ifapi_json_char_deserialize(jso2, &out->policyInstance);
160     return_if_error(r, "BAD VALUE");
161 
162     if (ifapi_get_sub_object(jso, "creationData", &jso2)) {
163         r = ifapi_json_TPM2B_CREATION_DATA_deserialize(jso2, &out->creationData);
164         return_if_error(r, "BAD VALUE");
165 
166     } else {
167         memset(&out->creationData, 0, sizeof(TPM2B_CREATION_DATA));
168     }
169 
170     if (ifapi_get_sub_object(jso, "creationTicket", &jso2)) {
171         r = ifapi_json_TPMT_TK_CREATION_deserialize(jso2, &out->creationTicket);
172         return_if_error(r, "BAD VALUE");
173 
174     } else {
175         memset(&out->creationData, 0, sizeof(TPMT_TK_CREATION));
176     }
177     if (!ifapi_get_sub_object(jso, "description", &jso2)) {
178         LOG_ERROR("Bad value");
179         return TSS2_FAPI_RC_BAD_VALUE;
180     }
181     r = ifapi_json_char_deserialize(jso2, &out->description);
182     return_if_error(r, "BAD VALUE");
183 
184     if (!ifapi_get_sub_object(jso, "certificate", &jso2)) {
185         LOG_ERROR("Bad value");
186         return TSS2_FAPI_RC_BAD_VALUE;
187     }
188     r = ifapi_json_char_deserialize(jso2, &out->certificate);
189     return_if_error(r, "BAD VALUE");
190 
191     if (out->public.publicArea.type != TPM2_ALG_KEYEDHASH) {
192          /* Keyed hash objects to not need a signing scheme. */
193         if (!ifapi_get_sub_object(jso, "signing_scheme", &jso2)) {
194             LOG_ERROR("Bad value");
195             return TSS2_FAPI_RC_BAD_VALUE;
196         }
197         r = ifapi_json_TPMT_SIG_SCHEME_deserialize(jso2, &out->signing_scheme);
198         return_if_error(r, "BAD VALUE");
199     }
200 
201     if (!ifapi_get_sub_object(jso, "name", &jso2)) {
202         LOG_ERROR("Bad value");
203         return TSS2_FAPI_RC_BAD_VALUE;
204     }
205     r = ifapi_json_TPM2B_NAME_deserialize(jso2, &out->name);
206     return_if_error(r, "BAD VALUE");
207     LOG_TRACE("true");
208     return TSS2_RC_SUCCESS;
209 }
210 
211 /** Deserialize a IFAPI_EXT_PUB_KEY json object.
212  *
213  * @param[in]  jso the json object to be deserialized.
214  * @param[out] out the deserialzed binary object.
215  * @retval TSS2_RC_SUCCESS if the function call was a success.
216  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
217  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
218  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
219  */
220 TSS2_RC
ifapi_json_IFAPI_EXT_PUB_KEY_deserialize(json_object * jso,IFAPI_EXT_PUB_KEY * out)221 ifapi_json_IFAPI_EXT_PUB_KEY_deserialize(json_object *jso,
222         IFAPI_EXT_PUB_KEY *out)
223 {
224     json_object *jso2;
225     TSS2_RC r;
226     LOG_TRACE("call");
227     return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
228 
229 
230     if (!ifapi_get_sub_object(jso, "pem_ext_public", &jso2)) {
231         LOG_ERROR("Bad value");
232         return TSS2_FAPI_RC_BAD_VALUE;
233     }
234     r = ifapi_json_char_deserialize(jso2, &out->pem_ext_public);
235     return_if_error(r, "BAD VALUE");
236 
237     if (ifapi_get_sub_object(jso, "certificate", &jso2)) {
238         r = ifapi_json_char_deserialize(jso2, &out->certificate);
239         return_if_error(r, "BAD VALUE");
240     } else {
241         out->certificate = NULL;
242     }
243 
244     if (ifapi_get_sub_object(jso, "public", &jso2)) {
245         r = ifapi_json_TPM2B_PUBLIC_deserialize(jso2, &out->public);
246         return_if_error(r, "BAD VALUE");
247 
248     } else {
249         memset(&out->public, 0, sizeof(TPM2B_PUBLIC));
250     }
251     LOG_TRACE("true");
252     return TSS2_RC_SUCCESS;
253 }
254 
255 /** Deserialize a IFAPI_NV json object.
256  *
257  * @param[in]  jso the json object to be deserialized.
258  * @param[out] out the deserialzed binary object.
259  * @retval TSS2_RC_SUCCESS if the function call was a success.
260  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
261  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
262  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
263  */
264 TSS2_RC
ifapi_json_IFAPI_NV_deserialize(json_object * jso,IFAPI_NV * out)265 ifapi_json_IFAPI_NV_deserialize(json_object *jso,  IFAPI_NV *out)
266 {
267     json_object *jso2;
268     TSS2_RC r;
269     LOG_TRACE("call");
270     return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
271 
272     if (!ifapi_get_sub_object(jso, "appData", &jso2)) {
273         memset(&out->appData, 0, sizeof(UINT8_ARY));
274     } else {
275         r = ifapi_json_UINT8_ARY_deserialize(jso2, &out->appData);
276         return_if_error(r, "BAD VALUE");
277     }
278 
279     if (ifapi_get_sub_object(jso, "with_auth", &jso2)) {
280         r = ifapi_json_TPMI_YES_NO_deserialize(jso2, &out->with_auth);
281         return_if_error(r, "BAD VALUE");
282 
283     } else {
284         out->with_auth = TPM2_NO;
285     }
286 
287     if (!ifapi_get_sub_object(jso, "public", &jso2)) {
288         LOG_ERROR("Bad value");
289         return TSS2_FAPI_RC_BAD_VALUE;
290     }
291     r = ifapi_json_TPM2B_NV_PUBLIC_deserialize(jso2, &out->public);
292     return_if_error(r, "BAD VALUE");
293 
294     if (!ifapi_get_sub_object(jso, "serialization", &jso2)) {
295         LOG_ERROR("Bad value");
296         return TSS2_FAPI_RC_BAD_VALUE;
297     }
298     r = ifapi_json_UINT8_ARY_deserialize(jso2, &out->serialization);
299     return_if_error(r, "BAD VALUE");
300 
301     if (!ifapi_get_sub_object(jso, "hierarchy", &jso2)) {
302         LOG_ERROR("Bad value");
303         return TSS2_FAPI_RC_BAD_VALUE;
304     }
305     r = ifapi_json_UINT32_deserialize(jso2, &out->hierarchy);
306     return_if_error(r, "BAD VALUE");
307 
308     if (!ifapi_get_sub_object(jso, "policyInstance", &jso2)) {
309         LOG_ERROR("Bad value");
310         return TSS2_FAPI_RC_BAD_VALUE;
311     }
312     r = ifapi_json_char_deserialize(jso2, &out->policyInstance);
313     return_if_error(r, "BAD VALUE");
314 
315     if (!ifapi_get_sub_object(jso, "description", &jso2)) {
316         LOG_ERROR("Bad value");
317         return TSS2_FAPI_RC_BAD_VALUE;
318     }
319     r = ifapi_json_char_deserialize(jso2, &out->description);
320     return_if_error(r, "BAD VALUE");
321 
322     return_if_error(r, "BAD VALUE");
323     if (ifapi_get_sub_object(jso, "event_log", &jso2)) {
324         r = ifapi_json_char_deserialize(jso2, &out->event_log);
325         return_if_error(r, "BAD VALUE");
326 
327     } else {
328         out->event_log = NULL;
329     }
330     LOG_TRACE("true");
331     return TSS2_RC_SUCCESS;
332 }
333 
334 /** Deserialize a IFAPI_NV json object.
335  *
336  * @param[in]  jso the json object to be deserialized.
337  * @param[out] out the deserialzed binary object.
338  * @retval TSS2_RC_SUCCESS if the function call was a success.
339  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
340  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
341  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
342  */
343 TSS2_RC
ifapi_json_IFAPI_HIERARCHY_deserialize(json_object * jso,IFAPI_HIERARCHY * out)344 ifapi_json_IFAPI_HIERARCHY_deserialize(json_object *jso,  IFAPI_HIERARCHY *out)
345 {
346     json_object *jso2;
347     TSS2_RC r;
348     LOG_TRACE("call");
349     return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
350 
351     if (ifapi_get_sub_object(jso, "with_auth", &jso2)) {
352         r = ifapi_json_TPMI_YES_NO_deserialize(jso2, &out->with_auth);
353         return_if_error(r, "BAD VALUE");
354 
355     } else {
356         out->with_auth = TPM2_NO;
357     }
358 
359     if (!ifapi_get_sub_object(jso, "authPolicy", &jso2)) {
360         LOG_ERROR("Bad value");
361         return TSS2_FAPI_RC_BAD_VALUE;
362     }
363     r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->authPolicy);
364     return_if_error(r, "BAD VALUE");
365 
366     if (!ifapi_get_sub_object(jso, "description", &jso2)) {
367         LOG_ERROR("Bad value");
368         return TSS2_FAPI_RC_BAD_VALUE;
369     }
370     r = ifapi_json_char_deserialize(jso2, &out->description);
371     return_if_error(r, "BAD VALUE");
372 
373     LOG_TRACE("true");
374     return TSS2_RC_SUCCESS;
375 }
376 
377 /** Deserialize a FAPI_QUOTE_INFO json object.
378  *
379  * @param[in]  jso the json object to be deserialized.
380  * @param[out] out the deserialzed binary object.
381  * @retval TSS2_RC_SUCCESS if the function call was a success.
382  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
383  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
384  */
385 TSS2_RC
ifapi_json_FAPI_QUOTE_INFO_deserialize(json_object * jso,FAPI_QUOTE_INFO * out)386 ifapi_json_FAPI_QUOTE_INFO_deserialize(json_object *jso,  FAPI_QUOTE_INFO *out)
387 {
388     json_object *jso2;
389     TSS2_RC r;
390     LOG_TRACE("call");
391     return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
392 
393 
394     if (!ifapi_get_sub_object(jso, "sig_scheme", &jso2)) {
395         LOG_ERROR("Bad value");
396         return TSS2_FAPI_RC_BAD_VALUE;
397     }
398     r = ifapi_json_TPMT_SIG_SCHEME_deserialize(jso2, &out->sig_scheme);
399     return_if_error(r, "BAD VALUE");
400 
401     if (!ifapi_get_sub_object(jso, "attest", &jso2)) {
402         LOG_ERROR("Bad value");
403         return TSS2_FAPI_RC_BAD_VALUE;
404     }
405     r = ifapi_json_TPMS_ATTEST_deserialize(jso2, &out->attest);
406     return_if_error(r, "BAD VALUE");
407     LOG_TRACE("true");
408     return TSS2_RC_SUCCESS;
409 }
410 
411 /** Deserialize a IFAPI_DUPLICATE json object.
412  *
413  * @param[in]  jso the json object to be deserialized.
414  * @param[out] out the deserialzed binary object.
415  * @retval TSS2_RC_SUCCESS if the function call was a success.
416  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
417  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
418  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
419  */
420 TSS2_RC
ifapi_json_IFAPI_DUPLICATE_deserialize(json_object * jso,IFAPI_DUPLICATE * out)421 ifapi_json_IFAPI_DUPLICATE_deserialize(json_object *jso, IFAPI_DUPLICATE *out)
422 {
423     json_object *jso2;
424     TSS2_RC r;
425     LOG_TRACE("call");
426     return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
427 
428     if (!ifapi_get_sub_object(jso, "duplicate", &jso2)) {
429         LOG_ERROR("Bad value");
430         return TSS2_FAPI_RC_BAD_VALUE;
431     }
432 
433     r = ifapi_json_TPM2B_PRIVATE_deserialize(jso2, &out->duplicate);
434     return_if_error(r, "BAD VALUE");
435 
436     if (!ifapi_get_sub_object(jso, "encrypted_seed", &jso2)) {
437         LOG_ERROR("Bad value");
438         return TSS2_FAPI_RC_BAD_VALUE;
439     }
440     r = ifapi_json_TPM2B_ENCRYPTED_SECRET_deserialize(jso2, &out->encrypted_seed);
441     return_if_error(r, "BAD VALUE");
442 
443     if (ifapi_get_sub_object(jso, "certificate", &jso2)) {
444         r = ifapi_json_char_deserialize(jso2, &out->certificate);
445         return_if_error(r, "BAD VALUE");
446 
447     } else {
448         out->certificate = NULL;
449     }
450 
451     if (!ifapi_get_sub_object(jso, "public", &jso2)) {
452         LOG_ERROR("Bad value");
453         return TSS2_FAPI_RC_BAD_VALUE;
454     }
455 
456     r = ifapi_json_TPM2B_PUBLIC_deserialize(jso2, &out->public);
457     return_if_error(r, "BAD VALUE");
458     if (!ifapi_get_sub_object(jso, "public_parent", &jso2)) {
459         LOG_ERROR("Bad value");
460         return TSS2_FAPI_RC_BAD_VALUE;
461     }
462 
463     r = ifapi_json_TPM2B_PUBLIC_deserialize(jso2, &out->public_parent);
464     return_if_error(r, "BAD VALUE");
465 
466     if (ifapi_get_sub_object(jso, "policy", &jso2)) {
467         out->policy = calloc(1, sizeof(TPMS_POLICY));
468         goto_if_null2(out->policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
469                       error_cleanup);
470 
471         r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->policy);
472         goto_if_error(r, "Deserialize policy.", error_cleanup);
473     } else {
474         out->policy = NULL;
475     }
476 
477     return TSS2_RC_SUCCESS;
478 
479 error_cleanup:
480     SAFE_FREE(out->policy);
481     return r;
482 }
483 
484 /**  Deserialize a IFAPI_OBJECT_TYPE_CONSTANT json object.
485  *
486  * @param[in]  jso the json object to be deserialized.
487  * @param[out] out the deserialzed binary object.
488  * @retval TSS2_RC_SUCCESS if the function call was a success.
489  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
490  */
491 TSS2_RC
ifapi_json_IFAPI_OBJECT_TYPE_CONSTANT_deserialize(json_object * jso,IFAPI_OBJECT_TYPE_CONSTANT * out)492 ifapi_json_IFAPI_OBJECT_TYPE_CONSTANT_deserialize(json_object *jso,
493         IFAPI_OBJECT_TYPE_CONSTANT *out)
494 {
495     LOG_TRACE("call");
496     const char *token = json_object_get_string(jso);
497     int64_t i64;
498     if (get_number(token, &i64)) {
499         *out = (IFAPI_OBJECT_TYPE_CONSTANT) i64;
500         if ((int64_t)*out != i64) {
501             LOG_ERROR("Bad value");
502             return TSS2_FAPI_RC_BAD_VALUE;
503         }
504         return TSS2_RC_SUCCESS;
505     } else {
506         LOG_ERROR("Bad value");
507         return TSS2_FAPI_RC_BAD_VALUE;
508     }
509 }
510 
511 /** Deserialize a IFAPI_OBJECT json object.
512  *
513  * @param[in]  jso the json object to be deserialized.
514  * @param[out] out the deserialzed binary object.
515  * @retval TSS2_RC_SUCCESS if the function call was a success.
516  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
517  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
518  * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
519  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
520  */
521 TSS2_RC
ifapi_json_IFAPI_OBJECT_deserialize(json_object * jso,IFAPI_OBJECT * out)522 ifapi_json_IFAPI_OBJECT_deserialize(json_object *jso, IFAPI_OBJECT *out)
523 {
524     json_object *jso2;
525     TSS2_RC r;
526     LOG_TRACE("call");
527     return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
528 
529     if (!ifapi_get_sub_object(jso, "objectType", &jso2)) {
530         LOG_ERROR("Bad value");
531         return TSS2_FAPI_RC_BAD_VALUE;
532     }
533 
534     r = ifapi_json_IFAPI_OBJECT_TYPE_CONSTANT_deserialize(jso2, &out->objectType);
535     return_if_error(r, "BAD VALUE");
536 
537     switch (out->objectType) {
538     case IFAPI_NV_OBJ:
539         r = ifapi_json_IFAPI_NV_deserialize(jso, &out->misc.nv);
540         return_if_error(r, "BAD VALUE");
541         break;
542 
543     case IFAPI_DUPLICATE_OBJ:
544         r = ifapi_json_IFAPI_DUPLICATE_deserialize(jso, &out->misc.key_tree);
545         return_if_error(r, "BAD VALUE");
546 
547         break;
548 
549     case IFAPI_EXT_PUB_KEY_OBJ:
550         r = ifapi_json_IFAPI_EXT_PUB_KEY_deserialize(jso, &out->misc.ext_pub_key);
551         return_if_error(r, "BAD VALUE");
552 
553         break;
554 
555     case IFAPI_HIERARCHY_OBJ:
556         r = ifapi_json_IFAPI_HIERARCHY_deserialize(jso, &out->misc.hierarchy);
557         return_if_error(r, "BAD VALUE");
558 
559         break;
560     case IFAPI_KEY_OBJ:
561         r = ifapi_json_IFAPI_KEY_deserialize(jso, &out->misc.key);
562         return_if_error(r, "BAD VALUE");
563 
564         break;
565     default:
566         goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Invalid call deserialize",
567                    cleanup);
568     }
569 
570     if (ifapi_get_sub_object(jso, "system", &jso2)) {
571         r = ifapi_json_TPMI_YES_NO_deserialize(jso2, &out->system);
572         return_if_error(r, "BAD VALUE");
573 
574     } else {
575         out->system = TPM2_NO;
576     }
577 
578     if (ifapi_get_sub_object(jso, "policy", &jso2)) {
579         out->policy = calloc(1, sizeof(TPMS_POLICY));
580         goto_if_null2(out->policy, "Out of memory.", r, TSS2_FAPI_RC_MEMORY,
581                       cleanup);
582 
583         r = ifapi_json_TPMS_POLICY_deserialize(jso2, out->policy);
584         goto_if_error(r, "Deserialize policy.", cleanup);
585     } else {
586         out->policy = NULL;
587     }
588 
589     return TSS2_RC_SUCCESS;
590 
591 cleanup:
592     SAFE_FREE(out->policy);
593     return r;
594 }
595 
596 /** Deserialize a IFAPI_EVENT_TYPE json object.
597  *
598  * @param[in]  jso the json object to be deserialized.
599  * @param[out] out the deserialzed binary object.
600  * @retval TSS2_RC_SUCCESS if the function call was a success.
601  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
602  */
603 TSS2_RC
ifapi_json_IFAPI_EVENT_TYPE_deserialize(json_object * jso,IFAPI_EVENT_TYPE * out)604 ifapi_json_IFAPI_EVENT_TYPE_deserialize(json_object *jso, IFAPI_EVENT_TYPE *out)
605 {
606     LOG_TRACE("call");
607     return ifapi_json_IFAPI_EVENT_TYPE_deserialize_txt(jso, out);
608 }
609 
610 typedef struct {
611     IFAPI_EVENT_TYPE in;
612     char *name;
613 } IFAPI_IFAPI_EVENT_TYPE_ASSIGN;
614 
615 static IFAPI_IFAPI_EVENT_TYPE_ASSIGN deserialize_IFAPI_EVENT_TYPE_tab[] = {
616     { IFAPI_IMA_EVENT_TAG, "ima-legacy" },
617     { IFAPI_TSS_EVENT_TAG, "tss2" },
618 };
619 
620 /**  Deserialize a json object of type IFAPI_EVENT_TYPE.
621  *
622  * @param[in]  jso the json object to be deserialized.
623  * @param[out] out the deserialzed binary object.
624  * @retval TSS2_RC_SUCCESS if the function call was a success.
625  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
626  */
627 TSS2_RC
ifapi_json_IFAPI_EVENT_TYPE_deserialize_txt(json_object * jso,IFAPI_EVENT_TYPE * out)628 ifapi_json_IFAPI_EVENT_TYPE_deserialize_txt(json_object *jso,
629         IFAPI_EVENT_TYPE *out)
630 {
631     LOG_TRACE("call");
632     const char *token = json_object_get_string(jso);
633     int64_t i64;
634     if (get_number(token, &i64)) {
635         *out = (IFAPI_EVENT_TYPE) i64;
636         if ((int64_t)*out != i64) {
637             LOG_ERROR("Bad value");
638             return TSS2_FAPI_RC_BAD_VALUE;
639         }
640         return TSS2_RC_SUCCESS;
641 
642     } else {
643         int itoken = get_token_start_idx(token);
644         size_t i;
645         size_t n = sizeof(deserialize_IFAPI_EVENT_TYPE_tab) /
646                    sizeof(deserialize_IFAPI_EVENT_TYPE_tab[0]);
647         size_t size = strlen(token) - itoken;
648         for (i = 0; i < n; i++) {
649             if (strncasecmp(&token[itoken],
650                             &deserialize_IFAPI_EVENT_TYPE_tab[i].name[0],
651                             size) == 0) {
652                 *out = deserialize_IFAPI_EVENT_TYPE_tab[i].in;
653                 return TSS2_RC_SUCCESS;
654             }
655         }
656         return_error(TSS2_FAPI_RC_BAD_VALUE, "Undefined constant.");
657     }
658 
659 }
660 
661 /** Deserialize a IFAPI_TSS_EVENT json object.
662  *
663  * @param[in]  jso the json object to be deserialized.
664  * @param[out] out the deserialzed binary object.
665  * @retval TSS2_RC_SUCCESS if the function call was a success.
666  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
667  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
668  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
669  */
670 TSS2_RC
ifapi_json_IFAPI_TSS_EVENT_deserialize(json_object * jso,IFAPI_TSS_EVENT * out)671 ifapi_json_IFAPI_TSS_EVENT_deserialize(json_object *jso,  IFAPI_TSS_EVENT *out)
672 {
673     json_object *jso2;
674     TSS2_RC r;
675     LOG_TRACE("call");
676     return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
677 
678     if (!ifapi_get_sub_object(jso, "data", &jso2)) {
679         LOG_ERROR("Bad value");
680         return TSS2_FAPI_RC_BAD_VALUE;
681     }
682     r = ifapi_json_TPM2B_EVENT_deserialize(jso2, &out->data);
683     return_if_error(r, "BAD VALUE");
684 
685     if (!ifapi_get_sub_object(jso, "event", &jso2)) {
686         out->event = NULL;
687     } else {
688         /* out->event is a special case. It can be an arbitrary
689            JSON object. Since FAPI does not access its internals
690            we just store its string represenation here. */
691         out->event = strdup(json_object_to_json_string_ext(jso2,
692                                 JSON_C_TO_STRING_PRETTY));
693         return_if_null(out->event, "OOM", TSS2_FAPI_RC_MEMORY);
694     }
695     LOG_TRACE("true");
696     return TSS2_RC_SUCCESS;
697 }
698 
699 /** Deserialize a IFAPI_IMA_EVENT json object.
700  *
701  * @param[in]  jso the json object to be deserialized.
702  * @param[out] out the deserialzed binary object.
703  * @retval TSS2_RC_SUCCESS if the function call was a success.
704  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
705  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
706  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
707  */
708 TSS2_RC
ifapi_json_IFAPI_IMA_EVENT_deserialize(json_object * jso,IFAPI_IMA_EVENT * out)709 ifapi_json_IFAPI_IMA_EVENT_deserialize(json_object *jso,  IFAPI_IMA_EVENT *out)
710 {
711     json_object *jso2;
712     TSS2_RC r;
713     LOG_TRACE("call");
714     return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
715 
716     if (!ifapi_get_sub_object(jso, "eventData", &jso2)) {
717         LOG_ERROR("Bad value");
718         return TSS2_FAPI_RC_BAD_VALUE;
719     }
720     r = ifapi_json_TPM2B_DIGEST_deserialize(jso2, &out->eventData);
721     return_if_error(r, "BAD VALUE");
722 
723     if (!ifapi_get_sub_object(jso, "eventName", &jso2)) {
724         LOG_ERROR("Bad value");
725         return TSS2_FAPI_RC_BAD_VALUE;
726     }
727     r = ifapi_json_char_deserialize(jso2, &out->eventName);
728     return_if_error(r, "BAD VALUE");
729     LOG_TRACE("true");
730     return TSS2_RC_SUCCESS;
731 }
732 
733 /** Deserialize a IFAPI_EVENT_UNION json object.
734  *
735  * This functions expects the Bitfield to be encoded as unsigned int in host-endianess.
736  * @param[in] jso the json object to be deserialized.
737  * @param[in] selector the event type.
738  * @param[out] out the deserialzed binary object.
739  * @retval TSS2_RC_SUCCESS if the function call was a success.
740  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
741  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
742  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
743  */
744 TSS2_RC
ifapi_json_IFAPI_EVENT_UNION_deserialize(UINT32 selector,json_object * jso,IFAPI_EVENT_UNION * out)745 ifapi_json_IFAPI_EVENT_UNION_deserialize(
746     UINT32 selector,
747     json_object *jso,
748     IFAPI_EVENT_UNION *out)
749 {
750     LOG_TRACE("call");
751     switch (selector) {
752     case IFAPI_TSS_EVENT_TAG:
753         return ifapi_json_IFAPI_TSS_EVENT_deserialize(jso, &out->tss_event);
754     case IFAPI_IMA_EVENT_TAG:
755         return ifapi_json_IFAPI_IMA_EVENT_deserialize(jso, &out->ima_event);
756     default:
757         LOG_TRACE("false");
758         return TSS2_FAPI_RC_BAD_VALUE;
759     };
760 }
761 
762 /** Deserialize a IFAPI_EVENT json object.
763  *
764  * @param[in]  jso the json object to be deserialized.
765  * @param[out] out the deserialzed binary object.
766  * @retval TSS2_RC_SUCCESS if the function call was a success.
767  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
768  * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
769  * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
770  */
771 TSS2_RC
ifapi_json_IFAPI_EVENT_deserialize(json_object * jso,IFAPI_EVENT * out)772 ifapi_json_IFAPI_EVENT_deserialize(json_object *jso,  IFAPI_EVENT *out)
773 {
774     json_object *jso2;
775     TSS2_RC r;
776     LOG_TRACE("call");
777     return_if_null(out, "Bad reference.", TSS2_FAPI_RC_BAD_REFERENCE);
778 
779     if (!ifapi_get_sub_object(jso, "recnum", &jso2)) {
780         LOG_ERROR("Bad value");
781         return TSS2_FAPI_RC_BAD_VALUE;
782     }
783     r = ifapi_json_UINT32_deserialize(jso2, &out->recnum);
784     return_if_error(r, "BAD VALUE");
785 
786     if (!ifapi_get_sub_object(jso, "pcr", &jso2)) {
787         LOG_ERROR("Bad value");
788         return TSS2_FAPI_RC_BAD_VALUE;
789     }
790     r = ifapi_json_TPM2_HANDLE_deserialize(jso2, &out->pcr);
791     return_if_error(r, "BAD VALUE");
792 
793     if (!ifapi_get_sub_object(jso, "digests", &jso2)) {
794         LOG_ERROR("Bad value");
795         return TSS2_FAPI_RC_BAD_VALUE;
796     }
797     r = ifapi_json_TPML_DIGEST_VALUES_deserialize(jso2, &out->digests);
798     return_if_error(r, "BAD VALUE");
799 
800     if (!ifapi_get_sub_object(jso, "type", &jso2)) {
801         LOG_ERROR("Bad value");
802         return TSS2_FAPI_RC_BAD_VALUE;
803     }
804     r = ifapi_json_IFAPI_EVENT_TYPE_deserialize(jso2, &out->type);
805     return_if_error(r, "BAD VALUE");
806 
807     if (!ifapi_get_sub_object(jso, "sub_event", &jso2)) {
808         LOG_ERROR("Bad value");
809         return TSS2_FAPI_RC_BAD_VALUE;
810     }
811     r = ifapi_json_IFAPI_EVENT_UNION_deserialize(out->type, jso2, &out->sub_event);
812     return_if_error(r, "BAD VALUE");
813     LOG_TRACE("true");
814     return TSS2_RC_SUCCESS;
815 }
816