1use crate::{
5 cli::SubCommand, command::CommandError, device::with_device, handle::Handle, job::Job,
6};
7use clap::Args;
8use std::io::IsTerminal;
9use tpm2_protocol::{data::TpmCc, message::TpmUnsealCommand};
10
11#[derive(Args, Debug)]
13#[command(about = "Retrieves data from a sealed data object.")]
14pub struct Unseal {
15 pub input: Handle,
17
18 #[arg(long)]
20 pub hex: bool,
21}
22
23impl SubCommand for Unseal {
24 fn run(&self, job: &mut Job) -> Result<(), CommandError> {
25 with_device(job.device.clone(), |device| {
26 let item_handle = job.load_context(device, &self.input)?;
27 let auths = vec![job.auth_list.first().cloned().unwrap_or_default()];
28
29 let unseal_cmd = TpmUnsealCommand {
30 item_handle: item_handle.0.into(),
31 };
32 let unseal_handles = [item_handle.0];
33
34 let (resp, _) = job.execute(device, &unseal_cmd, &unseal_handles, &auths)?;
35
36 let out_data = resp
37 .Unseal()
38 .map_err(|_| CommandError::ResponseMismatch(TpmCc::Unseal))?
39 .out_data;
40
41 if self.hex || std::io::stdout().is_terminal() {
42 writeln!(job.writer, "{}", hex::encode(out_data.as_ref()))?;
43 } else {
44 job.writer.write_all(out_data.as_ref())?;
45 }
46 Ok(())
47 })
48 }
49}