diff --git a/Cargo.lock b/Cargo.lock index 61ec0eea65b..feada33bfe0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2305,6 +2305,7 @@ dependencies = [ "ockam", "ockam_api", "ockam_core", + "ockam_identity", "ockam_multiaddr", "ockam_vault", "open", @@ -2312,6 +2313,7 @@ dependencies = [ "regex", "reqwest", "serde", + "serde_bare", "serde_json", "slug", "syntect", diff --git a/implementations/rust/ockam/ockam_command/Cargo.toml b/implementations/rust/ockam/ockam_command/Cargo.toml index 4afa574b819..4623afc927f 100644 --- a/implementations/rust/ockam/ockam_command/Cargo.toml +++ b/implementations/rust/ockam/ockam_command/Cargo.toml @@ -65,6 +65,7 @@ rand = "0.8" reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls-native-roots"] } serde = { version = "1", features = ["derive"] } serde_json = "1" +serde_bare = { version = "0.5.0", default-features = false, features = ["alloc"] } slug = "0.1" sysinfo = { version = "0.26", default-features = false } syntect = "5" @@ -85,6 +86,7 @@ ockam_api = { path = "../ockam_api", version = "0.19.0", features = ["std", "aut ockam_multiaddr = { path = "../ockam_multiaddr", version = "0.10.0", features = ["std"] } ockam_vault = { path = "../ockam_vault", version = "^0.66.0", features = ["storage"] } ockam_core = { path = "../ockam_core", version = "^0.70.0" } +ockam_identity = { path = "../ockam_identity", version = "^0.64.0" } [dev-dependencies] assert_cmd = "2" diff --git a/implementations/rust/ockam/ockam_command/src/identity/show.rs b/implementations/rust/ockam/ockam_command/src/identity/show.rs index 7adc1b012e5..18e01b28256 100644 --- a/implementations/rust/ockam/ockam_command/src/identity/show.rs +++ b/implementations/rust/ockam/ockam_command/src/identity/show.rs @@ -8,6 +8,7 @@ use core::fmt::Write; use ockam::Context; use ockam_api::nodes::models::identity::{LongIdentityResponse, ShortIdentityResponse}; use ockam_core::api::Request; +use ockam_identity::change_history::IdentityChangeHistory; #[derive(Clone, Debug, Args)] pub struct ShowCommand { @@ -45,7 +46,8 @@ async fn run_impl( impl Output for LongIdentityResponse<'_> { fn output(&self) -> anyhow::Result { let mut w = String::new(); - write!(w, "{}", hex::encode(self.identity.0.as_ref()))?; + let id: IdentityChangeHistory = serde_bare::from_slice(self.identity.0.as_ref())?; + write!(w, "{}", id)?; Ok(w) } } diff --git a/implementations/rust/ockam/ockam_core/src/vault/types.rs b/implementations/rust/ockam/ockam_core/src/vault/types.rs index c47d6247635..3bb531c39be 100644 --- a/implementations/rust/ockam/ockam_core/src/vault/types.rs +++ b/implementations/rust/ockam/ockam_core/src/vault/types.rs @@ -1,3 +1,4 @@ +use core::fmt; use cfg_if::cfg_if; use minicbor::{Decode, Encode}; use serde::{Deserialize, Serialize}; @@ -140,6 +141,12 @@ impl PublicKey { } } +impl fmt::Display for PublicKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?} {}", self.stype(), hex::encode(self.data())) + } +} + /// Binary representation of Signature. #[derive(Serialize, Deserialize, Clone, Debug, Zeroize)] pub struct Signature(SignatureVec); @@ -235,6 +242,18 @@ impl SecretAttributes { } } +impl fmt::Display for SecretAttributes { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{:?}({:?}) len:{}", + self.stype(), + self.persistence(), + self.length() + ) + } +} + /// A public key #[derive(Clone, Debug, Zeroize)] #[zeroize(drop)] diff --git a/implementations/rust/ockam/ockam_identity/src/change.rs b/implementations/rust/ockam/ockam_identity/src/change.rs index e0814de950e..260a3ff3bf5 100644 --- a/implementations/rust/ockam/ockam_identity/src/change.rs +++ b/implementations/rust/ockam/ockam_identity/src/change.rs @@ -1,3 +1,4 @@ +use core::fmt; use crate::ChangeIdentifier; use ockam_core::compat::vec::Vec; use ockam_core::vault::PublicKey; @@ -21,6 +22,15 @@ pub enum IdentityChange { RotateKey(RotateKeyChangeData), } +impl fmt::Display for IdentityChange { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + IdentityChange::CreateKey(data) => write!(f, " CreateKey:{}", data), + IdentityChange::RotateKey(data) => write!(f, " RotateKey:{}", data), + } + } +} + impl IdentityChange { pub(crate) fn has_label(&self, label: &str) -> bool { self.label() == label @@ -87,3 +97,14 @@ impl IdentitySignedChange { } } } + +impl fmt::Display for IdentitySignedChange { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!(f, " identifier: {}", self.identifier())?; + writeln!(f, " identity change: {}", self.change())?; + for s in self.signatures() { + writeln!(f, "signatures: {}", s)?; + } + Ok(()) + } +} diff --git a/implementations/rust/ockam/ockam_identity/src/change/create_key.rs b/implementations/rust/ockam/ockam_identity/src/change/create_key.rs index ea2bbb68d8a..28514b266af 100644 --- a/implementations/rust/ockam/ockam_identity/src/change/create_key.rs +++ b/implementations/rust/ockam/ockam_identity/src/change/create_key.rs @@ -1,3 +1,4 @@ +use core::fmt; use crate::change::{IdentityChange, IdentitySignedChange, Signature, SignatureType}; use crate::change_history::IdentityChangeHistory; use crate::IdentityError::InvalidInternalState; @@ -44,6 +45,18 @@ impl CreateKeyChangeData { } } +impl fmt::Display for CreateKeyChangeData { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "prev_change_id:{} key attibutes:{} public key:{}", + self.prev_change_id(), + self.key_attributes(), + self.public_key() + ) + } +} + impl Identity { async fn generate_key_if_needed( secret: Option<&KeyId>, diff --git a/implementations/rust/ockam/ockam_identity/src/change/rotate_key.rs b/implementations/rust/ockam/ockam_identity/src/change/rotate_key.rs index 294150324e6..4b4e52d7be8 100644 --- a/implementations/rust/ockam/ockam_identity/src/change/rotate_key.rs +++ b/implementations/rust/ockam/ockam_identity/src/change/rotate_key.rs @@ -1,3 +1,4 @@ +use core::fmt; use crate::change::{IdentityChange, IdentitySignedChange, Signature, SignatureType}; use crate::change_history::IdentityChangeHistory; use crate::{ChangeIdentifier, Identity, IdentityError, IdentityVault, KeyAttributes}; @@ -43,6 +44,18 @@ impl RotateKeyChangeData { } } +impl fmt::Display for RotateKeyChangeData { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "prev_change_id:{} key attibutes:{} public key:{}", + self.prev_change_id(), + self.key_attributes(), + self.public_key() + ) + } +} + impl Identity { /// Rotate key change pub(crate) async fn make_rotate_key_change( diff --git a/implementations/rust/ockam/ockam_identity/src/change_history.rs b/implementations/rust/ockam/ockam_identity/src/change_history.rs index c1c62c9578b..11c2fe13c4b 100644 --- a/implementations/rust/ockam/ockam_identity/src/change_history.rs +++ b/implementations/rust/ockam/ockam_identity/src/change_history.rs @@ -5,6 +5,7 @@ use crate::{ ChangeIdentifier, IdentityError, IdentityIdentifier, IdentityStateConst, IdentityVault, }; use core::cmp::Ordering; +use core::fmt; use minicbor::{Decode, Encode}; use ockam_core::compat::vec::Vec; use ockam_core::{allow, deny, Encodable, Result}; @@ -29,7 +30,31 @@ pub enum IdentityHistoryComparison { /// Full history of [`Identity`] changes. History and corresponding secret keys are enough to recreate [`Identity`] #[derive(Clone, Debug, Serialize, Deserialize)] -pub(crate) struct IdentityChangeHistory(Vec); +pub struct IdentityChangeHistory(Vec); + +impl fmt::Display for IdentityChangeHistory { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!(f, "Change History:")?; + for (i_num, ident) in self.0.iter().enumerate() { + let public_key = ident.change().public_key().unwrap(); + writeln!(f, " Change[{}]:", i_num)?; + writeln!(f, " identifier: {}", ident.identifier())?; + writeln!(f, " change:")?; + writeln!( + f, + " prev_change_identifier: {}", + ident.change().previous_change_identifier() + )?; + writeln!(f, " label: {}", ident.change().label())?; + writeln!(f, " public_key: {}", public_key)?; + writeln!(f, " signatures:")?; + for (sig_num, sig) in ident.signatures().iter().enumerate() { + writeln!(f, " [{}]: {}", sig_num, sig)?; + } + } + Ok(()) + } +} impl IdentityChangeHistory { pub fn export(&self) -> Result> { diff --git a/implementations/rust/ockam/ockam_identity/src/identifiers.rs b/implementations/rust/ockam/ockam_identity/src/identifiers.rs index 5c2b2d1c5a6..e1ab301b794 100644 --- a/implementations/rust/ockam/ockam_identity/src/identifiers.rs +++ b/implementations/rust/ockam/ockam_identity/src/identifiers.rs @@ -111,6 +111,11 @@ impl FromStr for IdentityIdentifier { /// Unique [`crate::IdentityChangeChange`] identifier, computed as SHA256 of the change data #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash)] pub struct ChangeIdentifier([u8; 32]); +impl Display for ChangeIdentifier { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", hex::encode(self.0)) + } +} impl AsRef<[u8]> for ChangeIdentifier { fn as_ref(&self) -> &[u8] { diff --git a/implementations/rust/ockam/ockam_identity/src/key_attributes.rs b/implementations/rust/ockam/ockam_identity/src/key_attributes.rs index 16b0f0f1b42..6f09556c8ad 100644 --- a/implementations/rust/ockam/ockam_identity/src/key_attributes.rs +++ b/implementations/rust/ockam/ockam_identity/src/key_attributes.rs @@ -1,3 +1,4 @@ +use core::fmt; use ockam_core::compat::string::String; use ockam_core::vault::{SecretPersistence, SecretType, CURVE25519_SECRET_LENGTH_U32}; use ockam_vault::SecretAttributes; @@ -39,3 +40,13 @@ impl KeyAttributes { } } } +impl fmt::Display for KeyAttributes { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + " label:{}, secrets:{}", + self.label(), + self.secret_attributes() + ) + } +} diff --git a/implementations/rust/ockam/ockam_identity/src/signature.rs b/implementations/rust/ockam/ockam_identity/src/signature.rs index f2a593a4438..303a84a9823 100644 --- a/implementations/rust/ockam/ockam_identity/src/signature.rs +++ b/implementations/rust/ockam/ockam_identity/src/signature.rs @@ -1,3 +1,4 @@ +use core::fmt; use ockam_core::vault::Signature as OckamVaultSignature; use serde::{Deserialize, Serialize}; @@ -36,3 +37,9 @@ impl Signature { Signature { stype, data } } } + +impl fmt::Display for Signature { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?} {}", self.stype(), hex::encode(self.data())) + } +}