Skip to content

Commit 2f45b9c

Browse files
committed
build(deps): update tss-esapi and revert policysigned
- Update tss-esapi to commit: 2c36f10, which fixes the policy_signed API. - Revert the changes (workaround) to policysigned.rs in commit: 35c3fb2. Signed-off-by: Takuma IMAMURA <209989118+hyperfinitism@users.noreply.github.com>
1 parent a1057e1 commit 2f45b9c

3 files changed

Lines changed: 63 additions & 142 deletions

File tree

Cargo.lock

Lines changed: 2 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ log = "0.4.29"
2020
serde = { version = "1.0.228", features = ["derive"] }
2121
serde_json = "1.0.149"
2222
thiserror = "2.0.18"
23-
tss-esapi = { version = "8.0.0-alpha.2", features = ["serde"] }
23+
tss-esapi = { git = "https://github.com/parallaxsecond/rust-tss-esapi", rev = "2c36f103edb30320ec03e5d4b3ebe3eb58a2291f", features = ["serde"] }
2424

2525
[dev-dependencies]
2626
assert_cmd = "2.2.0"

src/cmd/policysigned.rs

Lines changed: 60 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,21 @@ use std::path::PathBuf;
55
use anyhow::Context;
66
use clap::Parser;
77
use log::info;
8-
use tss_esapi::structures::Signature;
8+
use tss_esapi::constants::SessionType;
9+
use tss_esapi::handles::{ObjectHandle, SessionHandle};
10+
use tss_esapi::structures::{Digest, Nonce, Signature};
911
use tss_esapi::traits::UnMarshall;
10-
use tss_esapi::tss2_esys::*;
12+
use tss_esapi::tss2_esys::TPMT_TK_AUTH;
1113

1214
use crate::cli::GlobalOpts;
13-
use crate::parse::{self, parse_context_source};
14-
use crate::raw_esys::RawEsysContext;
15+
use crate::context::create_context;
16+
use crate::handle::{ContextSource, load_object_from_source};
17+
use crate::parse::parse_context_source;
18+
use crate::session::load_session_from_file;
1519

16-
use crate::handle::ContextSource;
17-
18-
/// Extend a policy with PolicySigned.
20+
/// Authorize a policy with a signed authorization.
1921
///
20-
/// Wraps TPM2_PolicySigned (raw FFI). PolicySigned uses no
21-
/// authorization sessions because the command has no authIndex.
22-
/// Instead, the TPM validates the provided signature against
23-
/// authObject's public key as part of the policy assertion.
22+
/// Wraps TPM2_PolicySigned.
2423
#[derive(Parser)]
2524
pub struct PolicySignedCmd {
2625
/// Policy session file
@@ -44,8 +43,8 @@ pub struct PolicySignedCmd {
4443
pub cphash_input: Option<PathBuf>,
4544

4645
/// Policy reference (digest) (hex:<hex_bytes> or file:<path>)
47-
#[arg(short = 'q', long = "qualification", value_parser = parse::parse_qualification)]
48-
pub qualification: Option<parse::Qualification>,
46+
#[arg(short = 'q', long = "qualification", value_parser = crate::parse::parse_qualification)]
47+
pub qualification: Option<crate::parse::Qualification>,
4948

5049
/// Output file for the timeout
5150
#[arg(short = 't', long = "timeout")]
@@ -62,160 +61,84 @@ pub struct PolicySignedCmd {
6261

6362
impl PolicySignedCmd {
6463
pub fn execute(&self, global: &GlobalOpts) -> anyhow::Result<()> {
65-
let mut raw = RawEsysContext::new(global.tcti.as_deref())?;
64+
let mut ctx = create_context(global.tcti.as_deref())?;
6665

67-
let session_handle = raw.context_load(
68-
self.session
69-
.to_str()
70-
.ok_or_else(|| anyhow::anyhow!("invalid session path"))?,
71-
)?;
66+
let session = load_session_from_file(&mut ctx, &self.session, SessionType::Policy)?;
67+
let policy_session = session
68+
.try_into()
69+
.map_err(|_| anyhow::anyhow!("expected a policy session"))?;
7270

73-
let auth_object = raw.resolve_handle_from_source(&self.key_context)?;
71+
let auth_object = load_object_from_source(&mut ctx, &self.key_context)?;
7472

7573
let sig_data = std::fs::read(&self.signature)
7674
.with_context(|| format!("reading signature from {}", self.signature.display()))?;
7775
let signature = Signature::unmarshall(&sig_data)
7876
.map_err(|e| anyhow::anyhow!("invalid signature: {e}"))?;
79-
let tpmt_sig: TPMT_SIGNATURE = signature
80-
.try_into()
81-
.map_err(|e| anyhow::anyhow!("signature conversion: {e:?}"))?;
82-
83-
let nonce_tpm = TPM2B_NONCE::default();
8477

8578
let cp_hash = match &self.cphash_input {
8679
Some(path) => {
8780
let data = std::fs::read(path)?;
88-
let mut buf = TPM2B_DIGEST::default();
89-
if data.len() > buf.buffer.len() {
90-
anyhow::bail!(
91-
"cpHash from {} is too large: {} bytes (maximum {} bytes)",
92-
path.display(),
93-
data.len(),
94-
buf.buffer.len()
95-
);
96-
}
97-
buf.size = data.len() as u16;
98-
buf.buffer[..data.len()].copy_from_slice(&data);
99-
buf
81+
Digest::try_from(data).map_err(|e| anyhow::anyhow!("invalid cpHash: {e}"))?
10082
}
101-
None => TPM2B_DIGEST::default(),
83+
None => Digest::default(),
10284
};
10385

10486
let policy_ref = match &self.qualification {
105-
Some(q) => {
106-
let data = q.as_slice();
107-
let mut buf = TPM2B_NONCE::default();
108-
if data.len() > buf.buffer.len() {
109-
anyhow::bail!(
110-
"qualification is too large: {} bytes (maximum {} bytes)",
111-
data.len(),
112-
buf.buffer.len()
113-
);
114-
}
115-
buf.size = data.len() as u16;
116-
buf.buffer[..data.len()].copy_from_slice(data);
117-
buf
118-
}
119-
None => TPM2B_NONCE::default(),
87+
Some(bytes) => Nonce::try_from(bytes.as_slice().to_vec())
88+
.map_err(|e| anyhow::anyhow!("qualifying data: {e}"))?,
89+
None => Nonce::default(),
12090
};
12191

122-
// Extract data from ESYS-allocated pointers immediately, then free
123-
// them before performing any I/O that could fail and leak memory.
124-
let (timeout_data, ticket_data) = unsafe {
125-
let mut timeout_ptr: *mut TPM2B_TIMEOUT = std::ptr::null_mut();
126-
let mut ticket_ptr: *mut TPMT_TK_AUTH = std::ptr::null_mut();
92+
let expiration = if self.expiration == 0 {
93+
None
94+
} else {
95+
Some(std::time::Duration::from_secs(self.expiration as u64))
96+
};
12797

128-
// PolicySigned has Auth Index: None for both handles,
129-
// so all session handles are ESYS_TR_NONE.
130-
let rc = Esys_PolicySigned(
131-
raw.ptr(),
98+
let (timeout, ticket) = ctx
99+
.policy_signed(
100+
policy_session,
132101
auth_object,
133-
session_handle,
134-
ESYS_TR_NONE,
135-
ESYS_TR_NONE,
136-
ESYS_TR_NONE,
137-
&nonce_tpm,
138-
&cp_hash,
139-
&policy_ref,
140-
self.expiration,
141-
&tpmt_sig,
142-
&mut timeout_ptr,
143-
&mut ticket_ptr,
144-
);
145-
if rc != 0 {
146-
anyhow::bail!("Esys_PolicySigned failed: 0x{rc:08x}");
147-
}
148-
149-
let timeout_data = if !timeout_ptr.is_null() {
150-
let t = &*timeout_ptr;
151-
Some(t.buffer[..t.size as usize].to_vec())
152-
} else {
153-
None
154-
};
155-
156-
let ticket_data = if !ticket_ptr.is_null() {
157-
let ticket = &*ticket_ptr;
158-
let bytes = std::slice::from_raw_parts(
159-
ticket as *const TPMT_TK_AUTH as *const u8,
160-
std::mem::size_of::<TPMT_TK_AUTH>(),
161-
);
162-
Some(bytes.to_vec())
163-
} else {
164-
None
165-
};
102+
Nonce::default(), // nonce_tpm
103+
cp_hash,
104+
policy_ref,
105+
expiration,
106+
signature,
107+
)
108+
.context("TPM2_PolicySigned failed")?;
166109

167-
if !timeout_ptr.is_null() {
168-
Esys_Free(timeout_ptr as *mut _);
169-
}
170-
if !ticket_ptr.is_null() {
171-
Esys_Free(ticket_ptr as *mut _);
172-
}
173-
174-
(timeout_data, ticket_data)
175-
};
110+
info!("policy signed succeeded");
176111

177-
if let (Some(path), Some(data)) = (&self.timeout_out, &timeout_data) {
178-
std::fs::write(path, data)
112+
if let Some(ref path) = self.timeout_out {
113+
std::fs::write(path, timeout.as_bytes())
179114
.with_context(|| format!("writing timeout to {}", path.display()))?;
180115
}
181116

182-
if let (Some(path), Some(data)) = (&self.ticket_out, &ticket_data) {
183-
std::fs::write(path, data)
117+
if let Some(ref path) = self.ticket_out {
118+
let tss_ticket: TPMT_TK_AUTH = ticket
119+
.try_into()
120+
.map_err(|e| anyhow::anyhow!("failed to convert ticket: {e:?}"))?;
121+
let bytes = unsafe {
122+
std::slice::from_raw_parts(
123+
&tss_ticket as *const TPMT_TK_AUTH as *const u8,
124+
std::mem::size_of::<TPMT_TK_AUTH>(),
125+
)
126+
};
127+
std::fs::write(path, bytes)
184128
.with_context(|| format!("writing ticket to {}", path.display()))?;
185129
}
186130

187131
if let Some(ref path) = self.policy {
188-
let digest_data = unsafe {
189-
let mut digest_ptr: *mut TPM2B_DIGEST = std::ptr::null_mut();
190-
let rc = Esys_PolicyGetDigest(
191-
raw.ptr(),
192-
session_handle,
193-
ESYS_TR_NONE,
194-
ESYS_TR_NONE,
195-
ESYS_TR_NONE,
196-
&mut digest_ptr,
197-
);
198-
if rc != 0 {
199-
anyhow::bail!("Esys_PolicyGetDigest failed: 0x{rc:08x}");
200-
}
201-
202-
if !digest_ptr.is_null() {
203-
let d = &*digest_ptr;
204-
let v = d.buffer[..d.size as usize].to_vec();
205-
Esys_Free(digest_ptr as *mut _);
206-
Some(v)
207-
} else {
208-
None
209-
}
210-
};
211-
if let Some(ref data) = digest_data {
212-
std::fs::write(path, data)
213-
.with_context(|| format!("writing policy digest to {}", path.display()))?;
214-
}
132+
let digest = ctx
133+
.policy_get_digest(policy_session)
134+
.context("TPM2_PolicyGetDigest failed")?;
135+
std::fs::write(path, digest.as_bytes())
136+
.with_context(|| format!("writing policy digest to {}", path.display()))?;
215137
}
216138

217-
raw.context_save_to_file(session_handle, &self.session)?;
218-
info!("policy signed succeeded");
139+
let handle: ObjectHandle = SessionHandle::from(policy_session).into();
140+
crate::session::save_session_and_forget(ctx, handle, &self.session)?;
141+
219142
Ok(())
220143
}
221144
}

0 commit comments

Comments
 (0)