isomdl/definitions/
device_signed.rs1use crate::cose::MaybeTagged;
8use crate::definitions::{
9 helpers::{NonEmptyMap, Tag24},
10 session::SessionTranscript,
11};
12use coset::{CoseMac0, CoseSign1};
13use serde::{Deserialize, Serialize};
14use std::collections::BTreeMap;
15
16#[derive(Clone, Debug, Deserialize, Serialize)]
18#[serde(rename_all = "camelCase")]
19pub struct DeviceSigned {
20 #[serde(rename = "nameSpaces")]
21 pub namespaces: DeviceNamespacesBytes,
23
24 pub device_auth: DeviceAuth,
26}
27
28pub type DeviceNamespacesBytes = Tag24<DeviceNamespaces>;
29pub type DeviceNamespaces = BTreeMap<String, DeviceSignedItems>;
30pub type DeviceSignedItems = NonEmptyMap<String, ciborium::Value>;
31
32#[derive(Clone, Debug, Deserialize, Serialize)]
37#[serde(rename_all = "camelCase")]
38pub enum DeviceAuth {
39 DeviceSignature(MaybeTagged<CoseSign1>),
40 DeviceMac(MaybeTagged<CoseMac0>),
41}
42
43#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
44pub enum DeviceAuthType {
45 Sign1,
46 Mac0,
47}
48
49pub type DeviceAuthenticationBytes<S> = Tag24<DeviceAuthentication<S>>;
50
51#[derive(Clone, Debug, Deserialize, Serialize)]
52pub struct DeviceAuthentication<S: SessionTranscript>(
53 &'static str,
54 #[serde(bound = "")] S,
56 String,
57 DeviceNamespacesBytes,
58);
59
60impl<S: SessionTranscript> DeviceAuthentication<S> {
61 pub fn new(transcript: S, doc_type: String, namespaces_bytes: DeviceNamespacesBytes) -> Self {
62 Self(
63 "DeviceAuthentication",
64 transcript,
65 doc_type,
66 namespaces_bytes,
67 )
68 }
69}
70
71#[derive(Debug, thiserror::Error)]
72pub enum Error {
73 #[error("Unable to encode value as CBOR: {0}")]
74 UnableToEncode(coset::CoseError),
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80 use crate::cbor;
81 use hex::FromHex;
82
83 static COSE_SIGN1: &str = include_str!("../../test/definitions/cose/sign1/serialized.cbor");
84
85 #[test]
86 fn device_auth() {
87 let bytes = Vec::<u8>::from_hex(COSE_SIGN1).unwrap();
88 let cose_sign1: MaybeTagged<CoseSign1> =
89 cbor::from_slice(&bytes).expect("failed to parse COSE_Sign1 from bytes");
90 let bytes2 = cbor::to_vec(&cose_sign1).unwrap();
91 assert_eq!(bytes, bytes2);
92 let device_auth = DeviceAuth::DeviceSignature(cose_sign1);
93 let bytes = cbor::to_vec(&device_auth).unwrap();
94 println!("bytes {}", hex::encode(&bytes));
95 let roundtripped: DeviceAuth = cbor::from_slice(&bytes).unwrap();
96 let roundtripped_bytes = cbor::to_vec(&roundtripped).unwrap();
97 assert_eq!(bytes, roundtripped_bytes);
98 }
99}