From 68a3fc96de09872a043e26fd13d0dde0c11cc971 Mon Sep 17 00:00:00 2001 From: Chris Frantz Date: Thu, 13 Jul 2023 14:14:02 -0700 Subject: [PATCH] [hsmtool] Improve attribute redactions When showing objects, manually redact private key components. The HSM normally redacts these, however, if you have extractable keys, the show command might dump their contents to the console. By default, we'll redact these components to avoid accidentally exposing private key material. Signed-off-by: Chris Frantz --- sw/host/hsmtool/src/commands/object/show.rs | 29 +++++++++++++++++++-- sw/host/hsmtool/src/util/attribute/attr.rs | 13 +++++++-- sw/host/hsmtool/src/util/attribute/data.rs | 7 +++++ sw/host/hsmtool/src/util/attribute/mod.rs | 2 +- 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/sw/host/hsmtool/src/commands/object/show.rs b/sw/host/hsmtool/src/commands/object/show.rs index 430820796f4a3..23494b80ab206 100644 --- a/sw/host/hsmtool/src/commands/object/show.rs +++ b/sw/host/hsmtool/src/commands/object/show.rs @@ -7,11 +7,12 @@ use cryptoki::session::Session; use serde::{Deserialize, Serialize}; use serde_annotate::Annotate; use std::any::Any; +use std::collections::HashSet; use crate::commands::Dispatch; use crate::error::HsmError; use crate::module::Module; -use crate::util::attribute::AttributeMap; +use crate::util::attribute::{AttributeMap, AttributeType}; use crate::util::helper; #[derive(clap::Args, Debug, Serialize, Deserialize)] @@ -20,6 +21,12 @@ pub struct Show { id: Option, #[arg(short, long)] label: Option, + #[arg(long, + action = clap::ArgAction::Set, + default_value = "true", + help="Redact senitive data", + )] + redact: bool, } #[derive(Default, Debug, Serialize, Deserialize)] @@ -27,6 +34,21 @@ pub struct ShowResult { pub objects: Vec, } +impl Show { + fn redactions() -> HashSet { + // TODO: Add attributes to this list depending on the type of + // object being shown. + HashSet::from([ + AttributeType::PrivateExponent, + AttributeType::Prime1, + AttributeType::Prime2, + AttributeType::Exponent1, + AttributeType::Exponent2, + AttributeType::Coefficient, + ]) + } +} + #[typetag::serde(name = "object-show")] impl Dispatch for Show { fn run( @@ -40,7 +62,10 @@ impl Dispatch for Show { let objects = session.find_objects(&attr)?; let mut result = Box::::default(); for object in objects { - let map = AttributeMap::from_object(session, object)?; + let mut map = AttributeMap::from_object(session, object)?; + if self.redact { + map.redact(&Self::redactions()); + } result.objects.push(map); } Ok(result) diff --git a/sw/host/hsmtool/src/util/attribute/attr.rs b/sw/host/hsmtool/src/util/attribute/attr.rs index 6dc1e91420847..c0c79773623ca 100644 --- a/sw/host/hsmtool/src/util/attribute/attr.rs +++ b/sw/host/hsmtool/src/util/attribute/attr.rs @@ -8,10 +8,10 @@ use cryptoki::session::Session; use indexmap::IndexMap; use once_cell::sync::OnceCell; use serde::{Deserialize, Serialize}; +use std::collections::HashSet; use std::str::FromStr; use strum::IntoEnumIterator; -use super::AttrData; use super::AttributeError; use super::AttributeType; use super::CertificateType; @@ -19,6 +19,7 @@ use super::Date; use super::KeyType; use super::MechanismType; use super::ObjectClass; +use super::{AttrData, Redacted}; /// Converts a cryptoki `Attribute` into a key-value pair of /// `(AttributeType, AttrData)`. This allows converting HSM @@ -285,6 +286,14 @@ impl AttributeMap { } } + pub fn redact(&mut self, redactions: &HashSet) { + for (k, v) in self.0.iter_mut() { + if redactions.contains(k) && !matches!(v, AttrData::Redacted(_)) { + *v = AttrData::Redacted(Redacted::RedactedByTool); + } + } + } + /// Retrieves an object from the PKCS#11 interface as an `AttributeMap`. pub fn from_object(session: &Session, object: ObjectHandle) -> Result { let all = Self::all(); @@ -299,7 +308,7 @@ impl AttributeMap { let mut map = AttributeMap::from(attrs.as_slice()); for (&a, i) in all.iter().zip(info.iter()) { if matches!(i, AttributeInfo::Sensitive) { - map.insert(a.into(), AttrData::None); + map.insert(a.into(), AttrData::Redacted(Redacted::RedactedByHsm)); } } Ok(map) diff --git a/sw/host/hsmtool/src/util/attribute/data.rs b/sw/host/hsmtool/src/util/attribute/data.rs index 5d5297428a7d8..61e7c5775e120 100644 --- a/sw/host/hsmtool/src/util/attribute/data.rs +++ b/sw/host/hsmtool/src/util/attribute/data.rs @@ -13,6 +13,12 @@ use crate::util::attribute::{ }; use crate::util::escape::{as_hex, escape, unescape}; +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub enum Redacted { + RedactedByHsm, + RedactedByTool, +} + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)] #[serde(untagged)] pub enum AttrData { @@ -24,6 +30,7 @@ pub enum AttrData { KeyType(KeyType), MechanismType(MechanismType), ObjectClass(ObjectClass), + Redacted(Redacted), Str(String), List(Vec), } diff --git a/sw/host/hsmtool/src/util/attribute/mod.rs b/sw/host/hsmtool/src/util/attribute/mod.rs index fb83f981668e6..abe90a5e62889 100644 --- a/sw/host/hsmtool/src/util/attribute/mod.rs +++ b/sw/host/hsmtool/src/util/attribute/mod.rs @@ -46,7 +46,7 @@ mod mechanism_type; mod object_class; pub use attr::AttributeMap; -pub use data::AttrData; +pub use data::{AttrData, Redacted}; pub use error::AttributeError; pub use attribute_type::AttributeType;