Skip to main content

tss_esapi/structures/
tickets.rs

1// Copyright 2020 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::{
4    constants::StructureTag,
5    handles::TpmHandle,
6    interface_types::reserved_handles::Hierarchy,
7    tss2_esys::{
8        TPM2B_DIGEST, TPMT_TK_AUTH, TPMT_TK_CREATION, TPMT_TK_HASHCHECK, TPMT_TK_VERIFIED,
9    },
10    Error, Result, WrapperErrorKind,
11};
12
13use log::error;
14use std::{
15    convert::{TryFrom, TryInto},
16    default::Default,
17};
18
19/// Macro used for implementing try_from
20/// TssTicketType -> TicketType
21/// TicketType -> TssTicketType
22const TPM2B_DIGEST_BUFFER_SIZE: usize = 64;
23macro_rules! impl_ticket_try_froms {
24    ($ticket_type:ident, $tss_ticket_type:ident) => {
25        impl TryFrom<$ticket_type> for $tss_ticket_type {
26            type Error = Error;
27            fn try_from(ticket: $ticket_type) -> Result<Self> {
28                let tag = ticket.tag();
29                let digest = ticket.digest;
30                if digest.len() > TPM2B_DIGEST_BUFFER_SIZE {
31                    return Err(Error::local_error(WrapperErrorKind::WrongParamSize));
32                }
33                let mut buffer = [0; TPM2B_DIGEST_BUFFER_SIZE];
34                buffer[..digest.len()].clone_from_slice(&digest[..digest.len()]);
35                Ok($tss_ticket_type {
36                    tag: tag.into(),
37                    hierarchy: TpmHandle::from(ticket.hierarchy).into(),
38                    digest: TPM2B_DIGEST {
39                        size: digest.len().try_into().unwrap(), // should not fail based on the checks done above
40                        buffer,
41                    },
42                })
43            }
44        }
45
46        impl TryFrom<$tss_ticket_type> for $ticket_type {
47            type Error = Error;
48
49            fn try_from(tss_ticket: $tss_ticket_type) -> Result<Self> {
50                let tag = match StructureTag::try_from(tss_ticket.tag) {
51                    Ok(val) => {
52                        if !<$ticket_type>::POSSIBLE_TAGS.contains(&val) {
53                            return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
54                        }
55                        val
56                    }
57                    Err(why) => {
58                        error!("Failed to parsed tag: {}", why);
59                        return Err(Error::local_error(WrapperErrorKind::InvalidParam));
60                    }
61                };
62
63                let len = tss_ticket.digest.size.into();
64                if len > TPM2B_DIGEST_BUFFER_SIZE {
65                    error!(
66                        "Invalid digest size. (Digest size: {0} > Digest buffer size: {1})",
67                        len, TPM2B_DIGEST_BUFFER_SIZE,
68                    );
69                    return Err(Error::local_error(WrapperErrorKind::InvalidParam));
70                }
71                let mut digest = tss_ticket.digest.buffer.to_vec();
72                digest.truncate(len);
73
74                let hierarchy = Hierarchy::try_from(TpmHandle::try_from(tss_ticket.hierarchy)?)?;
75
76                Ok($ticket_type {
77                    tag,
78                    hierarchy,
79                    digest,
80                })
81            }
82        }
83    };
84}
85
86pub trait Ticket {
87    const POSSIBLE_TAGS: &'static [StructureTag];
88    fn tag(&self) -> StructureTag;
89    fn hierarchy(&self) -> Hierarchy;
90    fn digest(&self) -> &[u8];
91}
92
93#[derive(Debug, Clone)]
94pub struct AuthTicket {
95    tag: StructureTag,
96    hierarchy: Hierarchy,
97    digest: Vec<u8>,
98}
99
100impl Ticket for AuthTicket {
101    /// The possible tags of AuthTickets
102    const POSSIBLE_TAGS: &'static [StructureTag] =
103        &[StructureTag::AuthSecret, StructureTag::AuthSigned];
104
105    /// Get the tag associated with the auth ticket.
106    fn tag(&self) -> StructureTag {
107        self.tag
108    }
109
110    /// Get the hierarchy associated with the auth ticket.
111    fn hierarchy(&self) -> Hierarchy {
112        self.hierarchy
113    }
114
115    /// Get the digest associated with the auth ticket.
116    fn digest(&self) -> &[u8] {
117        &self.digest
118    }
119}
120
121impl_ticket_try_froms!(AuthTicket, TPMT_TK_AUTH);
122
123#[derive(Debug, Clone)]
124pub struct HashcheckTicket {
125    tag: StructureTag,
126    hierarchy: Hierarchy,
127    digest: Vec<u8>,
128}
129
130impl Default for HashcheckTicket {
131    /// The default for the Hashcheck ticket is the Null ticket.
132    fn default() -> Self {
133        Self {
134            tag: StructureTag::Hashcheck,
135            hierarchy: Hierarchy::Null,
136            digest: Vec::<u8>::new(),
137        }
138    }
139}
140
141impl Ticket for HashcheckTicket {
142    /// The tag of the verified ticket.
143    const POSSIBLE_TAGS: &'static [StructureTag] = &[StructureTag::Hashcheck];
144
145    /// Get the tag associated with the hashcheck ticket.
146    fn tag(&self) -> StructureTag {
147        self.tag
148    }
149
150    /// Get the hierarchy associated with the verification ticket.
151    fn hierarchy(&self) -> Hierarchy {
152        self.hierarchy
153    }
154
155    /// Get the digest associated with the verification ticket.
156    fn digest(&self) -> &[u8] {
157        &self.digest
158    }
159}
160
161impl_ticket_try_froms!(HashcheckTicket, TPMT_TK_HASHCHECK);
162
163/// Rust native wrapper for `TPMT_TK_VERIFIED` objects.
164#[derive(Debug)]
165pub struct VerifiedTicket {
166    tag: StructureTag,
167    hierarchy: Hierarchy,
168    digest: Vec<u8>,
169}
170
171impl Ticket for VerifiedTicket {
172    // type TssTicketType = TPMT_TK_VERIFIED;
173    /// The tag of the verified ticket.
174    const POSSIBLE_TAGS: &'static [StructureTag] = &[StructureTag::Verified];
175    /// Get the tag associated with the verification ticket.
176    fn tag(&self) -> StructureTag {
177        self.tag
178    }
179    /// Get the hierarchy associated with the verification ticket.
180    fn hierarchy(&self) -> Hierarchy {
181        self.hierarchy
182    }
183    /// Get the digest associated with the verification ticket.
184    fn digest(&self) -> &[u8] {
185        &self.digest
186    }
187}
188
189impl_ticket_try_froms!(VerifiedTicket, TPMT_TK_VERIFIED);
190
191/// Rust native wrapper for `TPMT_TK_CREATION` objects.
192#[derive(Debug)]
193pub struct CreationTicket {
194    tag: StructureTag,
195    hierarchy: Hierarchy,
196    digest: Vec<u8>,
197}
198
199impl Ticket for CreationTicket {
200    // type TssTicketType = TPMT_TK_VERIFIED;
201    /// The tag of the verified ticket.
202    const POSSIBLE_TAGS: &'static [StructureTag] = &[StructureTag::Creation];
203
204    /// Get the tag associated with the creation ticket.
205    fn tag(&self) -> StructureTag {
206        self.tag
207    }
208
209    /// Get the hierarchy associated with the verification ticket.
210    fn hierarchy(&self) -> Hierarchy {
211        self.hierarchy
212    }
213    /// Get the digest associated with the verification ticket.
214    fn digest(&self) -> &[u8] {
215        &self.digest
216    }
217}
218
219impl_ticket_try_froms!(CreationTicket, TPMT_TK_CREATION);