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