nsm_nitro_enclave_utils_keygen/
lib.rs1pub mod encode;
4
5use p384::{
6 ecdsa::{DerSignature, SigningKey, VerifyingKey},
7 SecretKey,
8};
9use std::time::Duration;
10use x509_cert::{
11 builder::{Builder, CertificateBuilder, Profile},
12 name::Name,
13 serial_number::SerialNumber,
14 spki::SubjectPublicKeyInfo,
15 time::Validity,
16};
17
18pub use x509_cert::{
19 der::{Decode as DerDecodeExt, Encode as DerEncodeExt, EncodePem as PemEncodeExt},
20 Certificate,
21};
22
23#[derive(Clone)]
25pub struct NsmCertChain {
26 pub root: Certificate,
27 pub int: Certificate,
28 pub end_signer: EndCertificateSigner,
29}
30
31#[derive(Clone)]
33pub struct EndCertificateSigner {
34 pub cert: Certificate,
35 pub signing_key: SigningKey,
36}
37
38impl NsmCertChain {
39 pub fn generate(valid_until: Duration) -> Self {
43 let (root_signing_key, root_public_key) = generate_key();
44 let root_cert = build_cert(
45 Profile::Root,
46 root_signing_key.clone(),
47 root_public_key,
48 valid_until,
49 );
50
51 let (int_key, int_public_key) = generate_key();
52 let int_cert = build_cert(
53 Profile::SubCA {
54 issuer: Default::default(),
55 path_len_constraint: None,
56 },
57 root_signing_key,
58 int_public_key,
59 valid_until,
60 );
61
62 let (end_signing_key, end_public_key) = generate_key();
63 let end_cert = build_cert(
64 Profile::Leaf {
65 issuer: Default::default(),
66 enable_key_agreement: false,
67 enable_key_encipherment: false,
68 },
69 int_key,
70 end_public_key,
71 valid_until,
72 );
73
74 Self {
75 root: root_cert,
76 int: int_cert,
77 end_signer: EndCertificateSigner {
78 cert: end_cert,
79 signing_key: end_signing_key,
80 },
81 }
82 }
83}
84
85fn build_cert(
86 profile: Profile,
87 signing_key: SigningKey,
88 public_key: VerifyingKey,
89 valid_until: Duration,
90) -> Certificate {
91 let cert = CertificateBuilder::new(
92 profile.clone(),
93 SerialNumber::new(&[1]).expect("SerialNumber"),
94 Validity::from_now(valid_until).expect("Validity"),
95 Name::default(),
96 SubjectPublicKeyInfo::from_key(public_key).expect("SubjectPublicKeyInfo"),
97 &signing_key,
98 )
99 .unwrap()
100 .build::<DerSignature>()
101 .unwrap();
102
103 cert
104}
105
106fn generate_key() -> (SigningKey, VerifyingKey) {
107 let signing_key = SigningKey::from(SecretKey::random(&mut rand_core::OsRng));
108 let verifying_key = VerifyingKey::from(signing_key.clone());
109 (signing_key, verifying_key)
110}
111
112#[cfg(test)]
113mod test {
114 use crate::NsmCertChain;
115 use std::time::Duration;
116
117 #[test]
118 fn generate_chain() {
119 let until = Duration::from_secs(0);
120 NsmCertChain::generate(until);
121 }
122}