cli/command/
convert.rs

1// SPDX-License-Identifier: GPL-3-0-or-later
2// Copyright (c) 2024-2025 Jarkko Sakkinen
3// Copyright (c) 2025 Opinsys Oy
4
5use super::CommandError;
6use crate::{
7    cli::{get_auth, SubCommand},
8    context::ContextCache,
9    convert::{from_input_to_bytes, from_tpm_key_to_output},
10    device::{self, Device},
11    uri::Uri,
12};
13use argh::FromArgs;
14use std::{cell::RefCell, rc::Rc};
15use tpm2_protocol::data::TpmSe;
16
17/// Converts external key files to TPMKey files.
18#[derive(FromArgs, Debug)]
19#[argh(subcommand, name = "convert")]
20pub struct Convert {
21    /// parent: 'tpm://<handle>', or 'key://<name grip>'
22    #[argh(positional)]
23    pub parent: Uri,
24
25    /// input: PKCS#1, PKCS#8 or SEC1 key file
26    #[argh(positional)]
27    pub input: Option<Uri>,
28
29    /// output: TPMKey file
30    #[argh(option, short = 'o')]
31    pub output: Option<Uri>,
32
33    /// parent auth: 'password://<hex>' or 'session://<handle>'
34    /// Uses TPM2SH_PARENT_AUTH environment variable if not set.
35    #[argh(option, arg_name = "auth", short = 'p')]
36    pub parent_auth: Option<String>,
37
38    /// auth: 'password://<hex>' or 'session://<handle>'
39    /// Uses TPM2SH_AUTH environment variable if not set.
40    #[argh(option, arg_name = "auth", short = 'a')]
41    pub auth: Option<String>,
42
43    /// hmac auth: 'password://<hex>' or 'session://<handle>'
44    /// Uses TPM2SH_HMAC_AUTH environment variable if not set.
45    #[argh(option, arg_name = "auth", short = 'm', long = "hmac-auth")]
46    pub hmac_auth: Option<String>,
47}
48
49impl SubCommand for Convert {
50    fn run(
51        &self,
52        device: Option<Rc<RefCell<Device>>>,
53        context: &mut ContextCache,
54        _plain: bool,
55    ) -> Result<(), CommandError> {
56        let parent_auth = get_auth(
57            self.parent_auth.as_ref(),
58            "TPM2SH_PARENT_AUTH",
59            &context.session_map,
60            &[TpmSe::Policy],
61        )?;
62        device::with_device(device, |device| {
63            let input_bytes = from_input_to_bytes(self.input.as_ref())?;
64            let parent_handle = context.load_parent(device, &self.parent)?;
65            let tpm_key =
66                context.import_key(device, parent_handle, &input_bytes, &[parent_auth])?;
67            from_tpm_key_to_output(context, &tpm_key, self.output.as_ref())
68        })
69    }
70}