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