1 use anyhow::Result;
2 use openssl::x509::X509;
3 use std::{collections::HashMap, fmt};
4
5 use crate::dice::ChainForm;
6
7 #[derive(Clone, Eq, PartialEq)]
8 pub struct ProtectedData {
9 mac_key: Vec<u8>,
10 dice_chain: ChainForm,
11 uds_certs: Option<UdsCerts>,
12 }
13
14 #[derive(Clone, Debug, Default, Eq, PartialEq)]
15 pub struct UdsCerts(pub(crate) HashMap<String, UdsCertsEntry>);
16
17 /// Represent entries in the UDS certs mapping as an enum to support special cases in the future
18 /// where the input is not actually x.509 certs.
19 #[derive(Clone, Eq, PartialEq)]
20 pub enum UdsCertsEntry {
21 /// A chain of X.509 certificates that certify the UDS
22 X509Chain(Vec<Vec<u8>>),
23 }
24
25 impl ProtectedData {
new(mac_key: Vec<u8>, dice_chain: ChainForm, uds_certs: Option<UdsCerts>) -> Self26 pub fn new(mac_key: Vec<u8>, dice_chain: ChainForm, uds_certs: Option<UdsCerts>) -> Self {
27 Self { mac_key, dice_chain, uds_certs }
28 }
29 }
30
31 impl UdsCerts {
new() -> Self32 pub fn new() -> Self {
33 Self(HashMap::new())
34 }
35 }
36
37 impl UdsCertsEntry {
new_x509_chain(der_encoded_chain: Vec<Vec<u8>>) -> Result<Self>38 pub(crate) fn new_x509_chain(der_encoded_chain: Vec<Vec<u8>>) -> Result<Self> {
39 Ok(Self::X509Chain(der_encoded_chain))
40 }
41 }
42
43 impl fmt::Debug for ProtectedData {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result44 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
45 fmt.debug_struct("ProtectedData")
46 .field("mac_key", &hex::encode(&self.mac_key))
47 .field("dice_chain", &self.dice_chain)
48 .field("uds_certs", &self.uds_certs)
49 .finish()
50 }
51 }
52
53 impl fmt::Debug for UdsCertsEntry {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result54 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
55 match self {
56 Self::X509Chain(v) => format_x509_chain(fmt, v),
57 }
58 }
59 }
60
format_x509_chain(fmt: &mut fmt::Formatter, chain: &Vec<Vec<u8>>) -> fmt::Result61 fn format_x509_chain(fmt: &mut fmt::Formatter, chain: &Vec<Vec<u8>>) -> fmt::Result {
62 for c in chain {
63 fmt.write_str(&x509_der_to_pem(c).unwrap_or("[INVALID CERTIFICATE]".to_string()))?;
64 }
65 Ok(())
66 }
67
x509_der_to_pem(der: &[u8]) -> Result<String>68 fn x509_der_to_pem(der: &[u8]) -> Result<String> {
69 let utf8 = X509::from_der(der)?.to_pem()?;
70 Ok(std::str::from_utf8(&utf8)?.to_string())
71 }
72