Skip to content

Commit

Permalink
fix(data-formats): use correct CBOR serializer for Error messages
Browse files Browse the repository at this point in the history
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: fdo-rs#620

Signed-off-by: Miguel Martín <[email protected]>
  • Loading branch information
mmartinv committed Feb 29, 2024
1 parent 54f4502 commit d3d65d6
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 5 deletions.
2 changes: 1 addition & 1 deletion data-formats/src/constants/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ impl TryFrom<u8> 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 {
Expand Down
51 changes: 49 additions & 2 deletions data-formats/src/messages/v10/error.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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);
}
}
51 changes: 49 additions & 2 deletions data-formats/src/messages/v11/error.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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);
}
}

0 comments on commit d3d65d6

Please sign in to comment.