diff --git a/shared/src/cred.rs b/shared/src/cred.rs index 393816c9..ac0ed777 100644 --- a/shared/src/cred.rs +++ b/shared/src/cred.rs @@ -39,9 +39,18 @@ impl From for IdCredType { } } -/// A value of ID_CRED_x: a credential identifier +/// A value of ID_CRED_x: a credential identifier. /// /// Possible values include key IDs, credentials by value and others. +/// +/// ```rust +/// # use hexlit::hex; +/// # use lakers_shared::IdCred; +/// let short_kid = IdCred::from_encoded_value(&hex!("17")).unwrap(); // 23 +/// assert_eq!(short_kid.as_full_value(), &hex!("a1044117")); // {4: h'17'} +/// let long_kid = IdCred::from_encoded_value(&hex!("43616263")).unwrap(); // 'abc' +/// assert_eq!(long_kid.as_full_value(), &hex!("a10443616263")); // {4: 'abc'} +/// ``` #[derive(Clone, Copy, Debug, Default, PartialEq)] #[repr(C)] pub struct IdCred { @@ -73,8 +82,21 @@ impl IdCred { BufferIdCred::new_from_slice(&[0xa1, KID_LABEL, 0x41, x]) .map_err(|_| EDHOCError::CredentialTooLongError)? // TODO: how to avoid map_err overuse? } - // kid that has been encoded as CBOR byte string - &[0x41, x, ..] if !Self::bstr_representable_as_int(x) => { + // kid that has been encoded as CBOR byte string; supporting up to 23 long because + // those are easy + &[0x40..=0x57, ..] => { + let tail = &value[1..]; + if let &[single_byte] = tail { + if Self::bstr_representable_as_int(single_byte) { + // We require precise encoding + return Err(EDHOCError::ParsingError); + } + } + if usize::from(value[0] - 0x40) != tail.len() { + // Missing or trailing bytes. This is impossible when called from within Lakers + // where the value is a `.any_as_encoded()`. + return Err(EDHOCError::ParsingError); + } let mut bytes = BufferIdCred::new_from_slice(&[0xa1, KID_LABEL]) .map_err(|_| EDHOCError::CredentialTooLongError)?; bytes @@ -83,7 +105,7 @@ impl IdCred { bytes } // CCS by value - &[0xa1, KCSS_LABEL, ..] => BufferIdCred::new_from_slice(value) + &[0xa1, KCCS_LABEL, ..] => BufferIdCred::new_from_slice(value) .map_err(|_| EDHOCError::CredentialTooLongError)?, _ => return Err(EDHOCError::ParsingError), }; @@ -304,7 +326,7 @@ impl Credential { let mut id_cred = IdCred::new(); id_cred .bytes - .extend_from_slice(&[CBOR_MAJOR_MAP + 1, KCSS_LABEL]) + .extend_from_slice(&[CBOR_MAJOR_MAP + 1, KCCS_LABEL]) .map_err(|_| EDHOCError::CredentialTooLongError)?; id_cred .bytes diff --git a/shared/src/lib.rs b/shared/src/lib.rs index b7155f0f..556962bf 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -82,7 +82,9 @@ pub const MAX_INFO_LEN: usize = 2 + SHA256_DIGEST_LEN + // 32-byte digest as bst 1 + MAX_KDF_CONTEXT_LEN + // context <24 bytes as bstr 1; // length as u8 -pub const KCSS_LABEL: u8 = 14; +pub const KCCS_LABEL: u8 = 14; +#[deprecated(note = "Typo for KCCS_LABEL")] +pub const KCSS_LABEL: u8 = KCCS_LABEL; pub const KID_LABEL: u8 = 4; pub const ENC_STRUCTURE_LEN: usize = 8 + 5 + SHA256_DIGEST_LEN; // 8 for ENCRYPT0