From 0d609853a29d7ae0ad22d233fc76344a54e1b309 Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Fri, 14 May 2021 19:01:24 +0200 Subject: [PATCH] Adjust to Trussed object ID cleanup --- src/constants.rs | 4 +++- src/credential.rs | 14 ++++++-------- src/lib.rs | 32 ++++++++++++++++---------------- src/state.rs | 43 ++++++++++++++++++++----------------------- 4 files changed, 45 insertions(+), 48 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index 55c3384..25b09dc 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,5 +1,7 @@ +use trussed::types::{CertId, KeyId}; pub const FIDO2_UP_TIMEOUT: u32 = 30_000; pub const U2F_UP_TIMEOUT: u32 = 0_250; -pub const ATTESTATION_CERT_ID: u8 = 0; +pub const ATTESTATION_CERT_ID: CertId = CertId::from_special(0); +pub const ATTESTATION_KEY_ID: KeyId = KeyId::from_special(0); diff --git a/src/credential.rs b/src/credential.rs index 9fd49b6..6ebc65c 100644 --- a/src/credential.rs +++ b/src/credential.rs @@ -2,9 +2,7 @@ use core::convert::{TryFrom, TryInto}; use trussed::{ client, syscall, try_syscall, - types::{ - ObjectHandle, - }, + types::KeyId, }; pub(crate) use ctap_types::{ @@ -65,7 +63,7 @@ impl TryFrom for EncryptedSerializedCredential { #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] pub enum Key { - ResidentKey(ObjectHandle), + ResidentKey(KeyId), // THIS USED TO BE 92 NOW IT'S 96 or 97 or so... waddup? WrappedKey(Bytes), } @@ -87,14 +85,14 @@ pub struct CredentialData { // TODO(implement enums in cbor-deser): for all others, is a wrapped key // --> use above Key enum // #[serde(skip_serializing_if = "Option::is_none")] - // key_id: Option, + // key_id: Option, pub key: Key, // extensions pub hmac_secret: Option, pub cred_protect: Option, - // TODO: add `sig_counter: Option`, + // TODO: add `sig_counter: Option`, // and grant RKs a per-credential sig-counter. } @@ -170,7 +168,7 @@ impl Credential { pub fn id_using_hash<'a, T: client::Chacha8Poly1305>( &self, crypto: &mut T, - key_encryption_key: ObjectHandle, + key_encryption_key: KeyId, rp_id_hash: &Bytes32, ) -> Result @@ -191,7 +189,7 @@ impl Credential { pub fn id<'a, T: client::Chacha8Poly1305 + client::Sha256>( &self, trussed: &mut T, - key_encryption_key: ObjectHandle, + key_encryption_key: KeyId, ) -> Result { diff --git a/src/lib.rs b/src/lib.rs index af1dcaa..449df74 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,11 +10,11 @@ use trussed::{ client, syscall, try_syscall, Client as TrussedClient, types::{ + KeyId, KeySerialization, Mechanism, MediumData, Message, - ObjectHandle, SignatureSerialization, Location, }, @@ -661,7 +661,7 @@ where UP: UserPresence, }) } - fn decrypt_pin_hash_and_maybe_escalate(&mut self, shared_secret: ObjectHandle, pin_hash_enc: &Bytes) + fn decrypt_pin_hash_and_maybe_escalate(&mut self, shared_secret: KeyId, pin_hash_enc: &Bytes) -> Result<()> { let pin_hash = syscall!(self.trussed.decrypt_aes256cbc( @@ -695,7 +695,7 @@ where UP: UserPresence, Ok(()) } - fn decrypt_pin_check_length(&mut self, shared_secret: ObjectHandle, pin_enc: &[u8]) -> Result { + fn decrypt_pin_check_length(&mut self, shared_secret: KeyId, pin_enc: &[u8]) -> Result { // pin is expected to be filled with null bytes to length at least 64 if pin_enc.len() < 64 { // correct error? @@ -732,7 +732,7 @@ where UP: UserPresence, } } - fn verify_pin_auth(&mut self, shared_secret: ObjectHandle, data: &[u8], pin_auth: &Bytes) + fn verify_pin_auth(&mut self, shared_secret: KeyId, data: &[u8], pin_auth: &Bytes) -> Result<()> { let expected_pin_auth = syscall!(self.trussed.sign_hmacsha256(shared_secret, data)).signature; @@ -1321,11 +1321,11 @@ where UP: UserPresence, } #[inline(never)] - fn process_assertion_extensions(&mut self, - get_assertion_state: &state::ActiveGetAssertionData, - extensions: &ctap2::get_assertion::ExtensionsInput, + fn process_assertion_extensions(&mut self, + get_assertion_state: &state::ActiveGetAssertionData, + extensions: &ctap2::get_assertion::ExtensionsInput, _credential: &Credential, - credential_key_handle: ObjectHandle, + credential_key: KeyId, ) -> Result> { if let Some(hmac_secret) = &extensions.hmac_secret { @@ -1334,10 +1334,10 @@ where UP: UserPresence, // i.e. credRandom = HMAC(private_key, uv) let cred_random = syscall!(self.trussed.derive_key( Mechanism::HmacSha256, - credential_key_handle, + credential_key, Some(Bytes::try_from_slice(&[get_assertion_state.uv_performed as u8]).unwrap()), trussed::types::StorageAttributes::new().set_persistence(Location::Volatile) - )).key; + )).key; // Verify the auth tag, which uses the same process as the pinAuth let kek = self.state.runtime.generate_shared_secret(&mut self.trussed, &hmac_secret.key_agreement)?; @@ -1384,7 +1384,7 @@ where UP: UserPresence, } else { Ok(None) } - + } @@ -1736,7 +1736,7 @@ where UP: UserPresence, // let mut cred_protect_requested = CredentialProtectionPolicy::Optional; let mut cred_protect_requested = None; if let Some(extensions) = ¶meters.extensions { - + hmac_secret_requested = extensions.hmac_secret; if let Some(policy) = &extensions.cred_protect { @@ -1757,8 +1757,8 @@ where UP: UserPresence, false => Location::Volatile, }; - let private_key: ObjectHandle; - let public_key: ObjectHandle; + let private_key: KeyId; + let public_key: KeyId; let cose_public_key; match algorithm { SupportedAlgorithm::P256 => { @@ -2105,7 +2105,7 @@ where UP: UserPresence, } } -// fn get_or_create_counter_handle(trussed_client: &mut TrussedClient) -> Result { +// fn get_or_create_counter_handle(trussed_client: &mut TrussedClient) -> Result { // // there should be either 0 or 1 counters with this name. if not, it's a logic error. // let attributes = Attributes { @@ -2145,7 +2145,7 @@ where UP: UserPresence, // } // } -// fn get_or_create_counter_handle(trussed_client: &mut TrussedClient) -> Result { +// fn get_or_create_counter_handle(trussed_client: &mut TrussedClient) -> Result { // todo!("not implemented yet, follow counter code"); // } diff --git a/src/state.rs b/src/state.rs index 518f1cb..a707346 100644 --- a/src/state.rs +++ b/src/state.rs @@ -5,8 +5,7 @@ use trussed::{ Client as TrussedClient, types::{ self, - ObjectHandle as Key, - UniqueId, + KeyId, Location, Mechanism, }, @@ -78,7 +77,7 @@ impl State { pub struct Identity { // can this be [u8; 16] or need Bytes for serialization? // aaguid: Option>, - attestation_key: Option, + attestation_key: Option, } pub type Aaguid = [u8; 16]; @@ -120,17 +119,15 @@ impl Identity { Some(aaguid) } - pub fn attestation(&mut self, trussed: &mut T) -> (Option<(Key, Certificate)>, Aaguid) + pub fn attestation(&mut self, trussed: &mut T) -> (Option<(KeyId, Certificate)>, Aaguid) { - let key = Key { - object_id: UniqueId::from(0) - }; + let key = crate::constants::ATTESTATION_KEY_ID; let attestation_key_exists = syscall!(trussed.exists(Mechanism::P256, key)).exists; if attestation_key_exists { // Will panic if certificate does not exist. let cert = syscall!(trussed.read_certificate( - trussed::types::Id::from(crate::constants::ATTESTATION_CERT_ID), + crate::constants::ATTESTATION_CERT_ID )).der; let mut aaguid = self.yank_aaguid(&cert.as_slice()); @@ -166,10 +163,10 @@ pub struct ActiveGetAssertionData { #[derive(Clone, Debug, /*uDebug,*/ Default, /*PartialEq,*/ serde::Deserialize, serde::Serialize)] pub struct RuntimeState { - key_agreement_key: Option, - pin_token: Option, + key_agreement_key: Option, + pin_token: Option, // TODO: why is this field not used? - shared_secret: Option, + shared_secret: Option, consecutive_pin_mismatches: u8, // both of these are a cache for previous Get{Next,}Assertion call @@ -203,13 +200,13 @@ pub struct PersistentState { // We could alternatively make all methods take a TrussedClient as parameter initialised: bool, - key_encryption_key: Option, - key_wrapping_key: Option, + key_encryption_key: Option, + key_wrapping_key: Option, consecutive_pin_mismatches: u8, pin_hash: Option<[u8; 16]>, // Ideally, we'd dogfood a "Monotonic Counter" from trussed. // TODO: Add per-key counters for resident keys. - // counter: Option, + // counter: Option, timestamp: u32, } @@ -300,7 +297,7 @@ impl PersistentState { Ok(now) } - pub fn key_encryption_key(&mut self, trussed: &mut T) -> Result + pub fn key_encryption_key(&mut self, trussed: &mut T) -> Result { match self.key_encryption_key { Some(key) => Ok(key), @@ -308,7 +305,7 @@ impl PersistentState { } } - pub fn rotate_key_encryption_key(&mut self, trussed: &mut T) -> Result { + pub fn rotate_key_encryption_key(&mut self, trussed: &mut T) -> Result { if let Some(key) = self.key_encryption_key { syscall!(trussed.delete(key)); } let key = syscall!(trussed.generate_chacha8poly1305_key(Location::Internal)).key; self.key_encryption_key = Some(key); @@ -316,7 +313,7 @@ impl PersistentState { Ok(key) } - pub fn key_wrapping_key(&mut self, trussed: &mut T) -> Result + pub fn key_wrapping_key(&mut self, trussed: &mut T) -> Result { match self.key_wrapping_key { Some(key) => Ok(key), @@ -324,7 +321,7 @@ impl PersistentState { } } - pub fn rotate_key_wrapping_key(&mut self, trussed: &mut T) -> Result { + pub fn rotate_key_wrapping_key(&mut self, trussed: &mut T) -> Result { self.load_if_not_initialised(trussed); if let Some(key) = self.key_wrapping_key { syscall!(trussed.delete(key)); } let key = syscall!(trussed.generate_chacha8poly1305_key(Location::Internal)).key; @@ -450,14 +447,14 @@ impl RuntimeState { crate::Credential::deserialize(&data).unwrap() } - pub fn key_agreement_key(&mut self, trussed: &mut T) -> Key { + pub fn key_agreement_key(&mut self, trussed: &mut T) -> KeyId { match self.key_agreement_key { Some(key) => key, None => self.rotate_key_agreement_key(trussed), } } - pub fn rotate_key_agreement_key(&mut self, trussed: &mut T) -> Key { + pub fn rotate_key_agreement_key(&mut self, trussed: &mut T) -> KeyId { // TODO: need to rotate pin token? if let Some(key) = self.key_agreement_key { syscall!(trussed.delete(key)); @@ -472,14 +469,14 @@ impl RuntimeState { key } - pub fn pin_token(&mut self, trussed: &mut impl client::HmacSha256) -> Key { + pub fn pin_token(&mut self, trussed: &mut impl client::HmacSha256) -> KeyId { match self.pin_token { Some(token) => token, None => self.rotate_pin_token(trussed), } } - pub fn rotate_pin_token(&mut self, trussed: &mut T) -> Key { + pub fn rotate_pin_token(&mut self, trussed: &mut T) -> KeyId { // TODO: need to rotate key agreement key? if let Some(token) = self.pin_token { syscall!(trussed.delete(token)); } let token = syscall!(trussed.generate_secret_key(16, Location::Volatile)).key; @@ -499,7 +496,7 @@ impl RuntimeState { self.active_get_assertion = None; } - pub fn generate_shared_secret(&mut self, trussed: &mut T, platform_key_agreement_key: &CoseEcdhEsHkdf256PublicKey) -> Result { + pub fn generate_shared_secret(&mut self, trussed: &mut T, platform_key_agreement_key: &CoseEcdhEsHkdf256PublicKey) -> Result { let private_key = self.key_agreement_key(trussed); let serialized_pkak = cbor_serialize_message(platform_key_agreement_key).map_err(|_| Error::InvalidParameter)?;