Showing with 96 additions and 57 deletions.
  1. +10 −6 lib/tpm2_util.c
  2. +8 −0 lib/tpm2_util.h
  3. +22 −2 test/system/tests/listpersistent.sh
  4. +3 −2 tools/tpm2_createprimary.c
  5. +1 −2 tools/tpm2_import.c
  6. +52 −45 tools/tpm2_listpersistent.c
16 changes: 10 additions & 6 deletions lib/tpm2_util.c
Expand Up @@ -352,16 +352,22 @@ void print_yaml_indent(size_t indent_count) {
}
}

void tpm2_util_tpma_object_to_yaml(TPMA_OBJECT obj) {

char *attrs = tpm2_attr_util_obj_attrtostr(obj);
tpm2_tool_output("attributes:\n");
tpm2_tool_output(" value: %s\n", attrs);
tpm2_tool_output(" raw: 0x%x\n", obj);
free(attrs);
}

void tpm2_util_public_to_yaml(TPM2B_PUBLIC *public) {

tpm2_tool_output("algorithm:\n");
tpm2_tool_output(" value: %s\n", tpm2_alg_util_algtostr(public->publicArea.nameAlg));
tpm2_tool_output(" raw: 0x%x\n", public->publicArea.nameAlg);

char *attrs = tpm2_attr_util_obj_attrtostr(public->publicArea.objectAttributes);
tpm2_tool_output("attributes:\n");
tpm2_tool_output(" value: %s\n", attrs);
tpm2_tool_output(" raw: 0x%x\n", public->publicArea.objectAttributes);
tpm2_util_tpma_object_to_yaml(public->publicArea.objectAttributes);

tpm2_tool_output("type: \n");
tpm2_tool_output(" value: %s\n", tpm2_alg_util_algtostr(public->publicArea.type));
Expand All @@ -384,6 +390,4 @@ void tpm2_util_public_to_yaml(TPM2B_PUBLIC *public) {
public->publicArea.authPolicy.size, true);
tpm2_tool_output("\n");
}

free(attrs);
}
8 changes: 8 additions & 0 deletions lib/tpm2_util.h
Expand Up @@ -294,4 +294,12 @@ void print_yaml_indent(size_t indent_count);
*/
void tpm2_util_public_to_yaml(TPM2B_PUBLIC *public);


/**
* Convert a TPMA_OBJECT to a yaml format and output if not quiet.
* @param obj
* The TPMA_OBJECT attributes to print.
*/
void tpm2_util_tpma_object_to_yaml(TPMA_OBJECT obj);

#endif /* STRING_BYTES_H */
24 changes: 22 additions & 2 deletions test/system/tests/listpersistent.sh
Expand Up @@ -44,7 +44,7 @@ cleanup() {
tpm2_evictcontrol -Q -A "$auth" -H "$handle" -p "$handle"
done

rm -f primary.context
rm -f primary.context out.yaml
}

trap cleanup EXIT
Expand All @@ -55,6 +55,24 @@ onerror() {
}
trap onerror ERR


function yaml_get() {

python << pyscript
from __future__ import print_function
import sys
import yaml
with open("$1") as f:
try:
y = yaml.load(f)
print(len(y))
except yaml.YAMLError as exc:
sys.exit(exc)
pyscript
}

tpm2_clear

# Test persisting transient objects
Expand All @@ -65,7 +83,9 @@ do
tpm2_evictcontrol -Q -A "$auth" -p "$handle" -c primary.context
done

handle_cnt=$(tpm2_listpersistent | wc -l)
tpm2_listpersistent > out.yaml

handle_cnt=$(yaml_get out.yaml)

if [ "$handle_cnt" -ne "${#keys[@]}" ]; then
echo "Only $handle_cnt of ${#keys[@]} persistent objects were listed"
Expand Down
5 changes: 3 additions & 2 deletions tools/tpm2_createprimary.c
Expand Up @@ -172,7 +172,8 @@ int create_primary(TSS2_SYS_CONTEXT *sapi_context) {

if(setup_alg())
return -1;
tpm2_tool_output("ObjectAttribute: 0x%08X\n", ctx.in_public.publicArea.objectAttributes);

tpm2_util_tpma_object_to_yaml(ctx.in_public.publicArea.objectAttributes);

creationPCR.count = 0;

Expand All @@ -185,7 +186,7 @@ int create_primary(TSS2_SYS_CONTEXT *sapi_context) {
return -2;
}

tpm2_tool_output("\nCreatePrimary Succeed ! Handle: 0x%8.8x\n\n", ctx.handle2048rsa);
tpm2_tool_output("handle: 0x%X", ctx.handle2048rsa);

return 0;
}
Expand Down
3 changes: 1 addition & 2 deletions tools/tpm2_import.c
Expand Up @@ -298,8 +298,7 @@ static bool create_import_key_public_data_and_name(void) {
ctx.import_key_public.publicArea.objectAttributes = ctx.objectAttributes;
}

tpm2_tool_output("ObjectAttribute: 0x%08X\n",
ctx.import_key_public.publicArea.objectAttributes);
tpm2_util_tpma_object_to_yaml(ctx.import_key_public.publicArea.objectAttributes);

memcpy(ctx.import_key_public.publicArea.unique.sym.buffer,
ctx.import_key_public_unique_data, TPM2_SHA256_DIGEST_SIZE);
Expand Down
97 changes: 52 additions & 45 deletions tools/tpm2_listpersistent.c
Expand Up @@ -51,7 +51,6 @@ typedef struct tpm_listpersistent_context tpm_listpersistent_context;
struct tpm_listpersistent_context {
TPMI_ALG_HASH nameAlg;
TPMI_ALG_PUBLIC type;
UINT32 count;
};

static tpm_listpersistent_context ctx = {
Expand Down Expand Up @@ -82,50 +81,24 @@ static bool on_option(char key, char *value) {
return true;
}

int readPublic(TSS2_SYS_CONTEXT *sapi_context, TPMI_DH_OBJECT objectHandle) {
static int read_public(TSS2_SYS_CONTEXT *sapi_context,
TPMI_DH_OBJECT objectHandle, TPM2B_PUBLIC *outPublic) {

UINT32 rval;
TSS2L_SYS_AUTH_RESPONSE sessionsDataOut;

TPM2B_PUBLIC outPublic = TPM2B_EMPTY_INIT;
TPM2B_NAME name = TPM2B_TYPE_INIT(TPM2B_NAME, name);
TPM2B_NAME qualifiedName = TPM2B_TYPE_INIT(TPM2B_NAME, name);

rval = TSS2_RETRY_EXP(Tss2_Sys_ReadPublic(sapi_context, objectHandle, 0, &outPublic, &name, &qualifiedName, &sessionsDataOut));
if(rval != TPM2_RC_SUCCESS)
{
LOG_ERR("\nTPM2_ReadPublic error: rval = 0x%0x\n",rval);
rval = TSS2_RETRY_EXP(
Tss2_Sys_ReadPublic(sapi_context, objectHandle, NULL, outPublic,
&name, &qualifiedName, &sessionsDataOut)
);
if (rval != TPM2_RC_SUCCESS) {
LOG_ERR("TPM2_ReadPublic error: rval = 0x%X", rval);
return -1;
}

TPMI_ALG_PUBLIC type = outPublic.publicArea.type;
TPMI_ALG_HASH nameAlg = outPublic.publicArea.nameAlg;
char *attrs = tpm2_attr_util_obj_attrtostr(
outPublic.publicArea.objectAttributes);
char *attrbuf = attrs;

/*
* tmp must be declared at this scope for possible use in tpm2_tool_output when attrs
* is null.
*/
char tmp[11]; /* UINT32 in hex (8) + "0x" + '\0' */
if (!attrs) {
LOG_WARN("Could not convert objectAttributes, converting to hex output");
snprintf(tmp, sizeof(tmp), "0x%x", outPublic.publicArea.objectAttributes);
attrbuf = tmp;
}

if ((ctx.type != TPM2_ALG_NULL && ctx.type != type) ||
(ctx.nameAlg != TPM2_ALG_NULL && ctx.nameAlg != nameAlg)) {
goto out;
}

tpm2_tool_output("persistent-handle[%d]:0x%x key-alg:%s hash-alg:%s object-attr:%s\n",
ctx.count++, objectHandle, tpm2_alg_util_algtostr(type),
tpm2_alg_util_algtostr(nameAlg), attrbuf);

out:
free(attrs);

return 0;
}

Expand All @@ -151,20 +124,54 @@ int tpm2_tool_onrun(TSS2_SYS_CONTEXT *sapi_context, tpm2_option_flags flags) {
UINT32 rval;

UINT32 property = tpm2_util_endian_swap_32(TPM2_HT_PERSISTENT);
rval = TSS2_RETRY_EXP(Tss2_Sys_GetCapability(sapi_context, 0, TPM2_CAP_HANDLES,
property, TPM2_PT_TPM2_HR_PERSISTENT, &moreData,
&capabilityData, 0));
if(rval != TPM2_RC_SUCCESS)
{
LOG_ERR("\n......GetCapability: Get persistent object list Error."
" TPM Error:0x%x......", rval);
rval = TSS2_RETRY_EXP(
Tss2_Sys_GetCapability(sapi_context, NULL, TPM2_CAP_HANDLES,
property, TPM2_PT_TPM2_HR_PERSISTENT, &moreData,
&capabilityData, NULL));
if (rval != TPM2_RC_SUCCESS) {
LOG_ERR("GetCapability: Get persistent object list Error."
" TPM Error:0x%x......", rval);
return 1;
}

UINT32 i;
for(i = 0; i < capabilityData.data.handles.count; i++) {
if(readPublic(sapi_context, capabilityData.data.handles.handle[i]))
for (i = 0; i < capabilityData.data.handles.count; i++) {
TPM2B_PUBLIC outPublic = TPM2B_EMPTY_INIT;
TPM2_HANDLE objectHandle = capabilityData.data.handles.handle[i];
if (read_public(sapi_context, objectHandle, &outPublic)) {
return 2;
}

TPMI_ALG_PUBLIC type = outPublic.publicArea.type;
TPMI_ALG_HASH nameAlg = outPublic.publicArea.nameAlg;
if ((ctx.type != TPM2_ALG_NULL && ctx.type != type)
|| (ctx.nameAlg != TPM2_ALG_NULL && ctx.nameAlg != nameAlg)) {
/* Skip, filter me out */
continue;
}

char *attrs = tpm2_attr_util_obj_attrtostr(
outPublic.publicArea.objectAttributes);
char *attrbuf = attrs;

/*
* tmp must be declared at this scope for possible use in tpm2_tool_output when attrs
* is null.
*/
char tmp[11]; /* UINT32 in hex (8) + "0x" + '\0' */
if (!attrs) {
LOG_WARN(
"Could not convert objectAttributes, converting to hex output");
snprintf(tmp, sizeof(tmp), "0x%X",
outPublic.publicArea.objectAttributes);
attrbuf = tmp;
}

tpm2_tool_output(
"- { persistent-handle: 0x%X, key-alg: %s, hash-alg: %s, object-attr: %s }\n",
objectHandle, tpm2_alg_util_algtostr(type),
tpm2_alg_util_algtostr(nameAlg), attrbuf);
free(attrs);
}

return 0;
Expand Down