Skip to main content

tss_esapi/structures/lists/
handles.rs

1// Copyright 2022 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::handles::TpmHandle;
4use crate::tss2_esys::{TPM2_HANDLE, TPML_HANDLE};
5use crate::{Error, Result, WrapperErrorKind};
6use log::error;
7use std::convert::TryFrom;
8use std::ops::Deref;
9
10/// A list of TPM handles
11///
12/// # Details
13/// This corresponds to `TPML_HANDLE`.
14#[derive(Debug, Clone, Default, PartialEq, Eq)]
15pub struct HandleList {
16    handles: Vec<TpmHandle>,
17}
18
19impl HandleList {
20    pub const MAX_SIZE: usize = Self::calculate_max_size();
21
22    pub fn new() -> Self {
23        HandleList {
24            handles: Vec::new(),
25        }
26    }
27
28    /// Adds a handle to the current list of handles.
29    pub fn add(&mut self, handle: TpmHandle) -> Result<()> {
30        if self.handles.len() + 1 > HandleList::MAX_SIZE {
31            error!(
32                "Adding TPM handle to list will make the list exceeded its maximum count(> {})",
33                HandleList::MAX_SIZE
34            );
35            return Err(Error::local_error(WrapperErrorKind::WrongParamSize));
36        }
37        self.handles.push(handle);
38        Ok(())
39    }
40
41    /// Returns the inner type.
42    pub fn into_inner(self) -> Vec<TpmHandle> {
43        self.handles
44    }
45
46    /// Private function that calculates the maximum number
47    /// elements allowed in internal storage.
48    const fn calculate_max_size() -> usize {
49        crate::structures::capability_data::max_cap_size::<TPM2_HANDLE>()
50    }
51}
52
53impl TryFrom<TPML_HANDLE> for HandleList {
54    type Error = Error;
55
56    fn try_from(handles: TPML_HANDLE) -> Result<Self> {
57        let handle_count = handles.count as usize;
58        if handle_count > Self::MAX_SIZE {
59            error!("Error: Invalid TPML_HANDLE count(> {})", Self::MAX_SIZE);
60            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
61        }
62        handles.handle[..handle_count]
63            .iter()
64            .map(|&cc| TpmHandle::try_from(cc))
65            .collect::<Result<Vec<TpmHandle>>>()
66            .map(|handles| HandleList { handles })
67    }
68}
69
70impl From<HandleList> for TPML_HANDLE {
71    fn from(handles: HandleList) -> Self {
72        let mut tss_handles: TPML_HANDLE = Default::default();
73        for handle in handles.handles {
74            tss_handles.handle[tss_handles.count as usize] = handle.into();
75            tss_handles.count += 1;
76        }
77        tss_handles
78    }
79}
80
81impl TryFrom<Vec<TpmHandle>> for HandleList {
82    type Error = Error;
83
84    fn try_from(handles: Vec<TpmHandle>) -> Result<Self> {
85        if handles.len() > Self::MAX_SIZE {
86            error!("Error: Invalid TPML_HANDLE count(> {})", Self::MAX_SIZE);
87            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
88        }
89        Ok(HandleList { handles })
90    }
91}
92
93impl From<HandleList> for Vec<TpmHandle> {
94    fn from(handle_list: HandleList) -> Self {
95        handle_list.handles
96    }
97}
98
99impl AsRef<[TpmHandle]> for HandleList {
100    fn as_ref(&self) -> &[TpmHandle] {
101        self.handles.as_slice()
102    }
103}
104
105impl Deref for HandleList {
106    type Target = Vec<TpmHandle>;
107
108    fn deref(&self) -> &Self::Target {
109        &self.handles
110    }
111}