Blob Blame History Raw
From 517e94ee72b286e9942a5a6ecbffd05fc0b0bcf5 Mon Sep 17 00:00:00 2001
From: Juergen Repp <juergen.repp@sit.fraunhofer.de>
Date: Fri, 5 Nov 2021 23:08:47 +0100
Subject: [PATCH 07/23] FAPI: Fix loading of primary keys.

Problems caused by primary keys created with Fapi_CreateKey are fixed:

* For primary keys not in all cases the unique field was cleared before calling create
  primary.
* If the primary key was used for signing the object was cleared after loading. So
  access e.g. to the certificate did not work.
* For primary keys created with Fapi_Create with an auth value the auth_value was
  not used in inSensitive to recreate the primary key. Now the auth value callback
  is used to initialize inSensitive.

Fixes #2189.

Signed-off-by: Juergen Repp <juergen.repp@sit.fraunhofer.de>
---
 src/tss2-fapi/fapi_int.h  |  1 +
 src/tss2-fapi/fapi_util.c | 62 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/src/tss2-fapi/fapi_int.h b/src/tss2-fapi/fapi_int.h
index d13ec413..7bcf442c 100644
--- a/src/tss2-fapi/fapi_int.h
+++ b/src/tss2-fapi/fapi_int.h
@@ -768,6 +768,7 @@ enum _FAPI_STATE_PRIMARY {
     PRIMARY_READ_HIERARCHY,
     PRIMARY_READ_HIERARCHY_FINISH,
     PRIMARY_AUTHORIZE_HIERARCHY,
+    PRIMARY_GET_AUTH_VALUE,
     PRIMARY_WAIT_FOR_PRIMARY,
     PRIMARY_HAUTH_SENT,
     PRIMARY_CREATED,
diff --git a/src/tss2-fapi/fapi_util.c b/src/tss2-fapi/fapi_util.c
index a0fd714e..90f8b2aa 100644
--- a/src/tss2-fapi/fapi_util.c
+++ b/src/tss2-fapi/fapi_util.c
@@ -362,6 +362,52 @@ ifapi_get_object_path(IFAPI_OBJECT *object)
     return NULL;
 }
 
+/** Set authorization value for a primary key to be created.
+ *
+ * The callback which provides the auth value must be defined.
+ *
+ * @param[in,out] context The FAPI_CONTEXT.
+ * @param[in]     object The auth value will be assigned to this object.
+ * @param[in,out] inSensitive The sensitive data to store the auth value.
+ *
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN If the callback for getting
+ *         the auth value is not defined.
+ */
+TSS2_RC
+ifapi_set_auth_primary(
+    FAPI_CONTEXT *context,
+    IFAPI_OBJECT *object,
+    TPMS_SENSITIVE_CREATE *inSensitive)
+{
+    TSS2_RC r;
+    const char *auth = NULL;
+    const char *obj_path;
+
+    memset(inSensitive, 0, sizeof(TPMS_SENSITIVE_CREATE));
+
+    if (!object->misc.key.with_auth) {
+        return TSS2_RC_SUCCESS;
+    }
+
+    obj_path = ifapi_get_object_path(object);
+
+    /* Check whether callback is defined. */
+    if (context->callbacks.auth) {
+        r = context->callbacks.auth(obj_path, object->misc.key.description,
+                                    &auth, context->callbacks.authData);
+        return_if_error(r, "AuthCallback");
+        if (auth != NULL) {
+            inSensitive->userAuth.size = strlen(auth);
+            memcpy(&inSensitive->userAuth.buffer[0], auth,
+                   inSensitive->userAuth.size);
+        }
+        return TSS2_RC_SUCCESS;
+    }
+    SAFE_FREE(auth);
+    return_error( TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN, "Authorization callback not defined.");
+}
+
 /** Set authorization value for a FAPI object.
  *
  * The callback which provides the auth value must be defined.
@@ -848,7 +894,7 @@ ifapi_load_primary_finish(FAPI_CONTEXT *context, ESYS_TR *handle)
     IFAPI_KEY *pkey = &context->createPrimary.pkey_object.misc.key;
     TPMS_CAPABILITY_DATA **capabilityData = &context->createPrimary.capabilityData;
     TPMI_YES_NO moreData;
-    ESYS_TR auth_session;
+    ESYS_TR auth_session = ESYS_TR_NONE; /* Initialized due to scanbuild */
 
     LOG_TRACE("call");
 
@@ -923,12 +969,23 @@ ifapi_load_primary_finish(FAPI_CONTEXT *context, ESYS_TR *handle)
         memset(&context->createPrimary.inSensitive, 0, sizeof(TPM2B_SENSITIVE_CREATE));
         memset(&context->createPrimary.outsideInfo, 0, sizeof(TPM2B_DATA));
         memset(&context->createPrimary.creationPCR, 0, sizeof(TPML_PCR_SELECTION));
+        fallthrough;
+
+    statecase(context->primary_state, PRIMARY_GET_AUTH_VALUE);
+        /* Get the auth value to be stored in inSensitive */
+        r = ifapi_set_auth_primary(context, pkey_object,
+                                   &context->createPrimary.inSensitive.sensitive);
+        return_try_again(r);
+        goto_if_error_reset_state(r, "Get auth value for primary", error_cleanup);
 
         /* Prepare primary creation. */
+        TPM2B_PUBLIC public = pkey->public;
+        memset(&public.publicArea.unique, 0, sizeof(TPMU_PUBLIC_ID));
+
         r = Esys_CreatePrimary_Async(context->esys, hierarchy->handle,
                                      auth_session, ESYS_TR_NONE, ESYS_TR_NONE,
                                      &context->createPrimary.inSensitive,
-                                     &pkey->public,
+                                     &public,
                                      &context->createPrimary.outsideInfo,
                                      &context->createPrimary.creationPCR);
         return_if_error(r, "CreatePrimary");
@@ -1905,7 +1962,6 @@ ifapi_load_key_finish(FAPI_CONTEXT *context, bool flush_parent)
         } else {
             LOG_TRACE("success");
             ifapi_cleanup_ifapi_object(context->loadKey.key_object);
-            ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
             return TSS2_RC_SUCCESS;
         }
         break;
-- 
2.34.3