From d3d65d64767d8453716b30f6ebcbb22f0005d64b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Mart=C3=ADn?= Date: Tue, 27 Feb 2024 12:58:14 +0100 Subject: [PATCH] fix(data-formats): use correct CBOR serializer for Error messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use `serde_tuple` to serialize/deserialize the error messages as a CBOR arrays instead of a CBOR maps as described in the FIDO Device Onboard Specification. Fixes: #620 Signed-off-by: Miguel Martín --- data-formats/src/constants/mod.rs | 2 +- data-formats/src/messages/v10/error.rs | 51 +++++++++++++++++++++++++- data-formats/src/messages/v11/error.rs | 51 +++++++++++++++++++++++++- 3 files changed, 99 insertions(+), 5 deletions(-) diff --git a/data-formats/src/constants/mod.rs b/data-formats/src/constants/mod.rs index 45212d526..09ca90d62 100644 --- a/data-formats/src/constants/mod.rs +++ b/data-formats/src/constants/mod.rs @@ -405,7 +405,7 @@ impl TryFrom for MessageType { } } -#[derive(Debug, Clone, Copy, Serialize_repr, Deserialize_repr)] +#[derive(Debug, Clone, Copy, Serialize_repr, Deserialize_repr, PartialEq)] #[repr(u16)] #[non_exhaustive] pub enum ErrorCode { diff --git a/data-formats/src/messages/v10/error.rs b/data-formats/src/messages/v10/error.rs index 30d9d4ca0..180e1792b 100644 --- a/data-formats/src/messages/v10/error.rs +++ b/data-formats/src/messages/v10/error.rs @@ -1,11 +1,11 @@ -use serde::{Deserialize, Serialize}; +use serde_tuple::{Deserialize_tuple, Serialize_tuple}; use crate::{ constants::{ErrorCode, MessageType}, messages::{ClientMessage, EncryptionRequirement, Message, ServerMessage}, }; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize_tuple, Deserialize_tuple)] pub struct ErrorMessage { error_code: ErrorCode, previous_message_type: MessageType, @@ -75,3 +75,50 @@ impl Message for ErrorMessage { impl ClientMessage for ErrorMessage {} impl ServerMessage for ErrorMessage {} + +#[cfg(test)] +mod test { + use std::u128; + + use super::ErrorCode; + use super::ErrorMessage; + use super::MessageType; + use crate::Serializable; + + #[test] + fn test_error_message_serialization() { + let error_code = ErrorCode::InvalidOwnershipVoucher; + let previous_message_type = MessageType::TO0OwnerSign; + let error_string = "Ownership voucher manufacturer not trusted".to_string(); + let error_uuid = 16378777930150272023 as u128; + let error = ErrorMessage::new(error_code, previous_message_type, error_string, error_uuid); + + let serialized_error = error.serialize_data(); + assert!(serialized_error.is_ok()); + let serialized_data = serialized_error.unwrap(); + let serialized_string = hex::encode(serialized_data); + // Check the error message is serialized as a CBOR array + assert!(serialized_string.starts_with("85")); + } + #[test] + fn test_error_message_deserialization() { + let error_message_encoded = "850216782a4f776e65727368697020766f7563686572206d616e756661637475726572206e6f742074727573746564f61be34d1bbfbd9d5c17"; + + let error_code = ErrorCode::InvalidOwnershipVoucher; + let previous_message_type = MessageType::TO0OwnerSign; + let error_string = "Ownership voucher manufacturer not trusted".to_string(); + let error_uuid = 16378777930150272023 as u128; + + let error_decoded = hex::decode(error_message_encoded); + assert!(error_decoded.is_ok()); + let mut error_bytes = error_decoded.unwrap(); + let error_test = &error_bytes.as_mut_slice(); + let error_deserialized = ErrorMessage::deserialize_data(error_test); + assert!(error_deserialized.is_ok()); + let error_message = error_deserialized.unwrap(); + assert_eq!(error_message.error_code(), error_code); + assert_eq!(error_message.previous_message_type(), previous_message_type); + assert_eq!(error_message.error_string(), error_string); + assert_eq!(error_message.error_uuid(), error_uuid); + } +} diff --git a/data-formats/src/messages/v11/error.rs b/data-formats/src/messages/v11/error.rs index 6699ec7ef..7ca39d2d3 100644 --- a/data-formats/src/messages/v11/error.rs +++ b/data-formats/src/messages/v11/error.rs @@ -1,11 +1,11 @@ -use serde::{Deserialize, Serialize}; +use serde_tuple::{Deserialize_tuple, Serialize_tuple}; use crate::{ constants::{ErrorCode, MessageType}, messages::{ClientMessage, EncryptionRequirement, Message, ServerMessage}, }; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize_tuple, Deserialize_tuple)] pub struct ErrorMessage { error_code: ErrorCode, previous_message_type: MessageType, @@ -75,3 +75,50 @@ impl Message for ErrorMessage { impl ClientMessage for ErrorMessage {} impl ServerMessage for ErrorMessage {} + +#[cfg(test)] +mod test { + use std::u128; + + use super::ErrorCode; + use super::ErrorMessage; + use super::MessageType; + use crate::Serializable; + + #[test] + fn test_error_message_serialization() { + let error_code = ErrorCode::InvalidOwnershipVoucher; + let previous_message_type = MessageType::TO0OwnerSign; + let error_string = "Ownership voucher manufacturer not trusted".to_string(); + let error_uuid = 16378777930150272023 as u128; + let error = ErrorMessage::new(error_code, previous_message_type, error_string, error_uuid); + + let serialized_error = error.serialize_data(); + assert!(serialized_error.is_ok()); + let serialized_data = serialized_error.unwrap(); + let serialized_string = hex::encode(serialized_data); + // Check the error message is serialized as a CBOR array + assert!(serialized_string.starts_with("85")); + } + #[test] + fn test_error_message_deserialization() { + let error_message_encoded = "850216782a4f776e65727368697020766f7563686572206d616e756661637475726572206e6f742074727573746564f61be34d1bbfbd9d5c17"; + + let error_code = ErrorCode::InvalidOwnershipVoucher; + let previous_message_type = MessageType::TO0OwnerSign; + let error_string = "Ownership voucher manufacturer not trusted".to_string(); + let error_uuid = 16378777930150272023 as u128; + + let error_decoded = hex::decode(error_message_encoded); + assert!(error_decoded.is_ok()); + let mut error_bytes = error_decoded.unwrap(); + let error_test = &error_bytes.as_mut_slice(); + let error_deserialized = ErrorMessage::deserialize_data(error_test); + assert!(error_deserialized.is_ok()); + let error_message = error_deserialized.unwrap(); + assert_eq!(error_message.error_code(), error_code); + assert_eq!(error_message.previous_message_type(), previous_message_type); + assert_eq!(error_message.error_string(), error_string); + assert_eq!(error_message.error_uuid(), error_uuid); + } +}