Skip to main content

ear/
id.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use std::fmt;
4
5use serde::{
6    de::{self, Deserialize, Visitor},
7    ser::{Serialize, SerializeMap},
8};
9
10use crate::error::Error;
11
12/// identifies the verifier that produced the EAR
13#[derive(Debug, PartialEq)]
14pub struct VerifierID {
15    /// uniquely identifies the software build running the verifier
16    pub build: String,
17    /// uniquely identifies the organizational unit responsible for this build
18    pub developer: String,
19}
20
21impl VerifierID {
22    pub fn new() -> VerifierID {
23        VerifierID {
24            build: "".to_string(),
25            developer: "".to_string(),
26        }
27    }
28
29    pub fn validate(&self) -> Result<(), Error> {
30        if self.build.as_str() == "" {
31            return Err(Error::ValidationError("empty build".to_string()));
32        }
33
34        if self.developer.as_str() == "" {
35            return Err(Error::ValidationError("empty build".to_string()));
36        }
37
38        Ok(())
39    }
40}
41
42impl Default for VerifierID {
43    fn default() -> Self {
44        Self::new()
45    }
46}
47
48impl Serialize for VerifierID {
49    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
50    where
51        S: serde::Serializer,
52    {
53        let is_human_readable = serializer.is_human_readable();
54        let mut map = serializer.serialize_map(Some(2))?;
55
56        if is_human_readable {
57            map.serialize_entry("developer", &self.developer)?;
58            map.serialize_entry("build", &self.build)?;
59        } else {
60            map.serialize_entry(&0, &self.developer)?;
61            map.serialize_entry(&1, &self.build)?;
62        }
63
64        map.end()
65    }
66}
67
68impl<'de> Deserialize<'de> for VerifierID {
69    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
70    where
71        D: serde::Deserializer<'de>,
72    {
73        let is_hr = deserializer.is_human_readable();
74
75        deserializer.deserialize_map(VerifierIDVisitor {
76            is_human_readable: is_hr,
77        })
78    }
79}
80
81struct VerifierIDVisitor {
82    pub is_human_readable: bool,
83}
84
85impl<'de> Visitor<'de> for VerifierIDVisitor {
86    type Value = VerifierID;
87
88    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
89        formatter.write_str("a CBOR map or JSON object")
90    }
91
92    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
93    where
94        A: serde::de::MapAccess<'de>,
95    {
96        let mut vid = VerifierID::new();
97
98        loop {
99            if self.is_human_readable {
100                match map.next_key::<&str>()? {
101                    Some("developer") => vid.developer = map.next_value::<String>()?,
102                    Some("build") => vid.build = map.next_value::<String>()?,
103                    Some(s) => return Err(de::Error::custom(Error::InvalidName(s.to_string()))),
104                    None => break,
105                }
106            } else {
107                // !is_human_readable
108                match map.next_key::<i32>()? {
109                    Some(0) => vid.developer = map.next_value::<String>()?,
110                    Some(1) => vid.build = map.next_value::<String>()?,
111                    Some(x) => return Err(de::Error::custom(Error::InvalidKey(x))),
112                    None => break,
113                }
114            }
115        }
116
117        Ok(vid)
118    }
119}