Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions tss-esapi/src/abstraction/nv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ pub fn read_full(
}

/// Returns the NvPublic and Name associated with an NV index TPM handle
///
/// NOTE: This call _may_ close existing ESYS handles to the NV Index.
fn get_nv_index_info(
context: &mut Context,
nv_index_tpm_handle: NvIndexTpmHandle,
Expand All @@ -63,6 +65,8 @@ fn get_nv_index_info(
}

/// Lists all the currently defined NV Indexes' names and public components
///
/// NOTE: This call _may_ close existing ESYS handles to the NV Index.
pub fn list(context: &mut Context) -> Result<Vec<(NvPublic, Name)>> {
context.execute_without_session(|ctx| {
ctx.get_capability(
Expand Down Expand Up @@ -166,6 +170,8 @@ pub fn max_nv_buffer_size(ctx: &mut Context) -> Result<usize> {
/// Provides methods and trait implementations to interact with a non-volatile storage index that has been opened.
///
/// Use [`NvOpenOptions::open`] to obtain an [`NvReaderWriter`] object.
///
/// NOTE: When the `NvReaderWriter` is dropped, any existing ESYS handles to NV Indexes _may_ be closed.
#[derive(Debug)]
pub struct NvReaderWriter<'a> {
context: &'a mut Context,
Expand Down
10 changes: 7 additions & 3 deletions tss-esapi/src/context/handle_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,14 @@ impl HandleManager {
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
}

if self.open_handles.contains_key(&handle) {
error!("Handle({}) is already open", ESYS_TR::from(handle));
return Err(Error::local_error(WrapperErrorKind::InvalidHandleState));
// The TSS might return the same handle, see #383
if let Some(stored_handle_drop_action) = self.open_handles.get(&handle) {
if handle_drop_action != *stored_handle_drop_action {
error!("Handle drop action inconsistency");
return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
}
}

let _ = self.open_handles.insert(handle, handle_drop_action);
Ok(())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use tss_esapi::{

use crate::common::create_ctx_without_session;

#[ignore = "issues with tpm2-tss"]
#[test]
fn test_retrieve_ek_pubcert() {
let mut context = create_ctx_without_session();
Expand Down
28 changes: 24 additions & 4 deletions tss-esapi/tests/integration_tests/abstraction_tests/nv_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ fn write_nv_index(context: &mut Context, nv_index: NvIndexTpmHandle) -> NvIndexH
owner_nv_index_handle
}

#[ignore = "issues with tpm2-tss"]
#[test]
fn list() {
let mut context = create_ctx_with_session();
Expand All @@ -73,31 +72,52 @@ fn list() {
.map(|(public, _)| public.nv_index())
.any(|x| x == nv_index));

let owner_nv_index_handle = write_nv_index(&mut context, nv_index);
let initial_owner_nv_index_handle = write_nv_index(&mut context, nv_index);

assert!(nv::list(&mut context)
.unwrap()
.iter()
.map(|(public, _)| public.nv_index())
.any(|x| x == nv_index));

// Need to get the ESYS handle again, as it was closed by nv::list above.
// 1. If this fails with a TssError something is seriously wrong but it
// does not hurt to to try to clean the NV space up using the initial handle.
//
// 2. If this fails with a WrapperError then there is only an inconsistency
// in how the handle should be closed and cleaning up the NV space should
// using the initial handle should still be possible.
let owner_nv_index_handle = context
.tr_from_tpm_public(nv_index.into())
.map_or_else(|_| initial_owner_nv_index_handle, NvIndexHandle::from);

context
.nv_undefine_space(Provision::Owner, owner_nv_index_handle)
.expect("Call to nv_undefine_space failed");
}

#[ignore = "issues with tpm2-tss"]
#[test]
fn read_full() {
let mut context = create_ctx_with_session();

let nv_index = NvIndexTpmHandle::new(0x01500015).unwrap();

let owner_nv_index_handle = write_nv_index(&mut context, nv_index);
let initial_owner_nv_index_handle = write_nv_index(&mut context, nv_index);

// Now read it back
let read_result = nv::read_full(&mut context, NvAuth::Owner, nv_index);

// Need to get the ESYS handle again, as it was closed by nv::list above.
// 1. If this fails with a TssError something is seriously wrong but it
// does not hurt to to try to clean the NV space up using the initial handle.
//
// 2. If this fails with a WrapperError then there is only an inconsistency
// in how the handle should be closed and cleaning up the NV space should
// using the initial handle should still be possible.
let owner_nv_index_handle = context
.tr_from_tpm_public(nv_index.into())
.map_or_else(|_| initial_owner_nv_index_handle, NvIndexHandle::from);

context
.nv_undefine_space(Provision::Owner, owner_nv_index_handle)
.expect("Call to nv_undefine_space failed");
Expand Down