1use cryptoki::{
2 context::{CInitializeArgs, CInitializeFlags, Pkcs11},
3 mechanism::{
4 Mechanism, MechanismType,
5 eddsa::{EddsaParams, EddsaSignatureScheme},
6 rsa::{PkcsMgfType, PkcsPssParams},
7 },
8 object::{Attribute, AttributeType, CertificateType, KeyType, ObjectClass},
9 session::{Session, UserType},
10 types::AuthPin,
11};
12use log::{debug, error, info};
13use rustls::{
14 self, OtherError, SignatureAlgorithm, SignatureScheme,
15 client::ResolvesClientCert,
16 pki_types::CertificateDer,
17 sign::{CertifiedKey, Signer, SigningKey},
18};
19use std::{
20 ffi::OsStr,
21 fmt,
22 sync::{Arc, Mutex},
23};
24use x509_certificate::X509Certificate;
25
26#[derive(Debug)]
27enum PKCS11Error {
28 CertificateNotFoundError,
29 KeyHandleNotFoundError,
30 UnsupportedSignatureSchemeError(SignatureScheme),
31 SignError(cryptoki::error::Error),
32}
33
34impl std::error::Error for PKCS11Error {}
35
36impl fmt::Display for PKCS11Error {
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 match self {
39 PKCS11Error::SignError(err) => write!(f, "{}: {}", self, err),
40 PKCS11Error::UnsupportedSignatureSchemeError(scheme) => {
41 write!(f, "{}: {:?}", self, scheme)
42 }
43 _ => write!(f, "{}", self),
44 }
45 }
46}
47
48#[derive(Debug)]
49struct PKCS11Signer {
50 session: Arc<Mutex<Session>>,
51 scheme: SignatureScheme,
52}
53
54impl<'a> TryInto<Mechanism<'a>> for &PKCS11Signer {
72 type Error = rustls::Error;
73
74 fn try_into(self) -> Result<Mechanism<'a>, rustls::Error> {
75 match self.scheme {
76 SignatureScheme::ECDSA_NISTP256_SHA256 => Ok(Mechanism::EcdsaSha256),
78 SignatureScheme::ECDSA_NISTP384_SHA384 => Ok(Mechanism::EcdsaSha384),
80 SignatureScheme::ECDSA_NISTP521_SHA512 => Ok(Mechanism::EcdsaSha512),
82 SignatureScheme::RSA_PKCS1_SHA256 => Ok(Mechanism::Sha256RsaPkcs),
84 SignatureScheme::RSA_PKCS1_SHA384 => Ok(Mechanism::Sha384RsaPkcs),
86 SignatureScheme::RSA_PKCS1_SHA512 => Ok(Mechanism::Sha512RsaPkcs),
88 SignatureScheme::RSA_PSS_SHA256 => {
90 let params = PkcsPssParams {
91 hash_alg: MechanismType::SHA256_RSA_PKCS, mgf: PkcsMgfType::MGF1_SHA256, s_len: 32.into(),
94 };
95 Ok(Mechanism::Sha256RsaPkcsPss(params))
96 }
97 SignatureScheme::RSA_PSS_SHA384 => {
99 let params = PkcsPssParams {
100 hash_alg: MechanismType::SHA384_RSA_PKCS, mgf: PkcsMgfType::MGF1_SHA384, s_len: 48.into(),
103 };
104 Ok(Mechanism::Sha384RsaPkcsPss(params))
105 }
106 SignatureScheme::RSA_PSS_SHA512 => {
108 let params = PkcsPssParams {
109 hash_alg: MechanismType::SHA512_RSA_PKCS, mgf: PkcsMgfType::MGF1_SHA512, s_len: 64.into(),
112 };
113 Ok(Mechanism::Sha384RsaPkcsPss(params))
114 }
115 SignatureScheme::ED25519 => Ok(Mechanism::Eddsa(EddsaParams::new(
117 EddsaSignatureScheme::Ed25519,
118 ))),
119 unsupported_scheme => Err(rustls::Error::Other(OtherError(Arc::new(
120 PKCS11Error::UnsupportedSignatureSchemeError(unsupported_scheme),
121 )))),
122 }
123 }
124}
125
126impl Into<KeyType> for &PKCS11Signer {
128 fn into(self) -> KeyType {
129 match self.scheme {
130 SignatureScheme::ECDSA_NISTP256_SHA256 => KeyType::EC,
131 SignatureScheme::ECDSA_NISTP384_SHA384 => KeyType::EC,
132 _ => KeyType::RSA,
133 }
134 }
135}
136
137impl Signer for PKCS11Signer {
138 fn sign(&self, message: &[u8]) -> Result<Vec<u8>, rustls::Error> {
139 let session = self.session.lock().unwrap();
140
141 let key_template = vec![
142 Attribute::Token(true),
143 Attribute::Private(true),
144 Attribute::Sign(true),
145 Attribute::KeyType(self.into()),
146 ];
147
148 let key = session
149 .find_objects(&key_template)
150 .unwrap() .into_iter()
152 .next()
153 .ok_or(rustls::Error::Other(OtherError(Arc::new(
154 PKCS11Error::KeyHandleNotFoundError,
155 ))))?;
156
157 let mechanism = self.try_into()?;
158
159 let mut signed_message = session.sign(&mechanism, key, message).map_err(|err| {
160 rustls::Error::Other(OtherError(Arc::new(PKCS11Error::SignError(err))))
161 })?;
162
163 let signed_message = match self.into() {
167 KeyType::EC => signed_message.to_asn1_sig().unwrap(),
168 _ => signed_message,
169 };
170
171 debug!("{:?}({:02x?})", mechanism, signed_message);
172 Ok(signed_message)
173 }
174
175 fn scheme(&self) -> SignatureScheme {
176 self.scheme
177 }
178}
179
180#[derive(Debug)]
181struct PKCS11SigningKey {
182 session: Arc<Mutex<Session>>,
183 scheme: SignatureScheme,
184}
185
186impl Into<SignatureAlgorithm> for &PKCS11SigningKey {
187 fn into(self) -> SignatureAlgorithm {
188 match self.scheme {
189 SignatureScheme::ECDSA_NISTP256_SHA256 => SignatureAlgorithm::ECDSA,
190 SignatureScheme::ECDSA_NISTP384_SHA384 => SignatureAlgorithm::ECDSA,
191 SignatureScheme::RSA_PKCS1_SHA256 => SignatureAlgorithm::RSA,
192 SignatureScheme::RSA_PKCS1_SHA384 => SignatureAlgorithm::RSA,
193 SignatureScheme::RSA_PSS_SHA256 => SignatureAlgorithm::RSA,
194 SignatureScheme::RSA_PSS_SHA384 => SignatureAlgorithm::RSA,
195 _ => SignatureAlgorithm::Unknown(0),
196 }
197 }
198}
199
200impl SigningKey for PKCS11SigningKey {
201 fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
202 debug!(
203 "schemes offered: {:?}, scheme supported: {:?}",
204 offered, self.scheme
205 );
206 if offered.contains(&self.scheme) {
207 return Some(Box::new(PKCS11Signer {
208 session: self.session.clone(),
209 scheme: self.scheme,
210 }));
211 }
212 None
213 }
214
215 fn algorithm(&self) -> SignatureAlgorithm {
217 debug!("algorithm called!");
218 self.into()
219 }
220}
221
222#[derive(Debug)]
223pub struct PKCS11ClientCertResolver {
224 chain: Vec<CertificateDer<'static>>,
225 signing_key: Arc<PKCS11SigningKey>,
226}
227
228impl ResolvesClientCert for PKCS11ClientCertResolver {
229 fn resolve(
230 &self,
231 _acceptable_issuers: &[&[u8]],
232 _sigschemes: &[SignatureScheme],
233 ) -> Option<Arc<CertifiedKey>> {
234 Some(Arc::new(CertifiedKey {
235 cert: self.chain.clone(),
236 key: self.signing_key.clone(),
237 ocsp: None,
238 }))
239 }
240
241 fn has_certs(&self) -> bool {
242 self.chain.len() > 0
243 }
244}
245
246impl PKCS11ClientCertResolver {
247 pub fn new(pin: Option<&str>, path: &OsStr) -> Result<Self, Box<dyn std::error::Error>> {
279 let pkcs11client = Pkcs11::new(path)?;
280 pkcs11client.initialize(CInitializeArgs::new(CInitializeFlags::OS_LOCKING_OK))?;
281
282 let slot = pkcs11client.get_slots_with_token()?.remove(0); let session = pkcs11client.open_ro_session(slot)?;
284 match pin {
285 Some(pin) => session.login(UserType::User, Some(&AuthPin::new(pin.into())))?,
286 None => session.login(UserType::User, None)?,
287 }
288
289 let search_template = vec![
290 Attribute::Class(ObjectClass::CERTIFICATE),
291 Attribute::CertificateType(CertificateType::X_509),
292 ];
293 let handle = session.find_objects(&search_template)?.remove(0);
294 let value = session
295 .get_attributes(handle, &[AttributeType::Value])?
296 .remove(0);
297
298 let (scheme, chain) = parse_certificate(value)?;
299
300 let session = Arc::new(Mutex::new(session));
301 let signing_key = Arc::new(PKCS11SigningKey { session, scheme });
302
303 Ok(Self { chain, signing_key })
304 }
305}
306
307trait ToASN1 {
309 fn to_asn1_sig(&mut self) -> Result<Vec<u8>, asn1::WriteError>;
310}
311
312impl ToASN1 for Vec<u8> {
314 fn to_asn1_sig(&mut self) -> Result<Vec<u8>, asn1::WriteError> {
315 let mut mid = self.len() / 2;
316
317 if self[0] >> 7 == 1 {
319 self.insert(0, 0u8);
320 mid += 1; }
322 if self[mid] >> 7 == 1 {
323 self.insert(mid, 0u8);
324 }
325
326 asn1::write(|w| {
327 w.write_element(&asn1::SequenceWriter::new(&|w: &mut asn1::Writer| {
328 let r = asn1::BigInt::new(&self[..mid]);
329 w.write_element(&r)?;
330 let s = asn1::BigInt::new(&self[mid..]);
331 w.write_element(&s)?;
332 Ok(())
333 }))
334 })
335 }
336}
337
338fn parse_certificate(
340 value: Attribute,
341) -> Result<(SignatureScheme, Vec<CertificateDer<'static>>), Box<dyn std::error::Error>> {
342 match value {
343 Attribute::Value(cert) => {
344 let x509 = X509Certificate::from_der(&cert).unwrap();
345 info!(
346 "CN: {}, Issuer: {}",
347 x509.subject_common_name().unwrap(),
348 x509.issuer_common_name().unwrap(),
349 );
350 debug!(
351 "Signature algorithm: {:?}",
352 x509.signature_algorithm().unwrap(),
353 );
354 debug!("Pubkey({:02x})", x509.public_key_data());
355
356 let scheme = match x509.signature_algorithm().unwrap() {
357 x509_certificate::SignatureAlgorithm::RsaSha256 => {
360 SignatureScheme::RSA_PKCS1_SHA256 }
362 x509_certificate::SignatureAlgorithm::RsaSha384 => {
363 SignatureScheme::RSA_PKCS1_SHA384 }
365 x509_certificate::SignatureAlgorithm::EcdsaSha256 => {
366 SignatureScheme::ECDSA_NISTP256_SHA256
367 }
368 x509_certificate::SignatureAlgorithm::EcdsaSha384 => {
369 SignatureScheme::ECDSA_NISTP384_SHA384
370 }
371 unsupported_scheme => {
372 error!("Unsupported scheme: {}", unsupported_scheme);
373 return Err(Box::new(PKCS11Error::UnsupportedSignatureSchemeError(
374 SignatureScheme::Unknown(0),
375 )));
376 }
377 };
378
379 let certificate_der = CertificateDer::from_slice(&cert).into_owned();
380 Ok((scheme, vec![certificate_der]))
381 }
382 _ => Err(Box::new(PKCS11Error::CertificateNotFoundError)),
383 }
384}