cli/command/
create_primary.rs1use super::{deny_keyedhash, CommandError};
6use crate::{
7 cli::{get_auth, Hierarchy, SubCommand},
8 context::ContextCache,
9 device::{with_device, Auth, Device, DeviceError},
10 key::Alg,
11 template::{build_public_template, default_attributes},
12};
13use argh::FromArgs;
14use std::{cell::RefCell, rc::Rc};
15use tpm2_protocol::{
16 data::{
17 Tpm2bAuth, Tpm2bData, Tpm2bDigest, Tpm2bPublic, Tpm2bSensitiveCreate, Tpm2bSensitiveData,
18 TpmCc, TpmRh, TpmSe, TpmlPcrSelection, TpmsSensitiveCreate,
19 },
20 message::TpmCreatePrimaryCommand,
21};
22
23#[derive(FromArgs, Debug)]
25#[argh(subcommand, name = "create-primary")]
26pub struct CreatePrimary {
27 #[argh(option, short = 'H')]
29 pub hierarchy: Option<Hierarchy>,
30
31 #[argh(positional)]
33 pub algorithm: Alg,
34
35 #[argh(option, arg_name = "auth", short = 'a')]
38 pub auth: Option<String>,
39
40 #[argh(option, arg_name = "auth", short = 'm', long = "hmac-auth")]
43 pub hmac_auth: Option<String>,
44}
45
46impl SubCommand for CreatePrimary {
47 fn run(
48 &self,
49 device: Option<Rc<RefCell<Device>>>,
50 context: &mut ContextCache,
51 _plain: bool,
52 ) -> Result<(), CommandError> {
53 let auth = get_auth(
54 self.auth.as_ref(),
55 "TPM2SH_AUTH",
56 &context.session_map,
57 &[TpmSe::Policy],
58 )?;
59 with_device(device, |device| {
60 deny_keyedhash(&self.algorithm)?;
61
62 let primary_handle: TpmRh = self.hierarchy.unwrap_or_default().into();
63 let handles = [primary_handle as u32];
64 let auths = std::slice::from_ref(&auth);
65
66 let new_obj_user_auth = match &auth {
67 Auth::Password(p) => Tpm2bAuth::try_from(p.as_slice())?,
68 Auth::Tracked(_) => Tpm2bAuth::default(),
69 };
70
71 let user_with_auth = !new_obj_user_auth.is_empty();
72 let object_attributes = default_attributes(&self.algorithm, user_with_auth);
73 let public_template =
74 build_public_template(&self.algorithm, Tpm2bDigest::default(), object_attributes);
75
76 let cmd = TpmCreatePrimaryCommand {
77 primary_handle: (primary_handle as u32).into(),
78 in_sensitive: Tpm2bSensitiveCreate {
79 inner: TpmsSensitiveCreate {
80 user_auth: new_obj_user_auth,
81 data: Tpm2bSensitiveData::default(),
82 },
83 },
84 in_public: Tpm2bPublic {
85 inner: public_template,
86 },
87 outside_info: Tpm2bData::default(),
88 creation_pcr: TpmlPcrSelection::default(),
89 };
90
91 let (resp, _) = context.execute(device, &cmd, &handles, auths)?;
92
93 let resp = resp
94 .CreatePrimary()
95 .map_err(|_| DeviceError::ResponseMismatch(TpmCc::CreatePrimary))?;
96
97 let object_handle = resp.object_handle;
98 device.add_name_to_cache(object_handle.0, resp.name);
99 context.track(object_handle)?;
100
101 context.new_context(device, object_handle, &resp.name)?;
102 Ok(())
103 })
104 }
105}