Skip to content

Commit 80cdc31

Browse files
committed
refactor(pkcs11): Make crate::signing_key return a signer that can sign
Instead of returning a rustls::SigningKey, which can't immediately be used for signing, make tedge_p11_server::signing_key return an object on which one can call .sign() immediately. rustls::SigningKey first requires calling `choose_scheme` to obtain a signer that could be used for signing. So far `tedge_p11_server::signing_key` was called by only one caller which wanted a rustls::SigningKey, but now for CSR we want to call `.sign()`. There were also some changes in the pkcs11 module to remove some unnecessary structs that in practice were really duplicates - instead of having a separate `Pkcs11SigningKey` and `Pkcs11Signer` structs, just have `Pkcs11Signer` impl both `SigningKey` and `Signer`. Signed-off-by: Marcel Guzik <marcel.guzik@cumulocity.com>
1 parent 70331cd commit 80cdc31

File tree

3 files changed

+60
-57
lines changed

3 files changed

+60
-57
lines changed

crates/extensions/tedge-p11-server/src/pkcs11/mod.rs

Lines changed: 33 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ impl Cryptoki {
9292
})
9393
}
9494

95-
pub fn signing_key(&self, uri: Option<&str>) -> anyhow::Result<Pkcs11SigningKey> {
95+
pub fn signing_key(&self, uri: Option<&str>) -> anyhow::Result<Pkcs11Signer> {
9696
let mut config_uri = self
9797
.config
9898
.uri
@@ -156,7 +156,7 @@ impl Cryptoki {
156156
anyhow::bail!("can't get key type");
157157
};
158158

159-
let pkcs11 = PKCS11 {
159+
let session = Pkcs11Session {
160160
session: Arc::new(Mutex::new(session)),
161161
};
162162

@@ -177,18 +177,18 @@ impl Cryptoki {
177177

178178
let key = match keytype {
179179
KeyType::EC => {
180-
let sigscheme = get_ec_mechanism(&pkcs11.session.lock().unwrap(), key)
180+
let sigscheme = get_ec_mechanism(&session.session.lock().unwrap(), key)
181181
.unwrap_or(SigScheme::EcdsaNistp256Sha256);
182182

183-
Pkcs11SigningKey {
184-
session: pkcs11,
185-
handle: key,
183+
Pkcs11Signer {
184+
session,
185+
key,
186186
sigscheme,
187187
}
188188
}
189-
KeyType::RSA => Pkcs11SigningKey {
190-
session: pkcs11,
191-
handle: key,
189+
KeyType::RSA => Pkcs11Signer {
190+
session,
191+
key,
192192
sigscheme: SigScheme::RsaPssSha256,
193193
},
194194
_ => anyhow::bail!("unsupported key type"),
@@ -230,56 +230,20 @@ impl Cryptoki {
230230
}
231231

232232
#[derive(Debug, Clone)]
233-
pub struct Pkcs11SigningKey {
234-
session: PKCS11,
235-
handle: ObjectHandle,
236-
sigscheme: SigScheme,
237-
}
238-
239-
impl SigningKey for Pkcs11SigningKey {
240-
fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
241-
debug!("Offered signature schemes. offered={:?}", offered);
242-
let key_scheme = self.sigscheme.into();
243-
if offered.contains(&key_scheme) {
244-
debug!("Matching scheme: {key_scheme:?}");
245-
Some(Box::new(PkcsSigner {
246-
pkcs11: self.session.clone(),
247-
key: self.handle,
248-
sigscheme: self.sigscheme,
249-
}))
250-
} else {
251-
None
252-
}
253-
}
254-
255-
fn algorithm(&self) -> SignatureAlgorithm {
256-
self.sigscheme.into()
257-
}
258-
}
259-
260-
#[derive(Debug, Clone)]
261-
pub struct PKCS11 {
233+
pub struct Pkcs11Session {
262234
pub session: Arc<Mutex<Session>>,
263235
}
264236

265-
#[derive(Debug)]
266-
pub struct PkcsSigner {
267-
pkcs11: PKCS11,
237+
#[derive(Debug, Clone)]
238+
pub struct Pkcs11Signer {
239+
session: Pkcs11Session,
268240
key: ObjectHandle,
269241
sigscheme: SigScheme,
270242
}
271243

272-
impl PkcsSigner {
273-
pub fn from_key(key: Pkcs11SigningKey) -> Self {
274-
Self {
275-
pkcs11: key.session,
276-
key: key.handle,
277-
sigscheme: key.sigscheme,
278-
}
279-
}
280-
244+
impl Pkcs11Signer {
281245
pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>, anyhow::Error> {
282-
let session = self.pkcs11.session.lock().unwrap();
246+
let session = self.session.session.lock().unwrap();
283247

284248
let mechanism = self.sigscheme.into();
285249
let (mechanism, digest_mechanism) = match mechanism {
@@ -390,7 +354,24 @@ impl From<SigScheme> for Mechanism<'_> {
390354
}
391355
}
392356

393-
impl Signer for PkcsSigner {
357+
impl SigningKey for Pkcs11Signer {
358+
fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
359+
debug!("Offered signature schemes. offered={:?}", offered);
360+
let key_scheme = self.sigscheme.into();
361+
if offered.contains(&key_scheme) {
362+
debug!("Matching scheme: {key_scheme:?}");
363+
Some(Box::new(self.clone()))
364+
} else {
365+
None
366+
}
367+
}
368+
369+
fn algorithm(&self) -> SignatureAlgorithm {
370+
self.sigscheme.into()
371+
}
372+
}
373+
374+
impl Signer for Pkcs11Signer {
394375
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, rustls::Error> {
395376
Self::sign(self, message).map_err(|e| rustls::Error::General(e.to_string()))
396377
}

crates/extensions/tedge-p11-server/src/service.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::pkcs11::Cryptoki;
22
use crate::pkcs11::CryptokiConfigDirect;
3-
use crate::pkcs11::PkcsSigner;
43

54
use anyhow::Context;
65
use rustls::sign::SigningKey;
@@ -66,12 +65,11 @@ impl SigningService for TedgeP11Service {
6665
fn sign(&self, request: SignRequest) -> anyhow::Result<SignResponse> {
6766
trace!(?request);
6867
let uri = request.uri;
69-
let signing_key = self
68+
let signer = self
7069
.cryptoki
7170
.signing_key(uri.as_deref())
7271
.context("Failed to find a signing key")?;
7372

74-
let signer = PkcsSigner::from_key(signing_key);
7573
let signature = signer
7674
.sign(&request.to_sign)
7775
.context("Failed to sign using PKCS #11")?;

crates/extensions/tedge-p11-server/src/signer.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use tracing::instrument;
1010
use crate::client::TedgeP11Client;
1111
use crate::pkcs11::Cryptoki;
1212
use crate::pkcs11::CryptokiConfigDirect;
13+
use crate::pkcs11::Pkcs11Signer;
1314

1415
#[derive(Debug, Clone)]
1516
pub enum CryptokiConfig {
@@ -20,10 +21,26 @@ pub enum CryptokiConfig {
2021
},
2122
}
2223

24+
/// A signer using a private key object located on the PKCS11 token.
25+
///
26+
/// Is backed by either direct cryptoki library usage or by tedge-p11-server client.
27+
///
28+
/// Contains a handle to Pkcs11-backed private key that will be used for signing, selected at construction time.
29+
pub trait TedgeP11Signer: SigningKey {
30+
/// Signs the message using the selected private key.
31+
fn sign(&self, msg: &[u8]) -> anyhow::Result<Vec<u8>>;
32+
}
33+
34+
impl TedgeP11Signer for Pkcs11Signer {
35+
fn sign(&self, msg: &[u8]) -> anyhow::Result<Vec<u8>> {
36+
Pkcs11Signer::sign(self, msg)
37+
}
38+
}
39+
2340
/// Returns a rustls SigningKey that depending on the config, either connects to
2441
/// tedge-p11-server or calls cryptoki module directly.
25-
pub fn signing_key(config: CryptokiConfig) -> anyhow::Result<Arc<dyn SigningKey>> {
26-
let signing_key: Arc<dyn SigningKey> = match config {
42+
pub fn signing_key(config: CryptokiConfig) -> anyhow::Result<Arc<dyn TedgeP11Signer>> {
43+
let signing_key: Arc<dyn TedgeP11Signer> = match config {
2744
CryptokiConfig::Direct(config_direct) => {
2845
let uri = config_direct.uri.clone();
2946
let cryptoki =
@@ -49,6 +66,13 @@ pub struct TedgeP11ClientSigningKey {
4966
pub uri: Option<Arc<str>>,
5067
}
5168

69+
impl TedgeP11Signer for TedgeP11ClientSigningKey {
70+
fn sign(&self, msg: &[u8]) -> anyhow::Result<Vec<u8>> {
71+
self.client
72+
.sign(msg, self.uri.as_ref().map(|s| s.to_string()))
73+
}
74+
}
75+
5276
impl SigningKey for TedgeP11ClientSigningKey {
5377
#[instrument(skip_all)]
5478
fn choose_scheme(

0 commit comments

Comments
 (0)