bitwarden_crypto/signing/
message.rs1use coset::iana::CoapContentFormat;
18use serde::{de::DeserializeOwned, Serialize};
19
20use crate::error::EncodingError;
21
22pub struct SerializedMessage {
25 serialized_message_bytes: Vec<u8>,
26 content_type: CoapContentFormat,
27}
28
29impl AsRef<[u8]> for SerializedMessage {
30 fn as_ref(&self) -> &[u8] {
31 &self.serialized_message_bytes
32 }
33}
34
35impl SerializedMessage {
36 pub fn from_bytes(bytes: Vec<u8>, content_type: CoapContentFormat) -> Self {
38 SerializedMessage {
39 serialized_message_bytes: bytes,
40 content_type,
41 }
42 }
43
44 pub fn as_bytes(&self) -> &[u8] {
47 &self.serialized_message_bytes
48 }
49
50 pub(super) fn content_type(&self) -> CoapContentFormat {
51 self.content_type
52 }
53
54 pub(super) fn encode<Message: Serialize>(message: &Message) -> Result<Self, EncodingError> {
56 let mut buffer = Vec::new();
57 ciborium::ser::into_writer(message, &mut buffer)
58 .map_err(|_| EncodingError::InvalidCborSerialization)?;
59 Ok(SerializedMessage {
60 serialized_message_bytes: buffer,
61 content_type: CoapContentFormat::Cbor,
62 })
63 }
64
65 pub fn decode<Message: DeserializeOwned>(&self) -> Result<Message, EncodingError> {
68 if self.content_type != CoapContentFormat::Cbor {
69 return Err(EncodingError::InvalidValue("Unsupported content type"));
70 }
71
72 ciborium::de::from_reader(self.serialized_message_bytes.as_slice())
73 .map_err(|_| EncodingError::InvalidCborSerialization)
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use serde::{Deserialize, Serialize};
80
81 use super::*;
82
83 #[derive(Serialize, Deserialize, Debug, PartialEq)]
84 struct TestMessage {
85 field1: String,
86 field2: u32,
87 }
88
89 #[test]
90 fn test_serialization() {
91 let message = TestMessage {
92 field1: "Hello".to_string(),
93 field2: 42,
94 };
95
96 let serialized = SerializedMessage::encode(&message).unwrap();
97 let deserialized: TestMessage = serialized.decode().unwrap();
98
99 assert_eq!(message, deserialized);
100 }
101
102 #[test]
103 fn test_bytes() {
104 let message = TestMessage {
105 field1: "Hello".to_string(),
106 field2: 42,
107 };
108
109 let serialized = SerializedMessage::encode(&message).unwrap();
110 let deserialized: TestMessage = SerializedMessage::from_bytes(
111 serialized.as_bytes().to_vec(),
112 serialized.content_type(),
113 )
114 .decode()
115 .unwrap();
116 assert_eq!(message, deserialized);
117 }
118}