native_pkcs11_traits/
lib.rs1use std::{
16 any::Any,
17 hash::Hash,
18 sync::{Arc, LazyLock, RwLock},
19};
20
21use x509_cert::der::Decode;
22
23pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
24pub type Digest = [u8; 20];
25
26static STAGED_BACKEND: RwLock<Option<Box<dyn Backend>>> = RwLock::new(None);
29static BACKEND: LazyLock<Box<dyn Backend>> =
30 LazyLock::new(|| STAGED_BACKEND.write().unwrap().take().unwrap());
31
32pub fn register_backend(backend: Box<dyn Backend>) {
34 *STAGED_BACKEND.write().unwrap() = Some(backend);
35}
36
37pub fn backend() -> &'static dyn Backend {
38 BACKEND.as_ref()
39}
40
41#[derive(Debug, PartialEq, Eq, Clone)]
42pub enum DigestType {
43 Sha1,
44 Sha224,
45 Sha256,
46 Sha384,
47 Sha512,
48}
49
50impl DigestType {
51 pub fn digest_len(&self) -> usize {
52 match self {
53 DigestType::Sha1 => 20,
54 DigestType::Sha224 => 28,
55 DigestType::Sha256 => 32,
56 DigestType::Sha384 => 48,
57 DigestType::Sha512 => 64,
58 }
59 }
60}
61
62#[derive(Debug, Clone)]
63pub enum SignatureAlgorithm {
64 Ecdsa,
65 RsaRaw,
66 RsaPkcs1v15Raw,
67 RsaPkcs1v15Sha1,
68 RsaPkcs1v15Sha384,
69 RsaPkcs1v15Sha256,
70 RsaPkcs1v15Sha512,
71 RsaPss { digest: DigestType, mask_generation_function: DigestType, salt_length: u64 },
72}
73
74pub trait PrivateKey: Send + Sync {
75 fn public_key_hash(&self) -> Vec<u8>;
76 fn label(&self) -> String;
77 fn sign(&self, algorithm: &SignatureAlgorithm, data: &[u8]) -> Result<Vec<u8>>;
78 fn delete(&self);
79 fn algorithm(&self) -> KeyAlgorithm;
80 fn find_public_key(&self, backend: &dyn Backend) -> Result<Option<Box<dyn PublicKey>>> {
81 let pubkey_hash: Digest = self.public_key_hash().as_slice().try_into()?;
82 backend.find_public_key(KeySearchOptions::PublicKeyHash(pubkey_hash))
83 }
84}
85
86impl std::fmt::Debug for dyn PrivateKey {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 f.debug_struct("PrivateKey").field("label", &self.label()).finish_non_exhaustive()
89 }
90}
91
92impl PartialEq for dyn PrivateKey {
93 fn eq(&self, other: &Self) -> bool {
94 self.public_key_hash() == other.public_key_hash() && self.label() == other.label()
95 }
96}
97
98impl Eq for dyn PrivateKey {}
99impl Hash for dyn PrivateKey {
100 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
101 self.type_id().hash(state);
102 self.public_key_hash().hash(state);
103 self.label().hash(state);
104 }
105}
106
107pub trait PublicKey: Send + Sync + std::fmt::Debug {
108 fn public_key_hash(&self) -> Vec<u8>;
109 fn label(&self) -> String;
110 fn to_der(&self) -> Vec<u8>;
111 fn verify(&self, algorithm: &SignatureAlgorithm, data: &[u8], signature: &[u8]) -> Result<()>;
112 fn delete(self: Box<Self>);
113 fn algorithm(&self) -> KeyAlgorithm;
114}
115
116impl PartialEq for dyn PublicKey {
117 fn eq(&self, other: &Self) -> bool {
118 self.public_key_hash() == other.public_key_hash() && self.label() == other.label()
119 }
120}
121
122impl Eq for dyn PublicKey {}
123impl Hash for dyn PublicKey {
124 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
125 self.type_id().hash(state);
126 self.public_key_hash().hash(state);
127 self.label().hash(state);
128 }
129}
130
131pub trait Certificate: Send + Sync + std::fmt::Debug {
132 fn label(&self) -> String;
133 fn to_der(&self) -> Vec<u8>;
134 fn public_key(&self) -> &dyn PublicKey;
135 fn delete(self: Box<Self>);
136 fn algorithm(&self) -> KeyAlgorithm {
137 self.public_key().algorithm()
138 }
139}
140
141impl PartialEq for dyn Certificate {
142 fn eq(&self, other: &Self) -> bool {
143 self.to_der() == other.to_der() && self.label() == other.label()
144 }
145}
146impl Eq for dyn Certificate {}
147impl Hash for dyn Certificate {
148 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
149 self.type_id().hash(state);
150 self.to_der().hash(state);
151 self.label().hash(state);
152 }
153}
154
155pub trait CertificateExt: Certificate {
156 fn issuer(&self) -> Vec<u8> {
157 let der = self.to_der();
158 let c = x509_cert::Certificate::from_der(&der).unwrap();
159 x509_cert::der::Encode::to_der(&c.tbs_certificate.issuer).unwrap()
160 }
161
162 fn serial_number(&self) -> Vec<u8> {
163 let der = self.to_der();
164 let c = x509_cert::Certificate::from_der(&der).unwrap();
165 x509_cert::der::Encode::to_der(&c.tbs_certificate.serial_number).unwrap()
166 }
167
168 fn subject(&self) -> Vec<u8> {
169 let der = self.to_der();
170 let c = x509_cert::Certificate::from_der(&der).unwrap();
171 x509_cert::der::Encode::to_der(&c.tbs_certificate.subject).unwrap()
172 }
173}
174
175impl<T: Certificate + ?Sized> CertificateExt for T {}
176
177#[derive(Debug)]
178pub enum KeySearchOptions {
179 Label(String),
182 PublicKeyHash(Digest),
183}
184
185#[derive(Debug, Clone, Copy, PartialEq, Eq)]
186pub enum KeyAlgorithm {
187 Rsa,
188 Ecc,
189}
190
191pub trait Backend: Send + Sync {
192 fn name(&self) -> String;
193 fn find_all_certificates(&self) -> Result<Vec<Box<dyn Certificate>>>;
194 fn find_private_key(&self, query: KeySearchOptions) -> Result<Option<Arc<dyn PrivateKey>>>;
195 fn find_public_key(&self, query: KeySearchOptions) -> Result<Option<Box<dyn PublicKey>>>;
196 fn find_all_private_keys(&self) -> Result<Vec<Arc<dyn PrivateKey>>>;
197 fn find_all_public_keys(&self) -> Result<Vec<Arc<dyn PublicKey>>>;
198 fn generate_key(
199 &self,
200 algorithm: KeyAlgorithm,
201 label: Option<&str>,
202 ) -> Result<Arc<dyn PrivateKey>>;
203}
204
205pub fn random_label() -> String {
206 use rand::{Rng, distr::Alphanumeric};
207 String::from("bumpkey ")
208 + &rand::rng().sample_iter(&Alphanumeric).take(32).map(char::from).collect::<String>()
209}