tpm2-util: copy serialized result in tpm2_serialize()
For safety, though typically Esys_Free() is just a simple wrapper of free(), but let's do unconditionally. See the comment in the code. While at it, this makes it store the result into struct iovec.
This commit is contained in:
@@ -4794,13 +4794,13 @@ static int make_policy(bool force, RecoveryPinMode recovery_pin_mode) {
|
||||
}
|
||||
|
||||
if (!iovec_is_set(&nv_blob)) {
|
||||
r = tpm2_serialize(tc, nv_handle, &nv_blob.iov_base, &nv_blob.iov_len);
|
||||
r = tpm2_serialize(tc, nv_handle, &nv_blob);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to serialize NV index TR: %m");
|
||||
}
|
||||
|
||||
if (!iovec_is_set(&srk_blob)) {
|
||||
r = tpm2_serialize(tc, srk_handle, &srk_blob.iov_base, &srk_blob.iov_len);
|
||||
r = tpm2_serialize(tc, srk_handle, &srk_blob);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to serialize SRK index TR: %m");
|
||||
}
|
||||
|
||||
+11
-23
@@ -4579,15 +4579,13 @@ int tpm2_calculate_serialize(
|
||||
int tpm2_serialize(
|
||||
Tpm2Context *c,
|
||||
const Tpm2Handle *handle,
|
||||
void **ret_serialized,
|
||||
size_t *ret_serialized_size) {
|
||||
struct iovec *ret) {
|
||||
|
||||
TSS2_RC rc;
|
||||
|
||||
assert(c);
|
||||
assert(handle);
|
||||
assert(ret_serialized);
|
||||
assert(ret_serialized_size);
|
||||
assert(ret);
|
||||
|
||||
_cleanup_(Esys_Freep) unsigned char *serialized = NULL;
|
||||
size_t size = 0;
|
||||
@@ -4596,9 +4594,15 @@ int tpm2_serialize(
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
|
||||
"Failed to serialize: %s", sym_Tss2_RC_Decode(rc));
|
||||
|
||||
*ret_serialized = TAKE_PTR(serialized);
|
||||
*ret_serialized_size = size;
|
||||
/* Make a copy since we don't want the caller to understand that ESYS allocated the pointer.
|
||||
* It would make tracking what deallocator to use for the result in which context a PITA. */
|
||||
struct iovec v;
|
||||
v.iov_base = memdup(serialized, size);
|
||||
if (!v.iov_base)
|
||||
return log_oom_debug();
|
||||
v.iov_len = size;
|
||||
|
||||
*ret = v;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5466,25 +5470,9 @@ int tpm2_seal(Tpm2Context *c,
|
||||
log_debug("Completed TPM2 key sealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1));
|
||||
|
||||
if (ret_srk) {
|
||||
_cleanup_(iovec_done) struct iovec srk = {};
|
||||
_cleanup_(Esys_Freep) void *tmp = NULL;
|
||||
size_t tmp_size;
|
||||
|
||||
r = tpm2_serialize(c, primary_handle, &tmp, &tmp_size);
|
||||
r = tpm2_serialize(c, primary_handle, ret_srk);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/*
|
||||
* make a copy since we don't want the caller to understand that
|
||||
* ESYS allocated the pointer. It would make tracking what deallocator
|
||||
* to use for srk in which context a PITA.
|
||||
*/
|
||||
srk.iov_base = memdup(tmp, tmp_size);
|
||||
if (!srk.iov_base)
|
||||
return log_oom_debug();
|
||||
srk.iov_len = tmp_size;
|
||||
|
||||
*ret_srk = TAKE_STRUCT(srk);
|
||||
}
|
||||
|
||||
*ret_secret = TAKE_STRUCT(secret);
|
||||
|
||||
@@ -301,7 +301,7 @@ int tpm2_undefine_policy_nv_index(Tpm2Context *c, const Tpm2Handle *session, TPM
|
||||
int tpm2_seal_data(Tpm2Context *c, const struct iovec *data, const Tpm2Handle *primary_handle, const Tpm2Handle *encryption_session, const TPM2B_DIGEST *policy, struct iovec *ret_public, struct iovec *ret_private);
|
||||
int tpm2_unseal_data(Tpm2Context *c, const struct iovec *public, const struct iovec *private, const Tpm2Handle *primary_handle, const Tpm2Handle *policy_session, const Tpm2Handle *encryption_session, struct iovec *ret_data);
|
||||
|
||||
int tpm2_serialize(Tpm2Context *c, const Tpm2Handle *handle, void **ret_serialized, size_t *ret_serialized_size);
|
||||
int tpm2_serialize(Tpm2Context *c, const Tpm2Handle *handle, struct iovec *ret);
|
||||
int tpm2_deserialize(Tpm2Context *c, const struct iovec *serialized, Tpm2Handle **ret_handle);
|
||||
|
||||
int tpm2_load_public_key_file(const char *path, TPM2B_PUBLIC *ret);
|
||||
|
||||
Reference in New Issue
Block a user