nsm_nitro_enclave_utils/
lib.rs1pub mod api;
4
5pub mod driver;
6
7pub mod time;
8
9pub mod pcr;
10
11#[cfg(feature = "verify")]
12pub mod verify;
13
14#[derive(Debug)]
15pub struct Error<T> {
20 kind: T,
21 _backtrace: std::backtrace::Backtrace,
22 _source: Box<dyn std::error::Error + Send + Sync>,
23}
24
25impl<T> Error<T> {
26 fn new<E>(kind: T, err: E) -> Self
27 where
28 E: std::error::Error + Send + Sync + 'static,
29 {
30 Self {
31 kind,
32 _backtrace: std::backtrace::Backtrace::capture(),
33 _source: Box::new(err),
34 }
35 }
36
37 pub fn kind(&self) -> &T {
38 &self.kind
39 }
40}
41
42#[derive(Debug, PartialEq, Eq, Clone, Hash, PartialOrd, Ord)]
45pub struct ErrorContext(pub(crate) &'static str);
46
47impl std::fmt::Display for ErrorContext {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 write!(f, "{}", self.0)
50 }
51}
52
53impl std::error::Error for ErrorContext {}
54
55#[cfg(all(test, target_arch = "wasm32"))]
56mod wasm_tests {
59 use wasm_bindgen_test::*;
60
61 #[cfg(all(feature = "verify", feature = "pki"))]
62 #[wasm_bindgen_test]
63 fn sign_and_verify() {
64 use p384::{ecdsa::SigningKey, pkcs8::DecodePrivateKey};
65
66 use crate::api;
67 use crate::driver::dev::sign::AttestationDocSignerExt;
68 use crate::pcr::Pcrs;
69 use crate::time::Time;
70 use crate::verify::AttestationDocVerifierExt;
71
72 let time = Time::new(Box::new(|| include!("../../test_data/created_at.txt")));
73
74 let root_cert = include_bytes!("../../test_data/root-certificate.der");
75 let int_cert = include_bytes!("../../test_data/int-certificate.der");
76 let end_cert = include_bytes!("../../test_data/end-certificate.der");
77
78 let signing_key =
79 p384::SecretKey::from_pkcs8_der(include_bytes!("../../test_data/end-signing-key.der"))
80 .unwrap();
81 let signing_key: SigningKey = signing_key.into();
82
83 let doc = api::nsm::AttestationDoc {
84 module_id: "".to_string(),
85 digest: api::nsm::Digest::SHA384,
86 timestamp: time.time(),
87 pcrs: Pcrs::default().into(),
88 certificate: end_cert.to_vec().into(),
89 cabundle: vec![int_cert.to_vec().into()],
90 public_key: None,
91 user_data: None,
92 nonce: None,
93 };
94
95 let doc = doc.sign(signing_key).unwrap();
96
97 api::nsm::AttestationDoc::from_cose(&doc, root_cert, time).unwrap();
98 }
99
100 #[cfg(feature = "seed")]
101 #[wasm_bindgen_test]
102 fn seed_is_deterministic() {
103 use crate::pcr::{Pcrs, PCR_INDEXES};
104
105 use std::collections::BTreeMap;
106
107 let mut seed = BTreeMap::new();
108 for index in PCR_INDEXES {
109 seed.insert(index, usize::from(index).to_string());
110 }
111 let a = Pcrs::seed(seed.clone());
112 let b = Pcrs::seed(seed);
113 assert_eq!(a, b);
114
115 let mut alt_seed = BTreeMap::new();
116 for index in PCR_INDEXES {
117 alt_seed.insert(index, (usize::from(index) + 1).to_string());
118 }
119 let c = Pcrs::seed(alt_seed);
120 assert_ne!(a, c);
121 }
122
123 #[cfg(feature = "rand")]
124 #[wasm_bindgen_test]
125 fn rand() {
126 use crate::pcr::Pcrs;
127
128 let a = Pcrs::rand();
129 let b = Pcrs::rand();
130 assert_ne!(a, b);
131 }
132}