From 6cd9e32e1e7272a52de6b703faac74d9159dfe15 Mon Sep 17 00:00:00 2001 From: Geovane Fedrecheski Date: Thu, 29 Feb 2024 17:09:19 +0100 Subject: [PATCH 1/2] refactor: use CredentialRPK instead of IdCredOwned --- lib/src/edhoc.rs | 20 +++++++++++++------ lib/src/lib.rs | 49 ++++++++++++++++++---------------------------- shared/src/cred.rs | 4 ++++ shared/src/lib.rs | 6 ------ 4 files changed, 37 insertions(+), 42 deletions(-) diff --git a/lib/src/edhoc.rs b/lib/src/edhoc.rs index d1c3aa6d..082c676f 100644 --- a/lib/src/edhoc.rs +++ b/lib/src/edhoc.rs @@ -155,7 +155,7 @@ pub fn r_parse_message_3( state: &mut WaitM3, crypto: &mut impl CryptoTrait, message_3: &BufferMessage3, -) -> Result<(ProcessingM3, IdCredOwned, Option), EDHOCError> { +) -> Result<(ProcessingM3, CredentialRPK, Option), EDHOCError> { let plaintext_3 = decrypt_message_3(crypto, &state.prk_3e2m, &state.th_3, message_3); if let Ok(plaintext_3) = plaintext_3 { @@ -163,12 +163,16 @@ pub fn r_parse_message_3( if let Ok((id_cred_i, mac_3, ead_3)) = decoded_p3_res { let id_cred_i = match id_cred_i { - IdCred::CompactKid(kid) => IdCredOwned::CompactKid(kid), + IdCred::CompactKid(kid) => CredentialRPK { + value: Default::default(), + public_key: Default::default(), + kid, + }, IdCred::FullCredential(cred) => { let Ok(buffer) = EdhocMessageBuffer::new_from_slice(cred) else { return Err(EDHOCError::ParsingError); }; - IdCredOwned::FullCredential(buffer) + CredentialRPK::new(buffer)? } }; @@ -298,7 +302,7 @@ pub fn i_parse_message_2<'a>( state: &WaitM2, crypto: &mut impl CryptoTrait, message_2: &BufferMessage2, -) -> Result<(ProcessingM2, u8, IdCredOwned, Option), EDHOCError> { +) -> Result<(ProcessingM2, u8, CredentialRPK, Option), EDHOCError> { let res = parse_message_2(message_2); if let Ok((g_y, ciphertext_2)) = res { let th_2 = compute_th_2(crypto, &g_y, &state.h_message_1); @@ -324,12 +328,16 @@ pub fn i_parse_message_2<'a>( }; let id_cred_r = match id_cred_r { - IdCred::CompactKid(kid) => IdCredOwned::CompactKid(kid), + IdCred::CompactKid(kid) => CredentialRPK { + value: Default::default(), + public_key: Default::default(), + kid, + }, IdCred::FullCredential(cred) => { let Ok(buffer) = EdhocMessageBuffer::new_from_slice(cred) else { return Err(EDHOCError::ParsingError); }; - IdCredOwned::FullCredential(buffer) + CredentialRPK::new(buffer)? } }; diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 0fa3c602..d668ddef 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -162,7 +162,7 @@ impl<'a, Crypto: CryptoTrait> EdhocResponderWaitM3 { ) -> Result< ( EdhocResponderProcessingM3, - IdCredOwned, + CredentialRPK, Option, ), EDHOCError, @@ -290,7 +290,7 @@ impl<'a, Crypto: CryptoTrait> EdhocInitiatorWaitM2 { ( EdhocInitiatorProcessingM2, u8, - IdCredOwned, + CredentialRPK, Option, ), EDHOCError, @@ -423,7 +423,7 @@ pub fn generate_connection_identifier(crypto: &mut Crypto) // Implements auth credential checking according to draft-tiloca-lake-implem-cons pub fn credential_check_or_fetch<'a>( cred_expected: Option, - id_cred_received: IdCredOwned, + id_cred_received: CredentialRPK, ) -> Result { // Processing of auth credentials according to draft-tiloca-lake-implem-cons // Comments tagged with a number refer to steps in Section 4.3.1. of draft-tiloca-lake-implem-cons @@ -431,9 +431,10 @@ pub fn credential_check_or_fetch<'a>( // 1. Does ID_CRED_X point to a stored authentication credential? YES // IMPL: compare cred_i_expected with id_cred // IMPL: assume cred_i_expected is well formed - let credentials_match = match id_cred_received { - IdCredOwned::CompactKid(kid_received) => kid_received == cred_expected.kid, - IdCredOwned::FullCredential(cred_received) => cred_received == cred_expected.value, + let credentials_match = if id_cred_received.reference_only() { + id_cred_received.kid == cred_expected.kid + } else { + id_cred_received.value == cred_expected.value }; // 2. Is this authentication credential still valid? @@ -451,30 +452,18 @@ pub fn credential_check_or_fetch<'a>( // 1. Does ID_CRED_X point to a stored authentication credential? NO // IMPL: cred_i_expected provided by application is None // id_cred must be a full credential - if let IdCredOwned::FullCredential(cred_received) = id_cred_received { - // 3. Is the trust model Pre-knowledge-only? NO (hardcoded to NO for now) - - // 4. Is the trust model Pre-knowledge + TOFU? YES (hardcoded to YES for now) - - // 6. Validate CRED_X. Generally a CCS has to be validated only syntactically and semantically, unlike a certificate or a CWT. - // Is the validation successful? - // IMPL: parse_cred(cred_r) and check it is valid - match CredentialRPK::new(cred_received) { - Ok(cred_received) => { - // 5. Is the authentication credential authorized for use in the context of this EDHOC session? - // IMPL,TODO: we just skip this step for now - - // 7. Store CRED_X as valid and trusted. - // Pair it with consistent credential identifiers, for each supported type of credential identifier. - // IMPL: cred_r = id_cred - Ok(cred_received) - } - Err(_) => Err(EDHOCError::UnknownPeer), - } - } else { - // IMPL: should have gotten a full credential - Err(EDHOCError::UnknownPeer) - } + // 3. Is the trust model Pre-knowledge-only? NO (hardcoded to NO for now) + // 4. Is the trust model Pre-knowledge + TOFU? YES (hardcoded to YES for now) + // 6. Validate CRED_X. Generally a CCS has to be validated only syntactically and semantically, unlike a certificate or a CWT. + // Is the validation successful? + // IMPL,NOTE: the credential has already been parsed with CredentialRPK::new in the *_parse_message_* function + // 5. Is the authentication credential authorized for use in the context of this EDHOC session? + // IMPL,TODO: we just skip this step for now + // 7. Store CRED_X as valid and trusted. + // Pair it with consistent credential identifiers, for each supported type of credential identifier. + + assert!(!id_cred_received.reference_only()); + Ok(id_cred_received) } // 8. Is this authentication credential good to use in the context of this EDHOC session? diff --git a/shared/src/cred.rs b/shared/src/cred.rs index 239ccb17..73a6a5a7 100644 --- a/shared/src/cred.rs +++ b/shared/src/cred.rs @@ -18,6 +18,10 @@ impl CredentialRPK { }) } + pub fn reference_only(&self) -> bool { + self.value.len == 0 + } + pub fn get_id_cred(&self) -> BytesIdCred { [0xa1, 0x04, 0x41, self.kid] // cbor map = {4: kid} } diff --git a/shared/src/lib.rs b/shared/src/lib.rs index 1b3bbf94..6d536d98 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -351,12 +351,6 @@ pub enum IdCred<'a> { FullCredential(&'a [u8]), } -#[derive(Debug, Clone, Copy)] -pub enum IdCredOwned { - CompactKid(u8), - FullCredential(EdhocMessageBuffer), -} - mod helpers { use super::*; From c75dd179277cd4bde3012e48c85e96fc8c02264f Mon Sep 17 00:00:00 2001 From: Geovane Fedrecheski Date: Thu, 29 Feb 2024 17:11:47 +0100 Subject: [PATCH 2/2] refactor: remove IdCredOwned in python --- lakers-python/src/initiator.rs | 7 ++++--- lakers-python/src/lib.rs | 13 ++++++++++--- lakers-python/src/responder.rs | 7 ++++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/lakers-python/src/initiator.rs b/lakers-python/src/initiator.rs index 6de7f477..ea3c7a42 100644 --- a/lakers-python/src/initiator.rs +++ b/lakers-python/src/initiator.rs @@ -66,9 +66,10 @@ impl PyEdhocInitiator { match i_parse_message_2(&self.wait_m2, &mut default_crypto(), &message_2) { Ok((state, c_r, id_cred_r, ead_2)) => { self.processing_m2 = state; - let id_cred_r = match id_cred_r { - IdCredOwned::CompactKid(kid) => Vec::from([kid]), - IdCredOwned::FullCredential(cred) => Vec::from(cred.as_slice()), + let id_cred_r = if id_cred_r.reference_only() { + Vec::from([id_cred_r.kid]) + } else { + Vec::from(id_cred_r.value.as_slice()) }; Ok((c_r, id_cred_r, ead_2)) } diff --git a/lakers-python/src/lib.rs b/lakers-python/src/lib.rs index 53d0cbd3..d8828f9e 100644 --- a/lakers-python/src/lib.rs +++ b/lakers-python/src/lib.rs @@ -29,13 +29,20 @@ pub fn py_credential_check_or_fetch<'a>( None }; let valid_cred = if id_cred_received.len() == 1 { - credential_check_or_fetch(cred_expected, IdCredOwned::CompactKid(id_cred_received[0]))? + credential_check_or_fetch( + cred_expected, + CredentialRPK { + kid: id_cred_received[0], + value: Default::default(), + public_key: Default::default(), + }, + )? } else { credential_check_or_fetch( cred_expected, - IdCredOwned::FullCredential( + CredentialRPK::new( EdhocMessageBuffer::new_from_slice(id_cred_received.as_slice()).unwrap(), - ), + )?, )? }; Ok(PyBytes::new(py, valid_cred.value.as_slice())) diff --git a/lakers-python/src/responder.rs b/lakers-python/src/responder.rs index cfc6f580..99f836ca 100644 --- a/lakers-python/src/responder.rs +++ b/lakers-python/src/responder.rs @@ -77,9 +77,10 @@ impl PyEdhocResponder { match r_parse_message_3(&mut self.wait_m3, &mut default_crypto(), &message_3) { Ok((state, id_cred_i, ead_3)) => { self.processing_m3 = state; - let id_cred_i = match id_cred_i { - IdCredOwned::CompactKid(kid) => Vec::from([kid]), - IdCredOwned::FullCredential(cred) => Vec::from(cred.as_slice()), + let id_cred_i = if id_cred_i.reference_only() { + Vec::from([id_cred_i.kid]) + } else { + Vec::from(id_cred_i.value.as_slice()) }; Ok((id_cred_i, ead_3)) }