• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use anyhow::Result;
2 use openssl::x509::X509;
3 use std::{collections::HashMap, fmt};
4 
5 use crate::dice::ChainForm;
6 
7 /// The CSR V2 payload that is encrypted with an Endpoint Encryption Key (EEK).
8 #[derive(Clone, Eq, PartialEq)]
9 pub struct ProtectedData {
10     mac_key: Vec<u8>,
11     dice_chain: ChainForm,
12     uds_certs: Option<UdsCerts>,
13 }
14 
15 #[derive(Clone, Debug, Default, Eq, PartialEq)]
16 pub struct UdsCerts(pub(crate) HashMap<String, UdsCertsEntry>);
17 
18 /// Represent entries in the UDS certs mapping as an enum to support special cases in the future
19 /// where the input is not actually x.509 certs.
20 #[derive(Clone, Eq, PartialEq)]
21 pub enum UdsCertsEntry {
22     /// A chain of X.509 certificates that certify the UDS
23     X509Chain(Vec<Vec<u8>>),
24 }
25 
26 impl ProtectedData {
27     /// Constructs a new `ProtectedData` with a MAC key, DICE chain, and optional UDS certificates.
new(mac_key: Vec<u8>, dice_chain: ChainForm, uds_certs: Option<UdsCerts>) -> Self28     pub fn new(mac_key: Vec<u8>, dice_chain: ChainForm, uds_certs: Option<UdsCerts>) -> Self {
29         Self { mac_key, dice_chain, uds_certs }
30     }
31 
32     /// Returns the DICE chain.
dice_chain(&self) -> ChainForm33     pub fn dice_chain(&self) -> ChainForm {
34         self.dice_chain.clone()
35     }
36 
37     /// Returns the UDS certificates.
uds_certs(&self) -> Option<UdsCerts>38     pub fn uds_certs(&self) -> Option<UdsCerts> {
39         self.uds_certs.clone()
40     }
41 }
42 
43 impl UdsCerts {
new() -> Self44     pub fn new() -> Self {
45         Self(HashMap::new())
46     }
47 }
48 
49 impl UdsCertsEntry {
new_x509_chain(der_encoded_chain: Vec<Vec<u8>>) -> Result<Self>50     pub(crate) fn new_x509_chain(der_encoded_chain: Vec<Vec<u8>>) -> Result<Self> {
51         Ok(Self::X509Chain(der_encoded_chain))
52     }
53 }
54 
55 impl fmt::Debug for ProtectedData {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result56     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
57         fmt.debug_struct("ProtectedData")
58             .field("mac_key", &hex::encode(&self.mac_key))
59             .field("dice_chain", &self.dice_chain)
60             .field("uds_certs", &self.uds_certs)
61             .finish()
62     }
63 }
64 
65 impl fmt::Debug for UdsCertsEntry {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result66     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
67         match self {
68             Self::X509Chain(v) => format_x509_chain(fmt, v),
69         }
70     }
71 }
72 
format_x509_chain(fmt: &mut fmt::Formatter, chain: &Vec<Vec<u8>>) -> fmt::Result73 fn format_x509_chain(fmt: &mut fmt::Formatter, chain: &Vec<Vec<u8>>) -> fmt::Result {
74     for c in chain {
75         fmt.write_str(&x509_der_to_pem(c).unwrap_or("[INVALID CERTIFICATE]".to_string()))?;
76     }
77     Ok(())
78 }
79 
x509_der_to_pem(der: &[u8]) -> Result<String>80 fn x509_der_to_pem(der: &[u8]) -> Result<String> {
81     let utf8 = X509::from_der(der)?.to_pem()?;
82     Ok(std::str::from_utf8(&utf8)?.to_string())
83 }
84