Skip to main content

tss_esapi/structures/buffers/
public.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{
5    structures::Public,
6    traits::{impl_mu_complex, Marshall, UnMarshall},
7    tss2_esys::{TPM2B_PUBLIC, TPMT_PUBLIC},
8    Error, Result, WrapperErrorKind,
9};
10use log::error;
11use std::{
12    convert::{TryFrom, TryInto},
13    mem::size_of,
14    ops::Deref,
15};
16use zeroize::{Zeroize, ZeroizeOnDrop};
17
18/// Public data buffer.
19///
20/// # Details
21/// Corresponds to `TPM2B_PUBLIC`. The contents of
22/// the buffer can be unmarshalled into a [Public]
23/// structure.
24#[derive(Debug, Clone, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
25pub struct PublicBuffer(Vec<u8>);
26
27impl PublicBuffer {
28    pub const MAX_SIZE: usize = size_of::<TPMT_PUBLIC>();
29
30    pub fn value(&self) -> &[u8] {
31        &self.0
32    }
33
34    /// Private function for ensuring that a buffer size is valid.
35    fn ensure_valid_buffer_size(buffer_size: usize, container_name: &str) -> Result<()> {
36        if buffer_size > Self::MAX_SIZE {
37            error!("Invalid {} size(> {})", container_name, Self::MAX_SIZE);
38            return Err(Error::local_error(WrapperErrorKind::WrongParamSize));
39        }
40        Ok(())
41    }
42}
43
44impl Deref for PublicBuffer {
45    type Target = Vec<u8>;
46
47    fn deref(&self) -> &Self::Target {
48        &self.0
49    }
50}
51
52impl TryFrom<Vec<u8>> for PublicBuffer {
53    type Error = Error;
54
55    fn try_from(bytes: Vec<u8>) -> Result<Self> {
56        Self::ensure_valid_buffer_size(bytes.len(), "Vec<u8>")?;
57        Ok(PublicBuffer(bytes))
58    }
59}
60
61impl TryFrom<&[u8]> for PublicBuffer {
62    type Error = Error;
63
64    fn try_from(bytes: &[u8]) -> Result<Self> {
65        Self::ensure_valid_buffer_size(bytes.len(), "&[u8]")?;
66        Ok(PublicBuffer(bytes.to_vec()))
67    }
68}
69
70impl TryFrom<TPM2B_PUBLIC> for PublicBuffer {
71    type Error = Error;
72
73    fn try_from(tss: TPM2B_PUBLIC) -> Result<Self> {
74        let size = tss.size as usize;
75        Self::ensure_valid_buffer_size(size, "buffer")?;
76        Public::try_from(tss.publicArea)
77            .and_then(|public| public.marshall())
78            .map(PublicBuffer)
79    }
80}
81
82impl TryFrom<PublicBuffer> for TPM2B_PUBLIC {
83    type Error = Error;
84
85    fn try_from(native: PublicBuffer) -> Result<Self> {
86        let mut buffer = TPM2B_PUBLIC {
87            size: native.0.len() as u16,
88            ..Default::default()
89        };
90        let public = Public::unmarshall(&native.0)?;
91        buffer.publicArea = public.into();
92        Ok(buffer)
93    }
94}
95
96impl TryFrom<PublicBuffer> for Public {
97    type Error = Error;
98
99    fn try_from(buf: PublicBuffer) -> Result<Self> {
100        Public::unmarshall(&buf.0)
101    }
102}
103
104impl TryFrom<Public> for PublicBuffer {
105    type Error = Error;
106
107    fn try_from(public: Public) -> Result<PublicBuffer> {
108        Ok(PublicBuffer(public.marshall()?))
109    }
110}
111
112impl_mu_complex!(PublicBuffer, TPM2B_PUBLIC);