From 0767310e856c03bfe8f0e75174eb664c3d052306 Mon Sep 17 00:00:00 2001 From: Patrick Uiterwijk Date: Tue, 7 Dec 2021 16:16:15 +0100 Subject: [PATCH] feat: switch to josekit This patch changes from using biscuit to josekit for JWE. josekit uses OpenSSL for its crypto instead of ring. Signed-off-by: Patrick Uiterwijk --- Cargo.toml | 5 +- src/cli.rs | 37 +++--- src/main.rs | 276 +++++++++++---------------------------------- src/tpm_objects.rs | 36 +++--- src/utils.rs | 34 +++--- 5 files changed, 114 insertions(+), 274 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3fdeffd..a6704f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,10 +10,11 @@ license = "EUPL-1.2" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1" tss-esapi = "6.1.1" serde = "1.0" -biscuit = "0.5.0" +josekit = "0.7.4" serde_json = "1.0" base64 = "0.12.1" atty = "0.2.14" -tpm2-policy = "0.5.1" +tpm2-policy = "0.5.3" diff --git a/src/cli.rs b/src/cli.rs index d0c6b93..e5caa70 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,12 +1,11 @@ use std::convert::TryFrom; -use super::PinError; -use crate::utils::get_authorized_policy_step; - +use anyhow::{anyhow, bail, Error, Result}; use serde::{Deserialize, Serialize}; - use tpm2_policy::TPMPolicyStep; +use crate::utils::get_authorized_policy_step; + #[derive(Serialize, Deserialize, std::fmt::Debug)] pub(super) struct TPM2Config { pub hash: Option, @@ -24,9 +23,9 @@ pub(super) struct TPM2Config { } impl TryFrom<&TPM2Config> for TPMPolicyStep { - type Error = PinError; + type Error = Error; - fn try_from(cfg: &TPM2Config) -> Result { + fn try_from(cfg: &TPM2Config) -> Result { if cfg.pcr_ids.is_some() && cfg.policy_pubkey_path.is_some() { Ok(TPMPolicyStep::Or([ Box::new(TPMPolicyStep::PCRs( @@ -104,7 +103,7 @@ impl TPM2Config { } } - fn normalize(mut self) -> Result { + fn normalize(mut self) -> Result { self.normalize_pcr_ids()?; if self.pcr_ids.is_some() && self.pcr_bank.is_none() { self.pcr_bank = Some("sha256".to_string()); @@ -133,14 +132,12 @@ impl TPM2Config { || self.policy_path.is_none() || self.policy_ref.is_none()) { - return Err(PinError::Text( - "Not all of policy pubkey, path and ref are specified", - )); + bail!("Not all of policy pubkey, path and ref are specified",); } Ok(self) } - fn normalize_pcr_ids(&mut self) -> Result<(), PinError> { + fn normalize_pcr_ids(&mut self) -> Result<()> { // Normalize from array with one string to just string if let Some(serde_json::Value::Array(vals)) = &self.pcr_ids { if vals.len() == 1 { @@ -168,21 +165,21 @@ impl TPM2Config { Ok(res) => { let new = serde_json::Value::Number(res); if !new.is_u64() { - return Err("Non-positive string int"); + bail!("Non-positive string int"); } Ok(new) } - Err(_) => Err("Unparseable string int"), + Err(_) => Err(anyhow!("Unparseable string int")), } } serde_json::Value::Number(n) => { let new = serde_json::Value::Number(n.clone()); if !new.is_u64() { - return Err("Non-positive int"); + return Err(anyhow!("Non-positive int")); } Ok(new) } - _ => Err("Invalid value in pcr_ids"), + _ => Err(anyhow!("Invalid value in pcr_ids")), }) .collect(); self.pcr_ids = Some(serde_json::Value::Array(newvals?)); @@ -192,7 +189,7 @@ impl TPM2Config { None => Ok(()), // The normalization above would've caught any non-ints Some(serde_json::Value::Array(_)) => Ok(()), - _ => Err(PinError::Text("Invalid type")), + _ => Err(anyhow!("Invalid type")), } } } @@ -205,9 +202,7 @@ pub(super) enum ActionMode { Help, } -pub(super) fn get_mode_and_cfg( - args: &[String], -) -> Result<(ActionMode, Option), PinError> { +pub(super) fn get_mode_and_cfg(args: &[String]) -> Result<(ActionMode, Option)> { if args.len() > 1 && args[1] == "--summary" { return Ok((ActionMode::Summary, None)); } @@ -227,10 +222,10 @@ pub(super) fn get_mode_and_cfg( } else if args[1] == "decrypt" { (ActionMode::Decrypt, None) } else { - return Err(PinError::NoCommand); + bail!("No command specified"); } } else { - return Err(PinError::NoCommand); + bail!("No command specified"); }; let cfg: Option = match cfgstr { diff --git a/src/main.rs b/src/main.rs index 638b626..fb33aa7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,18 +13,14 @@ // limitations under the License. use std::convert::{TryFrom, TryInto}; -use std::error::Error; -use std::fmt; - use std::env; use std::io::{self, Read, Write}; -use biscuit::jwe; -use biscuit::CompactJson; - +use anyhow::{bail, Context, Error, Result}; +use josekit::jwe::{alg::direct::DirectJweAlgorithm::Dir, enc::A256GCM}; use serde::{Deserialize, Serialize}; - use tpm2_policy::TPMPolicyStep; +use tss_esapi::structures::SensitiveData; mod cli; mod tpm_objects; @@ -32,116 +28,7 @@ mod utils; use cli::TPM2Config; -use tss_esapi::structures::SensitiveData; - -#[derive(Debug)] -enum PinError { - Text(&'static str), - NoCommand, - Serde(serde_json::Error), - IO(std::io::Error), - TPM(tss_esapi::Error), - JWE(biscuit::errors::Error), - Base64Decoding(base64::DecodeError), - Utf8(std::str::Utf8Error), - FromUtf8(std::string::FromUtf8Error), - PolicyError(tpm2_policy::Error), -} - -impl PinError {} - -impl fmt::Display for PinError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - PinError::Text(e) => write!(f, "Error: {}", e), - PinError::Serde(err) => { - write!(f, "Serde error: ")?; - err.fmt(f) - } - PinError::IO(err) => { - write!(f, "IO error: ")?; - err.fmt(f) - } - PinError::TPM(err) => { - write!(f, "TPM error: ")?; - err.fmt(f) - } - PinError::JWE(err) => { - write!(f, "JWE error: ")?; - err.fmt(f) - } - PinError::Base64Decoding(err) => { - write!(f, "Base64 Decoding error: ")?; - err.fmt(f) - } - PinError::Utf8(err) => { - write!(f, "UTF8 error: ")?; - err.fmt(f) - } - PinError::FromUtf8(err) => { - write!(f, "UTF8 error: ")?; - err.fmt(f) - } - PinError::NoCommand => write!(f, "No command provided"), - PinError::PolicyError(err) => { - write!(f, "Policy Error: ")?; - err.fmt(f) - } - } - } -} - -impl Error for PinError {} - -impl From for PinError { - fn from(err: std::io::Error) -> Self { - PinError::IO(err) - } -} - -impl From for PinError { - fn from(err: tpm2_policy::Error) -> Self { - PinError::PolicyError(err) - } -} - -impl From<&'static str> for PinError { - fn from(err: &'static str) -> Self { - PinError::Text(err) - } -} - -impl From for PinError { - fn from(err: serde_json::Error) -> Self { - PinError::Serde(err) - } -} - -impl From for PinError { - fn from(err: tss_esapi::Error) -> Self { - PinError::TPM(err) - } -} - -impl From for PinError { - fn from(err: biscuit::errors::Error) -> Self { - PinError::JWE(err) - } -} - -impl From for PinError { - fn from(err: base64::DecodeError) -> Self { - PinError::Base64Decoding(err) - } -} - -impl From for PinError { - fn from(err: std::str::Utf8Error) -> Self { - PinError::Utf8(err) - } -} - -fn perform_encrypt(cfg: TPM2Config, input: Vec) -> Result<(), PinError> { +fn perform_encrypt(cfg: TPM2Config, input: Vec) -> Result<()> { let key_type = match &cfg.key { None => "ecc", Some(key_type) => key_type, @@ -161,17 +48,9 @@ fn perform_encrypt(cfg: TPM2Config, input: Vec) -> Result<(), PinError> { let (_, policy_digest) = policy_runner.send_policy(&mut ctx, true)?; - let key_bytes = ctx.get_random(32)?; - let key_bytes: &[u8] = key_bytes.value(); - let mut jwk = biscuit::jwk::JWK::new_octet_key(&key_bytes, biscuit::Empty {}); - jwk.common.algorithm = Some(biscuit::jwa::Algorithm::ContentEncryption( - biscuit::jwa::ContentEncryptionAlgorithm::A256GCM, - )); - jwk.common.key_operations = Some(vec![ - biscuit::jwk::KeyOperations::Encrypt, - biscuit::jwk::KeyOperations::Decrypt, - ]); - let jwk_str = serde_json::to_string(&jwk)?; + let mut jwk = josekit::jwk::Jwk::generate_oct_key(32).context("Error generating random JWK")?; + jwk.set_key_operations(vec!["encrypt", "decrypt"]); + let jwk_str = serde_json::to_string(&jwk.as_ref())?; let public = tpm_objects::create_tpm2b_public_sealed_object(policy_digest)?; let jwk_str = SensitiveData::try_from(jwk_str.as_bytes().to_vec())?; @@ -183,52 +62,37 @@ fn perform_encrypt(cfg: TPM2Config, input: Vec) -> Result<(), PinError> { let jwk_pub = tpm_objects::get_tpm2b_public(jwk_result.out_public)?; - let hdr: biscuit::jwe::Header = biscuit::jwe::Header { - registered: biscuit::jwe::RegisteredHeader { - cek_algorithm: biscuit::jwa::KeyManagementAlgorithm::DirectSymmetricKey, - enc_algorithm: biscuit::jwa::ContentEncryptionAlgorithm::A256GCM, - compression_algorithm: None, - media_type: None, - content_type: None, - web_key_url: None, - web_key: None, - key_id: None, - x509_url: None, - x509_chain: None, - x509_fingerprint: None, - critical: None, - }, - cek_algorithm: biscuit::jwe::CekAlgorithmHeader { - nonce: None, - tag: None, - }, - private: ClevisHeader { - clevis: ClevisInner { - pin: pin_type.to_string(), - tpm2: Tpm2Inner { - hash: cfg.hash.as_ref().unwrap_or(&"sha256".to_string()).clone(), - key: key_type.to_string(), - jwk_pub, - jwk_priv, - pcr_bank: cfg.pcr_bank.clone(), - pcr_ids: cfg.get_pcr_ids_str(), - policy_pubkey_path: cfg.policy_pubkey_path, - policy_ref: cfg.policy_ref, - policy_path: cfg.policy_path, - }, - }, + let private_hdr = ClevisInner { + pin: pin_type.to_string(), + tpm2: Tpm2Inner { + hash: cfg.hash.as_ref().unwrap_or(&"sha256".to_string()).clone(), + key: key_type.to_string(), + jwk_pub, + jwk_priv, + pcr_bank: cfg.pcr_bank.clone(), + pcr_ids: cfg.get_pcr_ids_str(), + policy_pubkey_path: cfg.policy_pubkey_path, + policy_ref: cfg.policy_ref, + policy_path: cfg.policy_path, }, }; - let rand_nonce = ctx.get_random(12)?; - let jwe_enc_options = biscuit::jwa::EncryptionOptions::AES_GCM { - nonce: rand_nonce.value().to_vec(), - }; + let mut hdr = josekit::jwe::JweHeader::new(); + hdr.set_algorithm(Dir.name()); + hdr.set_content_encryption(A256GCM.name()); + hdr.set_claim( + "clevis", + Some(serde_json::value::to_value(private_hdr).context("Error serializing private header")?), + ) + .context("Error adding clevis claim")?; - let jwe_token = biscuit::jwe::Compact::new_decrypted(hdr, input); - let jwe_token_compact = jwe_token.encrypt(&jwk, &jwe_enc_options)?; - let encoded_token = jwe_token_compact.encrypted()?.encode(); - io::stdout().write_all(encoded_token.as_bytes())?; + let encrypter = Dir + .encrypter_from_jwk(&jwk) + .context("Error creating direct encrypter")?; + let jwe_token = josekit::jwe::serialize_compact(&input, &hdr, &encrypter) + .context("Error serializing JWE token")?; + + io::stdout().write_all(jwe_token.as_bytes())?; Ok(()) } @@ -276,9 +140,9 @@ impl Tpm2Inner { } impl TryFrom<&Tpm2Inner> for TPMPolicyStep { - type Error = PinError; + type Error = Error; - fn try_from(cfg: &Tpm2Inner) -> Result { + fn try_from(cfg: &Tpm2Inner) -> Result { if cfg.pcr_ids.is_some() && cfg.policy_pubkey_path.is_some() { Ok(TPMPolicyStep::Or([ Box::new(TPMPolicyStep::PCRs( @@ -322,31 +186,24 @@ struct ClevisInner { tpm2: Tpm2Inner, } -#[derive(Debug, Serialize, Deserialize, Clone)] -struct ClevisHeader { - clevis: ClevisInner, -} +fn perform_decrypt(input: Vec) -> Result<()> { + let input = String::from_utf8(input).context("Error reading input")?; + let hdr = josekit::jwt::decode_header(&input).context("Error decoding header")?; + let hdr_clevis = hdr.claim("clevis").context("Error getting clevis claim")?; + let hdr_clevis: ClevisInner = + serde_json::from_value(hdr_clevis.clone()).context("Error deserializing clevis header")?; -impl CompactJson for Tpm2Inner {} -impl CompactJson for ClevisHeader {} -impl CompactJson for ClevisInner {} - -fn perform_decrypt(input: Vec) -> Result<(), PinError> { - let input = String::from_utf8(input).map_err(PinError::FromUtf8)?; - let token = biscuit::Compact::decode(input.trim()); - let hdr: biscuit::jwe::Header = token.part(0)?; - - if hdr.private.clevis.pin != "tpm2" && hdr.private.clevis.pin != "tpm2plus" { - return Err(PinError::Text("JWE pin mismatch")); + if hdr_clevis.pin != "tpm2" && hdr_clevis.pin != "tpm2plus" { + bail!("JWE pin mismatch"); } - let jwkpub = tpm_objects::build_tpm2b_public(&hdr.private.clevis.tpm2.jwk_pub)?; - let jwkpriv = tpm_objects::build_tpm2b_private(&hdr.private.clevis.tpm2.jwk_priv)?; + let jwkpub = tpm_objects::build_tpm2b_public(&hdr_clevis.tpm2.jwk_pub)?; + let jwkpriv = tpm_objects::build_tpm2b_private(&hdr_clevis.tpm2.jwk_priv)?; - let policy = TPMPolicyStep::try_from(&hdr.private.clevis.tpm2)?; + let policy = TPMPolicyStep::try_from(&hdr_clevis.tpm2)?; - let name_alg = crate::utils::get_hash_alg_from_name(Some(&hdr.private.clevis.tpm2.hash)); - let key_public = tpm_objects::get_key_public(hdr.private.clevis.tpm2.key.as_str(), name_alg)?; + let name_alg = crate::utils::get_hash_alg_from_name(Some(&hdr_clevis.tpm2.hash)); + let key_public = tpm_objects::get_key_public(hdr_clevis.tpm2.key.as_str(), name_alg)?; let mut ctx = utils::get_tpm2_ctx()?; let key_handle = utils::get_tpm2_primary_key(&mut ctx, &key_public)?; @@ -358,20 +215,16 @@ fn perform_decrypt(input: Vec) -> Result<(), PinError> { let unsealed = ctx.execute_with_session(policy_session, |ctx| ctx.unseal(key.into()))?; let unsealed = &unsealed.value(); - let unsealed = std::str::from_utf8(unsealed)?; - let jwk: biscuit::jwk::JWK = serde_json::from_str(unsealed)?; + let mut jwk = josekit::jwk::Jwk::from_bytes(unsealed).context("Error unmarshaling JWK")?; + jwk.set_algorithm(Dir.name()); + let decrypter = Dir + .decrypter_from_jwk(&jwk) + .context("Error creating decrypter")?; - let token: biscuit::jwe::Compact, biscuit::Empty> = jwe::Compact::Encrypted(token); + let (payload, _) = + josekit::jwe::deserialize_compact(&input, &decrypter).context("Error decrypting JWE")?; - let token = token.decrypt( - &jwk, - biscuit::jwa::KeyManagementAlgorithm::DirectSymmetricKey, - biscuit::jwa::ContentEncryptionAlgorithm::A256GCM, - )?; - // We just decrypted the token, there should be a payload - let payload = token.payload()?; - - io::stdout().write_all(payload)?; + io::stdout().write_all(&payload)?; Ok(()) } @@ -411,7 +264,7 @@ This command uses the following configuration properties: std::process::exit(2); } -fn main() { +fn main() -> Result<()> { let args: Vec = env::args().collect(); let (mode, cfg) = match cli::get_mode_and_cfg(&args) { Err(e) => { @@ -422,8 +275,8 @@ fn main() { }; match mode { - cli::ActionMode::Summary => return print_summary(), - cli::ActionMode::Help => return print_help(), + cli::ActionMode::Summary => return Ok(print_summary()), + cli::ActionMode::Help => return Ok(print_help()), _ => {} }; @@ -433,13 +286,10 @@ fn main() { std::process::exit(1); } - if let Err(e) = match mode { + match mode { cli::ActionMode::Encrypt => perform_encrypt(cfg.unwrap(), input), cli::ActionMode::Decrypt => perform_decrypt(input), - cli::ActionMode::Summary => panic!("Summary was already handled supposedly"), - cli::ActionMode::Help => panic!("Help was already handled supposedly"), - } { - eprintln!("Error executing command: {}", e); - std::process::exit(2); + cli::ActionMode::Summary => unreachable!(), + cli::ActionMode::Help => unreachable!(), } } diff --git a/src/tpm_objects.rs b/src/tpm_objects.rs index ed1acc5..79e0806 100644 --- a/src/tpm_objects.rs +++ b/src/tpm_objects.rs @@ -1,5 +1,6 @@ use std::convert::TryFrom; +use anyhow::{anyhow, bail, Result}; use tss_esapi::attributes::object::ObjectAttributesBuilder; use tss_esapi::constants::tss as tss_constants; use tss_esapi::interface_types::ecc::EccCurve; @@ -12,12 +13,10 @@ type Sizedu = u64; #[cfg(target_pointer_width = "32")] type Sizedu = u32; -use crate::PinError; - pub(super) fn get_key_public( key_type: &str, name_alg: HashingAlgorithm, -) -> Result { +) -> Result { match key_type { "ecc" => Ok(create_restricted_ecc_public()), "rsa" => Ok(tss_esapi::utils::create_restricted_decryption_rsa_public( @@ -25,8 +24,9 @@ pub(super) fn get_key_public( 2048, 0, )?), - _ => Err(PinError::Text("Unsupported key type used")), - }.map(|mut public| { + _ => Err(anyhow!("Unsupported key type used")), + } + .map(|mut public| { public.publicArea.nameAlg = name_alg.into(); public }) @@ -34,7 +34,7 @@ pub(super) fn get_key_public( pub(super) fn create_tpm2b_public_sealed_object( policy: Option, -) -> Result { +) -> Result { let mut object_attributes = ObjectAttributesBuilder::new() .with_fixed_tpm(true) .with_fixed_parent(true) @@ -65,9 +65,7 @@ pub(super) fn create_tpm2b_public_sealed_object( }) } -pub(super) fn get_tpm2b_public( - val: tss_esapi::tss2_esys::TPM2B_PUBLIC, -) -> Result, PinError> { +pub(super) fn get_tpm2b_public(val: tss_esapi::tss2_esys::TPM2B_PUBLIC) -> Result> { let mut offset = 0 as Sizedu; let mut resp = Vec::with_capacity((val.size + 4) as usize); @@ -79,7 +77,7 @@ pub(super) fn get_tpm2b_public( &mut offset, ); if res != 0 { - return Err(PinError::Text("Marshalling tpm2b_public failed")); + bail!("Marshalling tpm2b_public failed"); } resp.set_len(offset as usize); } @@ -87,9 +85,7 @@ pub(super) fn get_tpm2b_public( Ok(resp) } -pub(super) fn get_tpm2b_private( - val: tss_esapi::tss2_esys::TPM2B_PRIVATE, -) -> Result, PinError> { +pub(super) fn get_tpm2b_private(val: tss_esapi::tss2_esys::TPM2B_PRIVATE) -> Result> { let mut offset = 0 as Sizedu; let mut resp = Vec::with_capacity((val.size + 4) as usize); @@ -101,7 +97,7 @@ pub(super) fn get_tpm2b_private( &mut offset, ); if res != 0 { - return Err(PinError::Text("Marshalling tpm2b_private failed")); + bail!("Marshalling tpm2b_private failed"); } resp.set_len(offset as usize); } @@ -109,9 +105,7 @@ pub(super) fn get_tpm2b_private( Ok(resp) } -pub(super) fn build_tpm2b_private( - val: &[u8], -) -> Result { +pub(super) fn build_tpm2b_private(val: &[u8]) -> Result { let mut resp = tss_esapi::tss2_esys::TPM2B_PRIVATE::default(); let mut offset = 0 as Sizedu; @@ -123,16 +117,14 @@ pub(super) fn build_tpm2b_private( &mut resp, ); if res != 0 { - return Err(PinError::Text("Unmarshalling tpm2b_private failed")); + bail!("Unmarshalling tpm2b_private failed"); } } Ok(resp) } -pub(super) fn build_tpm2b_public( - val: &[u8], -) -> Result { +pub(super) fn build_tpm2b_public(val: &[u8]) -> Result { let mut resp = tss_esapi::tss2_esys::TPM2B_PUBLIC::default(); let mut offset = 0 as Sizedu; @@ -144,7 +136,7 @@ pub(super) fn build_tpm2b_public( &mut resp, ); if res != 0 { - return Err(PinError::Text("Unmarshalling tpm2b_public failed")); + bail!("Unmarshalling tpm2b_public failed"); } } diff --git a/src/utils.rs b/src/utils.rs index cbc6b15..5c99cd1 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,38 +2,40 @@ use std::env; use std::fs; use std::str::FromStr; +use anyhow::{Context as anyhow_context, Result}; +use serde::Deserialize; +use tpm2_policy::{PublicKey, SignedPolicyList, TPMPolicyStep}; use tss_esapi::{ handles::KeyHandle, interface_types::{algorithm::HashingAlgorithm, resource_handles::Hierarchy}, Context, Tcti, }; -use serde::Deserialize; - -use super::PinError; - -use tpm2_policy::{PublicKey, SignedPolicyList, TPMPolicyStep}; - pub(crate) fn get_authorized_policy_step( policy_pubkey_path: &str, policy_path: &Option, policy_ref: &Option, -) -> Result { +) -> Result { let policy_ref = match policy_ref { Some(policy_ref) => policy_ref.as_bytes().to_vec(), None => vec![], }; let signkey = { - let contents = fs::read_to_string(policy_pubkey_path)?; - serde_json::from_str::(&contents)? + let contents = + fs::read_to_string(policy_pubkey_path).context("Error reading policy signkey")?; + serde_json::from_str::(&contents) + .context("Error deserializing signing public key")? }; let policies = match policy_path { None => None, Some(policy_path) => { - let contents = fs::read_to_string(policy_path)?; - Some(serde_json::from_str::(&contents)?) + let contents = fs::read_to_string(policy_path).context("Error reading policy")?; + Some( + serde_json::from_str::(&contents) + .context("Error deserializing policy")?, + ) } }; @@ -53,7 +55,7 @@ pub(crate) fn get_hash_alg_from_name(name: Option<&String>) -> HashingAlgorithm "sha256" => HashingAlgorithm::Sha256, "sha384" => HashingAlgorithm::Sha384, "sha512" => HashingAlgorithm::Sha512, - _ => panic!(format!("Unsupported hash algo: {:?}", name)), + _ => panic!("Unsupported hash algo: {:?}", name), }, } } @@ -77,7 +79,7 @@ where }) } -pub(crate) fn get_tpm2_ctx() -> Result { +pub(crate) fn get_tpm2_ctx() -> Result { let tcti_path = match env::var("TCTI") { Ok(val) => val, Err(_) => { @@ -89,14 +91,14 @@ pub(crate) fn get_tpm2_ctx() -> Result { } }; - let tcti = Tcti::from_str(&tcti_path)?; - unsafe { Context::new(tcti) } + let tcti = Tcti::from_str(&tcti_path).context("Error parsing TCTI specification")?; + Context::new(tcti).context("Error initializing TPM2 context") } pub(crate) fn get_tpm2_primary_key( ctx: &mut Context, pub_template: &tss_esapi::tss2_esys::TPM2B_PUBLIC, -) -> Result { +) -> Result { ctx.execute_with_nullauth_session(|ctx| { ctx.create_primary(Hierarchy::Owner, pub_template, None, None, None, None) .map(|r| r.key_handle)