1use crate::{CborValue, CosePayload, CoseSignatureBytes};
2use coset::{
3 sig_structure_data, CborSerializable, CoseError, CoseSign1, Header, ProtectedHeader,
4 TaggedCborSerializable,
5};
6use serde::{Deserialize, Serialize};
7use std::{borrow::Borrow, ops::Deref};
8
9#[derive(Debug, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
17#[repr(transparent)]
18#[serde(transparent)]
19pub struct CoseSign1Bytes([u8]);
20
21impl CoseSign1Bytes {
22 pub fn new(bytes: &[u8]) -> &Self {
28 unsafe { std::mem::transmute(bytes) }
29 }
30
31 pub fn decode(&self, tagged: bool) -> Result<DecodedCoseSign1, CoseError> {
33 let cose = if tagged {
34 CoseSign1::from_tagged_slice(&self.0)?
35 } else {
36 CoseSign1::from_slice(&self.0)?
37 };
38
39 Ok(cose.into())
40 }
41
42 pub fn as_bytes(&self) -> &[u8] {
44 &self.0
45 }
46}
47
48impl AsRef<[u8]> for CoseSign1Bytes {
49 fn as_ref(&self) -> &[u8] {
50 self.as_bytes()
51 }
52}
53
54impl ToOwned for CoseSign1Bytes {
55 type Owned = CoseSign1BytesBuf;
56
57 fn to_owned(&self) -> Self::Owned {
58 CoseSign1BytesBuf(self.0.to_owned())
59 }
60}
61
62#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
71#[serde(transparent)]
72pub struct CoseSign1BytesBuf(Vec<u8>);
73
74impl CoseSign1BytesBuf {
75 pub fn new(bytes: Vec<u8>) -> Self {
81 Self(bytes)
82 }
83
84 pub fn encode(object: impl Into<CoseSign1>, tagged: bool) -> Self {
89 if tagged {
90 Self(TaggedCborSerializable::to_tagged_vec(object.into()).unwrap())
91 } else {
92 Self(CborSerializable::to_vec(object.into()).unwrap())
93 }
94 }
95
96 pub fn as_compact(&self) -> &CoseSign1Bytes {
98 CoseSign1Bytes::new(self.0.as_slice())
99 }
100}
101
102impl Deref for CoseSign1BytesBuf {
103 type Target = CoseSign1Bytes;
104
105 fn deref(&self) -> &Self::Target {
106 self.as_compact()
107 }
108}
109
110impl Borrow<CoseSign1Bytes> for CoseSign1BytesBuf {
111 fn borrow(&self) -> &CoseSign1Bytes {
112 self.as_compact()
113 }
114}
115
116impl From<CborValue> for CoseSign1BytesBuf {
117 fn from(value: CborValue) -> Self {
118 let mut buffer = Vec::new();
119 ciborium::into_writer(&value, &mut buffer).unwrap();
120 Self(buffer)
121 }
122}
123
124impl AsRef<[u8]> for CoseSign1BytesBuf {
125 fn as_ref(&self) -> &[u8] {
126 self.as_bytes()
127 }
128}
129
130impl From<Vec<u8>> for CoseSign1BytesBuf {
131 fn from(value: Vec<u8>) -> Self {
132 Self(value)
133 }
134}
135
136pub struct DecodedCoseSign1<T = ()> {
138 pub signing_bytes: UnsignedCoseSign1<T>,
140
141 pub signature: CoseSignatureBytes,
143}
144
145impl<T> DecodedCoseSign1<T> {
146 pub fn map<U>(self, f: impl FnOnce(T, &[u8]) -> U) -> DecodedCoseSign1<U> {
151 DecodedCoseSign1 {
152 signing_bytes: self.signing_bytes.map(f),
153 signature: self.signature,
154 }
155 }
156
157 pub fn try_map<U, E>(
162 self,
163 f: impl FnOnce(T, &[u8]) -> Result<U, E>,
164 ) -> Result<DecodedCoseSign1<U>, E> {
165 Ok(DecodedCoseSign1 {
166 signing_bytes: self.signing_bytes.try_map(f)?,
167 signature: self.signature,
168 })
169 }
170}
171
172impl From<CoseSign1> for DecodedCoseSign1 {
173 fn from(value: CoseSign1) -> Self {
174 Self {
175 signing_bytes: UnsignedCoseSign1 {
176 protected: value.protected,
177 unprotected: value.unprotected,
178 payload: PayloadBytes::from_bytes(value.payload.unwrap_or_default()),
179 },
180 signature: CoseSignatureBytes(value.signature),
181 }
182 }
183}
184
185impl<T> From<DecodedCoseSign1<T>> for CoseSign1 {
186 fn from(value: DecodedCoseSign1<T>) -> Self {
187 Self {
188 protected: value.signing_bytes.protected,
189 unprotected: value.signing_bytes.unprotected,
190 payload: Some(value.signing_bytes.payload.into_bytes()),
191 signature: value.signature.into_bytes(),
192 }
193 }
194}
195
196#[derive(Clone, PartialEq)]
205pub struct PayloadBytes<T = ()> {
206 bytes: Vec<u8>,
208
209 value: T,
211}
212
213impl PayloadBytes {
214 pub fn from_bytes(bytes: Vec<u8>) -> Self {
218 Self { bytes, value: () }
219 }
220}
221
222impl<T: CosePayload> PayloadBytes<T> {
223 pub fn new(value: T) -> Self {
226 Self {
227 bytes: value.payload_bytes().into_owned(),
228 value,
229 }
230 }
231}
232
233impl<T> PayloadBytes<T> {
234 pub fn as_bytes(&self) -> &[u8] {
236 &self.bytes
237 }
238
239 pub fn map<U>(self, f: impl FnOnce(T, &[u8]) -> U) -> PayloadBytes<U> {
244 let value = f(self.value, &self.bytes);
245 PayloadBytes {
246 bytes: self.bytes,
247 value,
248 }
249 }
250
251 pub fn try_map<U, E>(
256 self,
257 f: impl FnOnce(T, &[u8]) -> Result<U, E>,
258 ) -> Result<PayloadBytes<U>, E> {
259 let value = f(self.value, &self.bytes)?;
260 Ok(PayloadBytes {
261 bytes: self.bytes,
262 value,
263 })
264 }
265
266 pub fn into_bytes(self) -> Vec<u8> {
268 self.bytes
269 }
270}
271
272impl<T> Deref for PayloadBytes<T> {
273 type Target = T;
274
275 fn deref(&self) -> &Self::Target {
276 &self.value
277 }
278}
279
280impl<T> Borrow<T> for PayloadBytes<T> {
281 fn borrow(&self) -> &T {
282 &self.value
283 }
284}
285
286#[derive(Clone, PartialEq)]
288pub struct UnsignedCoseSign1<T> {
289 pub protected: ProtectedHeader,
291
292 pub unprotected: Header,
294
295 pub payload: PayloadBytes<T>,
297}
298
299impl<T> UnsignedCoseSign1<T> {
300 pub fn tbs_data(&self, aad: &[u8]) -> Vec<u8> {
302 sig_structure_data(
303 coset::SignatureContext::CoseSign1,
304 self.protected.clone(),
305 None,
306 aad,
307 self.payload.as_bytes(),
308 )
309 }
310
311 pub fn map<U>(self, f: impl FnOnce(T, &[u8]) -> U) -> UnsignedCoseSign1<U> {
313 UnsignedCoseSign1 {
314 protected: self.protected,
315 unprotected: self.unprotected,
316 payload: self.payload.map(f),
317 }
318 }
319
320 pub fn try_map<U, E>(
322 self,
323 f: impl FnOnce(T, &[u8]) -> Result<U, E>,
324 ) -> Result<UnsignedCoseSign1<U>, E> {
325 Ok(UnsignedCoseSign1 {
326 protected: self.protected,
327 unprotected: self.unprotected,
328 payload: self.payload.try_map(f)?,
329 })
330 }
331}