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}