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 <patrick@puiterwijk.org>
This commit is contained in:
Patrick Uiterwijk 2021-12-07 16:16:15 +01:00
parent 6bcb830067
commit 0767310e85
No known key found for this signature in database
GPG key ID: A0A847B80FBBFF4A
5 changed files with 114 additions and 274 deletions

View file

@ -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"

View file

@ -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<String>,
@ -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<Self, PinError> {
fn try_from(cfg: &TPM2Config) -> Result<Self> {
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<TPM2Config, PinError> {
fn normalize(mut self) -> Result<TPM2Config> {
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<TPM2Config>), PinError> {
pub(super) fn get_mode_and_cfg(args: &[String]) -> Result<(ActionMode, Option<TPM2Config>)> {
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<TPM2Config> = match cfgstr {

View file

@ -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<std::io::Error> for PinError {
fn from(err: std::io::Error) -> Self {
PinError::IO(err)
}
}
impl From<tpm2_policy::Error> 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<serde_json::Error> for PinError {
fn from(err: serde_json::Error) -> Self {
PinError::Serde(err)
}
}
impl From<tss_esapi::Error> for PinError {
fn from(err: tss_esapi::Error) -> Self {
PinError::TPM(err)
}
}
impl From<biscuit::errors::Error> for PinError {
fn from(err: biscuit::errors::Error) -> Self {
PinError::JWE(err)
}
}
impl From<base64::DecodeError> for PinError {
fn from(err: base64::DecodeError) -> Self {
PinError::Base64Decoding(err)
}
}
impl From<std::str::Utf8Error> for PinError {
fn from(err: std::str::Utf8Error) -> Self {
PinError::Utf8(err)
}
}
fn perform_encrypt(cfg: TPM2Config, input: Vec<u8>) -> Result<(), PinError> {
fn perform_encrypt(cfg: TPM2Config, input: Vec<u8>) -> 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<u8>) -> 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<u8>) -> Result<(), PinError> {
let jwk_pub = tpm_objects::get_tpm2b_public(jwk_result.out_public)?;
let hdr: biscuit::jwe::Header<ClevisHeader> = 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<Self, PinError> {
fn try_from(cfg: &Tpm2Inner) -> Result<Self> {
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<u8>) -> 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<u8>) -> Result<(), PinError> {
let input = String::from_utf8(input).map_err(PinError::FromUtf8)?;
let token = biscuit::Compact::decode(input.trim());
let hdr: biscuit::jwe::Header<ClevisHeader> = 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<u8>) -> 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<biscuit::Empty> = 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<Vec<u8>, 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<String> = 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!(),
}
}

View file

@ -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<tss_esapi::tss2_esys::TPM2B_PUBLIC, PinError> {
) -> Result<tss_esapi::tss2_esys::TPM2B_PUBLIC> {
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<Digest>,
) -> Result<tss_esapi::tss2_esys::TPM2B_PUBLIC, PinError> {
) -> Result<tss_esapi::tss2_esys::TPM2B_PUBLIC> {
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<Vec<u8>, PinError> {
pub(super) fn get_tpm2b_public(val: tss_esapi::tss2_esys::TPM2B_PUBLIC) -> Result<Vec<u8>> {
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<Vec<u8>, PinError> {
pub(super) fn get_tpm2b_private(val: tss_esapi::tss2_esys::TPM2B_PRIVATE) -> Result<Vec<u8>> {
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<tss_esapi::tss2_esys::TPM2B_PRIVATE, PinError> {
pub(super) fn build_tpm2b_private(val: &[u8]) -> Result<tss_esapi::tss2_esys::TPM2B_PRIVATE> {
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<tss_esapi::tss2_esys::TPM2B_PUBLIC, PinError> {
pub(super) fn build_tpm2b_public(val: &[u8]) -> Result<tss_esapi::tss2_esys::TPM2B_PUBLIC> {
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");
}
}

View file

@ -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<String>,
policy_ref: &Option<String>,
) -> Result<TPMPolicyStep, PinError> {
) -> Result<TPMPolicyStep> {
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::<PublicKey>(&contents)?
let contents =
fs::read_to_string(policy_pubkey_path).context("Error reading policy signkey")?;
serde_json::from_str::<PublicKey>(&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::<SignedPolicyList>(&contents)?)
let contents = fs::read_to_string(policy_path).context("Error reading policy")?;
Some(
serde_json::from_str::<SignedPolicyList>(&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<tss_esapi::Context, tss_esapi::Error> {
pub(crate) fn get_tpm2_ctx() -> Result<tss_esapi::Context> {
let tcti_path = match env::var("TCTI") {
Ok(val) => val,
Err(_) => {
@ -89,14 +91,14 @@ pub(crate) fn get_tpm2_ctx() -> Result<tss_esapi::Context, tss_esapi::Error> {
}
};
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<KeyHandle, PinError> {
) -> Result<KeyHandle> {
ctx.execute_with_nullauth_session(|ctx| {
ctx.create_primary(Hierarchy::Owner, pub_template, None, None, None, None)
.map(|r| r.key_handle)