diff --git a/Makefile-test.am b/Makefile-test.am index 52cc28bdf..cdd5eefd7 100644 --- a/Makefile-test.am +++ b/Makefile-test.am @@ -383,6 +383,8 @@ FAPI_TESTS_INTEGRATION = \ test/integration/fapi-get-esys-blobs.fint \ test/integration/fapi-get-random.fint \ test/integration/fapi-platform-certificates.fint \ + test/integration/fapi-import-ossl-key-ecc.fint \ + test/integration/fapi-import-ossl-key-rsa.fint \ test/integration/fapi-key-create-sign.fint \ test/integration/fapi-key-create-he-sign.fint \ test/integration/fapi-key-create-primary-sign.fint \ @@ -2445,6 +2447,22 @@ test_integration_fapi_duplicate_fint_SOURCES = \ test/integration/fapi-duplicate.int.c \ test/integration/main-fapi.c test/integration/test-fapi.h +test_integration_fapi_import_ossl_key_ecc_fint_CFLAGS = $(TESTS_CFLAGS) \ + -DFAPI_PROFILE=\"P_ECC\" +test_integration_fapi_import_ossl_key_ecc_fint_LDADD = $(TESTS_LDADD) +test_integration_fapi_import_ossl_key_ecc_fint_LDFLAGS = $(TESTS_LDFLAGS) +test_integration_fapi_import_ossl_key_ecc_fint_SOURCES = \ + test/integration/fapi-import-ossl-key.int.c \ + test/integration/main-fapi.c test/integration/test-fapi.h + +test_integration_fapi_import_ossl_key_rsa_fint_CFLAGS = $(TESTS_CFLAGS) \ + -DFAPI_PROFILE=\"P_RSA\" +test_integration_fapi_import_ossl_key_rsa_fint_LDADD = $(TESTS_LDADD) +test_integration_fapi_import_ossl_key_rsa_fint_LDFLAGS = $(TESTS_LDFLAGS) +test_integration_fapi_import_ossl_key_rsa_fint_SOURCES = \ + test/integration/fapi-import-ossl-key.int.c \ + test/integration/main-fapi.c test/integration/test-fapi.h + test_integration_fapi_pcr_test_fint_CFLAGS = $(TESTS_CFLAGS) test_integration_fapi_pcr_test_fint_LDADD = $(TESTS_LDADD) test_integration_fapi_pcr_test_fint_LDFLAGS = $(TESTS_LDFLAGS) diff --git a/src/tss2-fapi/api/Fapi_Import.c b/src/tss2-fapi/api/Fapi_Import.c index 06ef64f0c..a1425e04f 100644 --- a/src/tss2-fapi/api/Fapi_Import.c +++ b/src/tss2-fapi/api/Fapi_Import.c @@ -19,6 +19,7 @@ #include "fapi_int.h" #include "fapi_util.h" #include "tss2_esys.h" +#include "tss2_mu.h" #include "ifapi_json_deserialize.h" #include "ifapi_policy_json_deserialize.h" #include "tpm_json_deserialize.h" @@ -148,6 +149,7 @@ Fapi_Import_Async( json_object *jso2; size_t pos = 0; TPMS_POLICY policy = { 0 }; + TPMA_OBJECT *attributes; /* Check for NULL parameters */ check_not_null(context); @@ -169,6 +171,9 @@ Fapi_Import_Async( command->jso_string = NULL; strdup_check(command->out_path, path, r, cleanup_error); memset(&command->object, 0, sizeof(IFAPI_OBJECT)); + memset(&command->public_templ, 0, sizeof(IFAPI_KEY_TEMPLATE)); + command->ossl_priv = NULL; + command->profile = NULL; extPubKey->pem_ext_public = NULL; if (strncmp(importData, IFAPI_PEM_PUBLIC_STRING, @@ -202,8 +207,48 @@ Fapi_Import_Async( context->state = IMPORT_KEY_WRITE_OBJECT_PREPARE; - } else if (strcmp(importData, IFAPI_PEM_PRIVATE_KEY) == 0) { - goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "Invalid importData.", cleanup_error); + } else if (strncmp(importData, IFAPI_PEM_PRIVATE_KEY, + sizeof(IFAPI_PEM_PRIVATE_KEY) - 1) == 0 || + strncmp(importData, IFAPI_PEM_ECC_PRIVATE_KEY, + sizeof(IFAPI_PEM_ECC_PRIVATE_KEY) - 1) == 0 || + strncmp(importData, IFAPI_PEM_RSA_PRIVATE_KEY, + sizeof(IFAPI_PEM_RSA_PRIVATE_KEY) - 1) == 0) { + + r = ifapi_non_tpm_mode_init(context); + goto_if_error(r, "Initialize Import in none TPM mode", cleanup_error); + + /* If the async state automata of FAPI shall be tested, then we must not set + the timeouts of ESYS to blocking mode. + During testing, the mssim tcti will ensure multiple re-invocations. + Usually however the synchronous invocations of FAPI shall instruct ESYS + to block until a result is available. */ +#ifndef TEST_FAPI_ASYNC + r = Esys_SetTimeout(context->esys, TSS2_TCTI_TIMEOUT_BLOCK); + goto_if_error_reset_state(r, "Set Timeout to blocking", cleanup_error); +#endif /* TEST_FAPI_ASYNC */ + + r = ifapi_session_init(context); + goto_if_error(r, "Initialize Import", cleanup_error); + + attributes = &context->cmd.ImportKey.public_templ.public.publicArea.objectAttributes; + r = ifapi_profiles_get(&context->profiles, path, &context->cmd.ImportKey.profile); + goto_if_error2(r, "Get profile for path: %s", cleanup_error, path); + + r = ifapi_merge_profile_into_template(context->cmd.ImportKey.profile, + &context->cmd.ImportKey.public_templ); + goto_if_error(r, "Merge profile", cleanup_error); + + *attributes = TPMA_OBJECT_SIGN_ENCRYPT | TPMA_OBJECT_DECRYPT | TPMA_OBJECT_USERWITHAUTH; + context->cmd.ImportKey.ossl_priv = importData; + + /* Create session for key loading. */ + r = ifapi_get_sessions_async(context, + IFAPI_SESSION_GEN_SRK | IFAPI_SESSION1, + TPMA_SESSION_DECRYPT, 0); + goto_if_error_reset_state(r, "Create sessions", cleanup_error); + + context->state = IMPORT_WAIT_FOR_SESSION; + return TSS2_RC_SUCCESS; } else { r = ifapi_non_tpm_mode_init(context); @@ -368,6 +413,8 @@ Fapi_Import_Finish( TSS2_RC r; ESYS_TR session; + size_t marshalled_sensitive_size = 0; + size_t marshalled_length = 0; /* Check for NULL parameters */ check_not_null(context); @@ -393,6 +440,7 @@ Fapi_Import_Finish( char *profile_name = context->loadKey.path_list->str; r = ifapi_profiles_get(&context->profiles, profile_name, &context->cmd.ImportKey.profile); + goto_if_error_reset_state(r, "Retrieving profile data", error_cleanup); if (object->misc.key.public.publicArea.type == TPM2_ALG_RSA) @@ -413,6 +461,39 @@ Fapi_Import_Finish( goto_if_error(r, "LoadKey finish", error_cleanup); context->loadKey.auth_object = *auth_object; + + /* Copy private OSSL PEM key to key tree. */ + if (command->ossl_priv) { + command->parent_object = &context->loadKey.auth_object; + command->public_templ.public.publicArea.nameAlg = + command->parent_object->misc.key.public.publicArea.nameAlg; + r = ifapi_openssl_load_private(command->ossl_priv, + NULL, + NULL, + &context->cmd.ImportKey.public_templ.public, + &keyTree->public, + &command->sensitive); + + goto_if_error_reset_state(r, "Fapi load OSSL Key.", error_cleanup); + + r = Tss2_MU_TPMT_SENSITIVE_Marshal(&command->sensitive.sensitiveArea, + &keyTree->duplicate.buffer[sizeof(uint16_t)], + TPM2_MAX_DIGEST_BUFFER, + &marshalled_sensitive_size); + goto_if_error_reset_state(r, "Fapi marshalling sensitive data of OSSL key failed.", + error_cleanup); + + r = Tss2_MU_UINT16_Marshal(marshalled_sensitive_size, + &keyTree->duplicate.buffer[0], sizeof(uint16_t), + &marshalled_length); + goto_if_error_reset_state(r, "Fapi marshalling size of sensitive date failed.", + error_cleanup); + + keyTree->duplicate.size = marshalled_sensitive_size + sizeof(uint16_t); + context->state = IMPORT_KEY_AUTHORIZE_PARENT; + return TSS2_FAPI_RC_TRY_AGAIN; + } + fallthrough; statecase(context->state, IMPORT_WAIT_FOR_AUTHORIZATION); @@ -550,14 +631,16 @@ Fapi_Import_Finish( r = Esys_Import_Finish(context->esys, &command->private); try_again_or_error_goto(r, "Import", error_cleanup); - /* Concatenate keyname and parent path */ - char* ipath = NULL; - r = ifapi_asprintf(&ipath, "%s%s%s", command->parent_path, - IFAPI_FILE_DELIM, command->out_path); - goto_if_error(r, "Out of memory.", error_cleanup); + if (!command->ossl_priv) { + /* Concatenate keyname and parent path */ + char* ipath = NULL; + r = ifapi_asprintf(&ipath, "%s%s%s", command->parent_path, + IFAPI_FILE_DELIM, command->out_path); + goto_if_error(r, "Out of memory.", error_cleanup); - SAFE_FREE(command->out_path); - command->out_path = ipath; + SAFE_FREE(command->out_path); + command->out_path = ipath; + } context->state = IMPORT_KEY_WAIT_FOR_FLUSH; fallthrough; @@ -580,7 +663,9 @@ Fapi_Import_Finish( newObject->misc.key.policyInstance = NULL; newObject->misc.key.description = NULL; newObject->misc.key.certificate = NULL; - r = ifapi_get_profile_sig_scheme(&context->profiles.default_profile, + r = ifapi_get_profile_sig_scheme(context->cmd.ImportKey.profile ? + context->cmd.ImportKey.profile : + &context->profiles.default_profile, &keyTree->public.publicArea, &newObject->misc.key.signing_scheme); goto_if_error(r, "Get signing scheme.", error_cleanup); diff --git a/src/tss2-fapi/fapi_crypto.c b/src/tss2-fapi/fapi_crypto.c index f603d8629..e5c13ffc3 100644 --- a/src/tss2-fapi/fapi_crypto.c +++ b/src/tss2-fapi/fapi_crypto.c @@ -2201,3 +2201,191 @@ ifapi_rsa_encrypt(const char *pem_key, OSSL_FREE(ctx, EVP_PKEY_CTX); return r; } + +static bool +load_private_RSA_from_key(EVP_PKEY *key, + TPM2B_SENSITIVE *priv) { + + bool result = false; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + const BIGNUM *p = NULL; /* the private key exponent */ + + RSA *k = EVP_PKEY_get0_RSA(key); + if (!k) { + LOG_ERROR("Could not retrieve RSA key"); + goto out; + } + RSA_get0_factors(k, &p, NULL); +#else + BIGNUM *p = NULL; /* the private key exponent */ + + int rc = EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_RSA_FACTOR1, &p); + if (!rc) { + LOG_ERROR("Could not read private key"); + goto out; + } +#endif + + TPMT_SENSITIVE *sa = &priv->sensitiveArea; + + sa->sensitiveType = TPM2_ALG_RSA; + + TPM2B_PRIVATE_KEY_RSA *pkr = &sa->sensitive.rsa; + + unsigned priv_bytes = BN_num_bytes(p); + if (priv_bytes > sizeof(pkr->buffer)) { + LOG_ERROR("Expected prime \"d\" to be less than or equal to %zu," + " got: %u", sizeof(pkr->buffer), priv_bytes); + goto out; + } + + pkr->size = priv_bytes; + + int success = BN_bn2bin(p, pkr->buffer); + if (!success) { + ERR_print_errors_fp(stderr); + LOG_ERROR("Could not copy private exponent \"d\""); + goto out; + } + result = true; +out: +#if OPENSSL_VERSION_NUMBER < 0x30000000L + /* k,p point to internal structrues and must not be freed after use */ +#else + BN_free(p); +#endif + return result; +} + +static TSS2_RC +load_RSA_key(EVP_PKEY *key, + TPM2B_PUBLIC *pub, + TPM2B_SENSITIVE *priv) { + TSS2_RC rc = TSS2_RC_SUCCESS; + + bool loaded_priv = load_private_RSA_from_key(key, priv); + if (!loaded_priv) { + return TSS2_FAPI_RC_GENERAL_FAILURE; + } + + rc = get_rsa_tpm2b_public_from_evp(key, pub); + if (rc) { + goto out; + } +out: + EVP_PKEY_free(key); + return rc; +} + +static bool +load_private_ECC_from_key(EVP_PKEY *key, + TPM2B_SENSITIVE *priv) { + bool result = false; + /* + * private data + */ + priv->sensitiveArea.sensitiveType = TPM2_ALG_ECC; + + TPM2B_ECC_PARAMETER *p = &priv->sensitiveArea.sensitive.ecc; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EC_KEY *k = EVP_PKEY_get0_EC_KEY(key); + if (!k) { + LOG_ERROR("Could not retrieve ECC key"); + goto out; + } + + const EC_GROUP *group = EC_KEY_get0_group(k); + const BIGNUM *b = EC_KEY_get0_private_key(k); + unsigned priv_bytes = (EC_GROUP_get_degree(group) + 7) / 8; +#else + BIGNUM *b = NULL; /* the private key exponent */ + + int rc = EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_PRIV_KEY, &b); + if (!rc) { + LOG_ERROR("Could not read ECC private key"); + goto out; + } + unsigned priv_bytes = (EVP_PKEY_bits(key) + 7) / 8; +#endif + + if (priv_bytes > sizeof(p->buffer)) { + LOG_ERROR("Expected ECC private portion to be less than or equal to %zu," + " got: %u", sizeof(p->buffer), priv_bytes); + goto out; + } + + p->size = BN_bn2binpad(b, p->buffer, priv_bytes); + if (p->size != priv_bytes) { + goto out; + } + result = true; +out: +#if OPENSSL_VERSION_NUMBER < 0x30000000L + /* k,b point to internal structrues and must not be freed after use */ +#else + BN_free(b); +#endif + return result; +} + +static TSS2_RC +load_ECC_key(EVP_PKEY *key, + TPM2B_PUBLIC *pub, + TPM2B_SENSITIVE *priv) { + TSS2_RC rc = TSS2_RC_SUCCESS; + + if (!load_private_ECC_from_key(key, priv)) { + rc = TSS2_FAPI_RC_GENERAL_FAILURE; + goto out; + } + rc = get_ecc_tpm2b_public_from_evp(key, pub); + if (rc) { + goto out; + } +out: + EVP_PKEY_free(key); + return rc; +} + +TSS2_RC +ifapi_openssl_load_private(const char *pem_key, + const char *passin, + const char *object_auth, + TPM2B_PUBLIC *template, + TPM2B_PUBLIC *pub, + TPM2B_SENSITIVE *priv) { + *pub = *template; + BIO *bio = NULL; + EVP_PKEY *key = NULL; + TSS2_RC rc = TSS2_RC_SUCCESS; + (void)object_auth; + + /* Create a key from PEM string. */ + bio = BIO_new_mem_buf(pem_key, -1); + + if (!bio) { + LOG_ERROR("Error creating BIO."); + return TSS2_FAPI_RC_GENERAL_FAILURE; + } + + key = PEM_read_bio_PrivateKey(bio,NULL,NULL, (void *) passin); + + if (!key) { + LOG_ERROR("Creation of key from PEM string failed."); + return TSS2_FAPI_RC_GENERAL_FAILURE; + } + + switch (template->publicArea.type) { + case TPM2_ALG_RSA: + rc = load_RSA_key(key, pub, priv); + break; + case TPM2_ALG_ECC: + rc = load_ECC_key(key, pub, priv); + break; + default: + LOG_ERROR("Cannot handle algorithm, got: 0x%x", template->publicArea.type); + rc = TSS2_FAPI_RC_GENERAL_FAILURE; + } + return rc; +} diff --git a/src/tss2-fapi/fapi_crypto.h b/src/tss2-fapi/fapi_crypto.h index 33b61e128..4360b9cdb 100644 --- a/src/tss2-fapi/fapi_crypto.h +++ b/src/tss2-fapi/fapi_crypto.h @@ -132,4 +132,13 @@ ifapi_rsa_encrypt( uint8_t **cipherText, size_t *cipherTextSize); +TSS2_RC +ifapi_openssl_load_private( + const char *pem_key, + const char *passin, + const char *object_auth, + TPM2B_PUBLIC *template, + TPM2B_PUBLIC *pub, + TPM2B_SENSITIVE *priv); + #endif /* FAPI_CRYPTO_H */ diff --git a/src/tss2-fapi/fapi_int.h b/src/tss2-fapi/fapi_int.h index a9a542420..2833dfc88 100644 --- a/src/tss2-fapi/fapi_int.h +++ b/src/tss2-fapi/fapi_int.h @@ -69,7 +69,9 @@ typedef UINT8 IFAPI_SESSION_TYPE; #define IFAPI_PUB_KEY_DIR "ext" #define IFAPI_POLICY_DIR "policy" #define IFAPI_PEM_PUBLIC_STRING "-----BEGIN PUBLIC KEY-----" -#define IFAPI_PEM_PRIVATE_KEY "-----PRIVATE KEY-----" +#define IFAPI_PEM_PRIVATE_KEY "-----BEGIN PRIVATE KEY-----" +#define IFAPI_PEM_RSA_PRIVATE_KEY "-----BEGIN RSA PRIVATE KEY-----" +#define IFAPI_PEM_ECC_PRIVATE_KEY "-----BEGIN EC PRIVATE KEY-----" #define IFAPI_JSON_TAG_POLICY "policy" #define IFAPI_JSON_TAG_OBJECT_TYPE "objectType" #define IFAPI_JSON_TAG_DUPLICATE "public_parent" @@ -716,6 +718,9 @@ typedef struct { TPM2B_PRIVATE *private; char *jso_string; const IFAPI_PROFILE *profile; + IFAPI_KEY_TEMPLATE public_templ; /**< The template for the keys public data */ + const char *ossl_priv; /**< Private OSSL PEM key to be import. */ + TPM2B_SENSITIVE sensitive; /**< The sensitive part of an OSSL key. */ } IFAPI_ImportKey; diff --git a/test/integration/fapi-import-ossl-key.int.c b/test/integration/fapi-import-ossl-key.int.c new file mode 100644 index 000000000..e52f8f30b --- /dev/null +++ b/test/integration/fapi-import-ossl-key.int.c @@ -0,0 +1,166 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/******************************************************************************* + * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG + * All rights reserved. + *******************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "tss2_fapi.h" + +#include "test-fapi.h" +#define LOGMODULE test +#include "util/log.h" +#include "util/aux_util.h" + +#define SIZE 2000 + +/** Test the FAPI functions for key duplication. + * + * Tested FAPI commands: + * - Fapi_Provision() + * - Fapi_Import() + * - Fapi_Delete() + * + * @param[in,out] context The FAPI_CONTEXT. + * @retval EXIT_FAILURE + * @retval EXIT_SUCCESS + */ + +const char *priv_rsa_pem = + "-----BEGIN RSA PRIVATE KEY-----\n" + "MIIEpAIBAAKCAQEAwBgOktII9d+oYJQLUhQYPk8Ad6dW54ak8XWLdMtNx7161kgQ\n" + "sohndq3WUZ10mR/lf/GVPYNHj5+vR28BQ3In0GZgYGNSiE+6drSq6h+VyaYzDRQG\n" + "b2CUKqNSMhl5FAqhCs6kM8GeXI6FZhnur3gNv4S+hcra9is9mwzucLnt1Maqu5/D\n" + "7HgXJrWmn5JTg8OlZMiYnqD91LD+nx9ZYWxCQzwUBDVaEXQtndvF5neTALOXro1B\n" + "awMMqjlMug0IFA46MOo2mvOWaRWm4JgVS50lj+cye7nobQbw6gkF/kb1VbiEvi/L\n" + "/vbnQCtDlvjx9a97QKuphp2sGtOM/K8c9yuXMwIDAQABAoIBADPYSlamCXUS4Ebw\n" + "rf2BHunyOJYSvAnQ9UOWDgV/uYZnRXgAC0GkPwhw8p8keAu76B0X/seTXwUMfCoz\n" + "c4vYi5Zbizd4lxXjLthK+rYlwC+kg7LL7NCyqEq5ub170onuNHjOPNMbNrqUXLyp\n" + "0xnYtR0znphNn7tBAGeQneoexGngnPnImUh4+wwJReUaDO6Kozu4ETd/1TWa1xLY\n" + "VzMWWLuU+adUmjY+AvEOHXva7P2c4B1d+FS16JHSxGN0i/cPyZBMx3DEAGP3JIN8\n" + "zpMmMlUmG3yuX3w0atWXkvA/lPYajIiRASdzBFri8dLt4euR/I88DUYAT0gelvl7\n" + "IoPnOUECgYEA5lqTe7NNnLJNFqWd96Xu2ga44711oIOuTBLgiuHjTnDwUicBRjMY\n" + "rzPx7Ya3kJds9SLatyswWAvlr3oBidRg/HH/IMejinySGLgbaJOB2srAXMuHD4/k\n" + "pMrHC7CSGglgvXkNFH+4FIny5n1CHcsRA8cHFfUGbW5FYRaNnuJyvgcCgYEA1XsE\n" + "09gbBy0jaTZHdn0Km82+7uTb+9zgtG8TeTskR7zLC3Daq2O896dhPYqVnrZ6MSj1\n" + "9cZGTEzhtT5LaipvDkXU27yvUhcDfZAYYBIAlQ40mpkDxzorHGPEdZ3opxzg1E8D\n" + "UHEs0kdsoVQS7FgugEHTZ2zOZc2VtenOL3of0nUCgYEApnQbEI8PbUSWWeARVwur\n" + "nhavcbnNDtE4mLYnVZRHCb6omeSfkheIJcpWbnojmTMiw7yM6UEnLOhj77os9Gjo\n" + "MGM7pXc9YOwFMiGPhLDaa7yI5kUX8pHa+Y2h6XuNB41xP1kCr6Ze4VCRmiY3KYo8\n" + "YEtofmBRZbACKFcAvSgLG+8CgYEAublk4cjI+t1SSV5nnbX7XMEKs1t35w6qj09z\n" + "aa0CS0b8ft+X3jPPWsXL23aN5J5sgAhas4/j6M2aL8waYCq6o3gtT15ASPKsnriV\n" + "/D6tMwBA0577ooAAsZo6ePkARyLgltSG1Z0gmXB6GYDDVcsB6aNbAEew6PCKptDa\n" + "CIP+22ECgYBWe2OzDxPVj04WDCcyaQIURFtjYjL+Z7FQD9iQX9ux4a+qBdNkEdEs\n" + "CRawbM1vO4VgjLzqg5QSl+OM8CAr7jiSAxqUCCe/25VrxZi+QqDMZ2a0wzz00dSZ\n" + "N1DbUyfqzTzv0jCTEPNbtSjDc/SMuLPWB1G9wvz6LRZxOgeGgaQQGQ==\n" + "-----END RSA PRIVATE KEY-----\n"; + +const char *priv_ecc_pem = + "-----BEGIN EC PRIVATE KEY-----\n" + "MHcCAQEEIJ+3y/OoXGdVUvht0DxYtOhI69dNqe0KqyWFmIleIjMqoAoGCCqGSM49\n" + "AwEHoUQDQgAEKGzvYBs1yaZO5t0unKAtXSl/theSgmdGpkFKc5BAzXp+AeNgmuu1\n" + "wpkzNe7Pl4hneV/W4ddBvJMI5ux2ftaCBQ==\n" + "-----END EC PRIVATE KEY-----\n"; + +const char *pub_rsa_pem = + "-----BEGIN PUBLIC KEY-----\n" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwBgOktII9d+oYJQLUhQY\n" + "Pk8Ad6dW54ak8XWLdMtNx7161kgQsohndq3WUZ10mR/lf/GVPYNHj5+vR28BQ3In\n" + "0GZgYGNSiE+6drSq6h+VyaYzDRQGb2CUKqNSMhl5FAqhCs6kM8GeXI6FZhnur3gN\n" + "v4S+hcra9is9mwzucLnt1Maqu5/D7HgXJrWmn5JTg8OlZMiYnqD91LD+nx9ZYWxC\n" + "QzwUBDVaEXQtndvF5neTALOXro1BawMMqjlMug0IFA46MOo2mvOWaRWm4JgVS50l\n" + "j+cye7nobQbw6gkF/kb1VbiEvi/L/vbnQCtDlvjx9a97QKuphp2sGtOM/K8c9yuX\n" + "MwIDAQAB\n" + "-----END PUBLIC KEY-----\n"; + +const char *pub_ecc_pem = + "-----BEGIN PUBLIC KEY-----\n" + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKGzvYBs1yaZO5t0unKAtXSl/theS\n" + "gmdGpkFKc5BAzXp+AeNgmuu1wpkzNe7Pl4hneV/W4ddBvJMI5ux2ftaCBQ==\n" + "-----END PUBLIC KEY-----\n"; + +int +test_fapi_import_ossl(FAPI_CONTEXT *context) +{ + TSS2_RC r; + const char *priv_pem; + char *json_string_pubkey = NULL; + json_object *jso = NULL; + json_object *jso_public = NULL; + char *pubkey_pem = NULL; + const char *pubkey_test = NULL; + + + if (strncmp(FAPI_PROFILE, "P_RSA", 5) == 0) { + priv_pem = priv_rsa_pem; + pubkey_test = pub_rsa_pem; + } else { + priv_pem = priv_ecc_pem; + pubkey_test =pub_ecc_pem; + } + + r = Fapi_Provision(context, NULL, NULL, NULL); + goto_if_error(r, "Error Fapi_Provision", error); + + r = Fapi_Import(context, "/SRK/my_osslkey", priv_pem); + goto_if_error(r, "Error Fapi_Import", error); + + r = Fapi_ExportKey(context, "/SRK/my_osslkey", NULL, &json_string_pubkey); + goto_if_error(r, "Error Fapi_CreateKey", error); + ASSERT(json_string_pubkey != NULL); + ASSERT(strlen(json_string_pubkey) > ASSERT_SIZE); + + jso = json_tokener_parse(json_string_pubkey); + LOG_INFO("\nExported: %s\n", json_string_pubkey); + + if (!jso || !json_object_object_get_ex(jso, "pem_ext_public", &jso_public)) { + LOG_ERROR("No public key eyported."); + goto error; + } + pubkey_pem = strdup(json_object_get_string(jso_public)); + if (!pubkey_pem) { + LOG_ERROR("Out of memory."); + goto error; + } + + if (strcmp(pubkey_pem, pubkey_test) != 0) { + LOG_ERROR("Pub keys not equal."); + LOG_ERROR("%s", pubkey_test); + LOG_ERROR("%s", pubkey_pem); + goto error; + } + + r = Fapi_Delete(context, "/"); + goto_if_error(r, "Error Fapi_Delete", error2); + + SAFE_FREE(json_string_pubkey); + json_object_put(jso); + SAFE_FREE(pubkey_pem); + return EXIT_SUCCESS; + +error: + Fapi_Delete(context, "/"); + error2: + if (jso) + json_object_put(jso); + SAFE_FREE(pubkey_pem); + SAFE_FREE(json_string_pubkey); + return EXIT_FAILURE; +} + +int +test_invoke_fapi(FAPI_CONTEXT *fapi_context) +{ + return test_fapi_import_ossl(fapi_context); +}