123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- /* SPDX-License-Identifier: BSD-2-Clause */
- /*******************************************************************************
- * Copyright 2017, Fraunhofer SIT sponsored by Infineon Technologies AG
- * All rights reserved.
- *******************************************************************************/
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <stdio.h>
- #include <stdbool.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <json-c/json_util.h>
- #include <json-c/json_tokener.h>
- #include "tss2_esys.h"
- #include "tss2_fapi.h"
- #include "test-fapi.h"
- #define LOGDEFAULT LOGLEVEL_INFO
- #define LOGMODULE test
- #include "util/log.h"
- #include "util/aux_util.h"
- #ifndef FAPI_PROFILE
- #define FAPI_PROFILE "P_ECC"
- #endif /* FAPI_PROFILE */
- char *fapi_profile = NULL;
- char *tmpdir = NULL;
- char *config = NULL;
- char *config_path = NULL;
- char *config_env = NULL;
- char *remove_cmd = NULL;
- char *system_dir = NULL;
- FAPI_CONTEXT *global_fapi_context = NULL;
- bool file_exists (char *path) {
- struct stat buffer;
- return (stat (path, &buffer) == 0);
- }
- /* Determine integer number from json object. */
- static int64_t
- get_number(json_object *jso) {
- const char* token;
- int itoken = 0;
- int pos = 0;
- int64_t num;
- token = json_object_get_string(jso);
- if (strncmp(token, "0x", 2) == 0) {
- itoken = 2;
- sscanf(&token[itoken], "%"PRIx64"%n", &num, &pos);
- } else {
- sscanf(&token[itoken], "%"PRId64"%n", &num, &pos);
- }
- return num;
- }
- /* Determin number of fields in a json objecd. */
- size_t nmb_of_fields(json_object *jso) {
- size_t n = 0;
- json_object_object_foreach(jso, key, val) {
- UNUSED(val);
- UNUSED(key);
- n++;
- }
- return n;
- }
- /* Compare two json objects.
- *
- * Only strings, integers, array and json objects are supported.
- */
- bool cmp_jso(json_object *jso1, json_object *jso2) {
- enum json_type type1, type2;
- size_t i, size;
- type1 = json_object_get_type(jso1);
- type2 = json_object_get_type(jso2);
- if (type1 != type2) {
- return false;
- }
- if (type1 == json_type_object) {
- if (nmb_of_fields(jso1) != nmb_of_fields(jso2)) {
- return false;
- }
- json_object_object_foreach(jso1, key1, jso_sub1) {
- json_object *jso_sub2;
- if (!json_object_object_get_ex(jso2, key1, &jso_sub2)) {
- return false;
- }
- if (!cmp_jso(jso_sub1, jso_sub2)) {
- return false;
- }
- }
- return true;
- } else if (type1 == json_type_int) {
- return (get_number(jso1) == get_number(jso2));
- } else if (type1 == json_type_array) {
- size = json_object_array_length(jso1);
- /* Cast to size_t due to change in json-c API.
- older versions use result type int */
- if (size != (size_t)json_object_array_length(jso2)) {
- return false;
- }
- for (i = 0; i < size; i++) {
- if (!cmp_jso(json_object_array_get_idx(jso1, i),
- json_object_array_get_idx(jso2, i))) {
- return false;
- }
- }
- return true;
- } else if (type1 == json_type_string) {
- return (strcmp(json_object_get_string(jso1),
- json_object_get_string(jso2)) == 0);
- } else {
- return false;
- }
- }
- /* Compare two delimter sparated token lists. */
- bool cmp_strtokens(char* string1, char *string2, char *delimiter) {
- bool found = false;
- char *token1 = NULL;
- char *token2 = NULL;
- char *end_token1;
- char *end_token2;
- char *string2_copy;
- string1 = strdup(string1);
- ASSERT(string1);
- token1 = strtok_r(string1, delimiter, &end_token1);
- while(token1 != NULL) {
- found = false;
- string2_copy = strdup(string2);
- ASSERT(string2_copy);
- token2 = strtok_r(string2_copy, delimiter, &end_token2);
- while (token2 != NULL) {
- if (strcmp(token1, token2) == 0) {
- found = true;
- break;
- }
- token2 = strtok_r(NULL, delimiter, &end_token2);
- }
- free(string2_copy);
- if (!found) {
- break;
- }
- token1 = strtok_r(NULL, delimiter, &end_token1);
- }
- free(string1);
- return found;
- error:
- SAFE_FREE(string1);
- return false;
- }
- TSS2_RC
- pcr_reset(FAPI_CONTEXT *context, UINT32 pcr)
- {
- TSS2_RC r;
- TSS2_TCTI_CONTEXT *tcti;
- ESYS_CONTEXT *esys;
- r = Fapi_GetTcti(context, &tcti);
- goto_if_error(r, "Error Fapi_GetTcti", error);
- r = Esys_Initialize(&esys, tcti, NULL);
- goto_if_error(r, "Error Fapi_GetTcti", error);
- r = Esys_PCR_Reset(esys, pcr,
- ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE);
- Esys_Finalize(&esys);
- goto_if_error(r, "Error Eys_PCR_Reset", error);
- error:
- return r;
- }
- int init_fapi(char *profile, FAPI_CONTEXT **fapi_context)
- {
- TSS2_RC rc;
- int ret, size;
- SAFE_FREE(config);
- SAFE_FREE(config_path);
- SAFE_FREE(config_env);
- SAFE_FREE(remove_cmd);
- SAFE_FREE(system_dir);
- FILE *config_file;
- fapi_profile = profile;
- /* First we construct a fapi config file */
- #if defined(FAPI_NONTPM)
- size = asprintf(&config, "{\n"
- " \"profile_name\": \"%s\",\n"
- " \"profile_dir\": \"" TOP_SOURCEDIR "/test/data/fapi/\",\n"
- " \"user_dir\": \"%s/user/dir\",\n"
- " \"system_dir\": \"%s/system_dir\",\n"
- " \"system_pcrs\" : [],\n"
- " \"log_dir\" : \"%s\",\n"
- " \"tcti\": \"none\",\n"
- "}\n",
- profile, tmpdir, tmpdir, tmpdir);
- #elif defined(FAPI_TEST_FINGERPRINT)
- size = asprintf(&config, "{\n"
- " \"profile_name\": \"%s\",\n"
- " \"profile_dir\": \"" TOP_SOURCEDIR "/test/data/fapi/\",\n"
- " \"user_dir\": \"%s/user/dir\",\n"
- " \"system_dir\": \"%s/system_dir\",\n"
- " \"system_pcrs\" : [],\n"
- " \"log_dir\" : \"%s\",\n"
- " \"tcti\": \"%s\",\n"
- #if defined(FAPI_TEST_EK_CERT_LESS)
- " \"ek_cert_less\": \"yes\",\n"
- #else
- " \"ek_fingerprint\": %s,\n"
- #endif
- "}\n",
- profile, tmpdir, tmpdir, tmpdir,
- getenv("TPM20TEST_TCTI")
- #if !defined(FAPI_TEST_EK_CERT_LESS)
- , getenv("FAPI_TEST_FINGERPRINT")
- #endif
- );
- #elif defined(FAPI_TEST_CERTIFICATE)
- size = asprintf(&config, "{\n"
- " \"profile_name\": \"%s\",\n"
- " \"profile_dir\": \"" TOP_SOURCEDIR "/test/data/fapi/\",\n"
- " \"user_dir\": \"%s/user/dir\",\n"
- " \"system_dir\": \"%s/system_dir\",\n"
- " \"system_pcrs\" : [],\n"
- " \"log_dir\" : \"%s\",\n"
- " \"tcti\": \"%s\",\n"
- #if defined(FAPI_TEST_EK_CERT_LESS)
- " \"ek_cert_less\": \"yes\",\n"
- #else
- " \"ek_cert_file\": \"%s\",\n"
- #endif
- "}\n",
- profile, tmpdir, tmpdir, tmpdir,
- getenv("TPM20TEST_TCTI")
- #if !defined(FAPI_TEST_EK_CERT_LESS)
- , getenv("FAPI_TEST_CERTIFICATE")
- #endif
- );
- #elif defined(FAPI_TEST_FINGERPRINT_ECC)
- size = asprintf(&config, "{\n"
- " \"profile_name\": \"%s\",\n"
- " \"profile_dir\": \"" TOP_SOURCEDIR "/test/data/fapi/\",\n"
- " \"user_dir\": \"%s/user/dir\",\n"
- " \"system_dir\": \"%s/system_dir\",\n"
- " \"system_pcrs\" : [],\n"
- " \"log_dir\" : \"%s\",\n"
- " \"tcti\": \"%s\",\n"
- #if defined(FAPI_TEST_EK_CERT_LESS)
- " \"ek_cert_less\": \"yes\",\n"
- #else
- " \"ek_fingerprint\": %s,\n"
- #endif
- "}\n",
- profile, tmpdir, tmpdir, tmpdir,
- getenv("TPM20TEST_TCTI")
- #if !defined(FAPI_TEST_EK_CERT_LESS)
- , getenv("FAPI_TEST_FINGERPRINT_ECC")
- #endif
- );
- #elif defined(FAPI_TEST_CERTIFICATE_ECC)
- size = asprintf(&config, "{\n"
- " \"profile_name\": \"%s\",\n"
- " \"profile_dir\": \"" TOP_SOURCEDIR "/test/data/fapi/\",\n"
- " \"user_dir\": \"%s/user/dir\",\n"
- " \"system_dir\": \"%s/system_dir\",\n"
- " \"system_pcrs\" : [],\n"
- " \"log_dir\" : \"%s\",\n"
- " \"tcti\": \"%s\",\n"
- #if defined(FAPI_TEST_EK_CERT_LESS)
- " \"ek_cert_less\": \"yes\",\n"
- #else
- " \"ek_cert_file\": \"%s\",\n"
- #endif
- "}\n",
- profile, tmpdir, tmpdir, tmpdir,
- getenv("TPM20TEST_TCTI")
- #if defined(FAPI_TEST_EK_CERT_LESS)
- #else
- , getenv("FAPI_TEST_CERTIFICATE_ECC")
- #endif
- );
- #else /* FAPI_NONTPM */
- size = asprintf(&config, "{\n"
- " \"profile_name\": \"%s\",\n"
- " \"profile_dir\": \"" TOP_SOURCEDIR "/test/data/fapi/\",\n"
- " \"user_dir\": \"%s/user/dir\",\n"
- " \"system_dir\": \"%s/system_dir\",\n"
- " \"system_pcrs\" : [],\n"
- " \"log_dir\" : \"%s\",\n"
- " \"tcti\": \"%s\",\n"
- #if defined(FAPI_TEST_EK_CERT_LESS)
- " \"ek_cert_less\": \"yes\",\n"
- #endif
- "}\n",
- profile, tmpdir, tmpdir, tmpdir,
- getenv("TPM20TEST_TCTI"));
- #endif /* FAPI_NONTPM */
- if (size < 0) {
- LOG_ERROR("Out of memory");
- ret = EXIT_ERROR;
- goto error;
- }
- size = asprintf(&system_dir, "%s/system_dir/", tmpdir);
- if (size < 0) {
- LOG_ERROR("Out of memory");
- ret = EXIT_ERROR;
- goto error;
- }
- if (!file_exists(system_dir)) {
- int rc_mkdir = mkdir(system_dir, 0777);
- if (rc_mkdir != 0) {
- LOG_ERROR("mkdir not possible: %i %s", rc_mkdir, system_dir);
- ret = EXIT_ERROR;
- goto error;
- }
- }
- if (size < 0) {
- LOG_ERROR("Out of memory");
- ret = EXIT_ERROR;
- goto error;
- }
- LOG_INFO("Using config:\n%s", config);
- /* We construct the path for the config file */
- size = asprintf(&config_path, "%s/fapi-config.json", tmpdir);
- if (size < 0) {
- LOG_ERROR("Out of memory");
- ret = EXIT_ERROR;
- goto error;
- }
- /* We write the config file to disk */
- config_file = fopen(config_path, "w");
- if (!config_file) {
- LOG_ERROR("Opening config file for writing");
- perror(config_path);
- ret = EXIT_ERROR;
- goto error;
- }
- size = fprintf(config_file, "%s", config);
- fclose(config_file);
- if (size < 0) {
- LOG_ERROR("Writing config file");
- perror(config_path);
- ret = EXIT_ERROR;
- goto error;
- }
- /* We set the environment variable for FAPI to consume the config file */
- size = asprintf(&config_env, "TSS2_FAPICONF=%s", config_path);
- if (size < 0) {
- LOG_ERROR("Out of memory");
- ret = EXIT_ERROR;
- goto error;
- }
- putenv(config_env);
- /***********
- * Call FAPI
- ***********/
- rc = Fapi_Initialize(fapi_context, NULL);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR("Esys_Initialize FAILED! Response Code : 0x%x", rc);
- ret = EXIT_FAILURE;
- goto error;
- }
- global_fapi_context = *fapi_context;
- return 0;
- error:
- Fapi_Finalize(fapi_context);
- if (system_dir) free(system_dir);
- if (config) free(config);
- if (config_path) free(config_path);
- if (config_env) free(config_env);
- if (remove_cmd) free(remove_cmd);
- return ret;
- }
- /**
- * This program is a template for integration tests (ones that use the TCTI,
- * the ESAPI, and FAPI contexts / API directly). It does nothing more than
- * parsing command line options that allow the caller (likely a script)
- * to specifywhich TCTI to use for the test using getenv("TPM20TEST_TCTI").
- */
- int
- main(int argc, char *argv[])
- {
- int ret, size;
- char *config = NULL;
- char *config_path = NULL;
- char *config_env = NULL;
- char *remove_cmd = NULL;
- char *system_dir = NULL;
- char template[] = "/tmp/fapi_tmpdir.XXXXXX";
- tmpdir = mkdtemp(template);
- if (!tmpdir) {
- LOG_ERROR("No temp dir created");
- return EXIT_ERROR;
- }
- ret = init_fapi(FAPI_PROFILE, &global_fapi_context);
- if (ret)
- goto error;
- ret = test_invoke_fapi(global_fapi_context);
- LOG_INFO("Test returned %i", ret);
- if (ret) goto error;
- size = asprintf(&remove_cmd, "rm -r -f %s", tmpdir);
- if (size < 0) {
- LOG_ERROR("Out of memory");
- ret = EXIT_ERROR;
- goto error;
- }
- if (system(remove_cmd) != 0) {
- LOG_ERROR("Directory %s can't be deleted.", tmpdir);
- ret = EXIT_ERROR;
- goto error;
- }
- error:
- Fapi_Finalize(&global_fapi_context);
- if (system_dir) free(system_dir);
- if (config) free(config);
- if (config_path) free(config_path);
- if (config_env) free(config_env);
- if (remove_cmd) free(remove_cmd);
- return ret;
- }
|