Skip to content

Commit 2fc5e79

Browse files
committed
Make pkcs1v15::Signing/VerifyingKey accept raw message
Change the SigningKey and VerifiyingKey implementations accept raw message rather than pre-hashed message. Signed-off-by: Dmitry Baryshkov <[email protected]>
1 parent 2ffd3ae commit 2fc5e79

File tree

2 files changed

+81
-36
lines changed

2 files changed

+81
-36
lines changed

src/lib.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,16 @@
5858
//!
5959
//! let bits = 2048;
6060
//! let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
61-
//! let signing_key = SigningKey::new_with_hash(private_key, Hash::SHA2_256);
62-
//! let verifying_key: VerifyingKey = (&signing_key).into();
61+
//! let signing_key = SigningKey::<Sha256>::new_with_hash(private_key, Hash::SHA2_256);
62+
//! let verifying_key: VerifyingKey<_> = (&signing_key).into();
6363
//!
6464
//! // Sign
6565
//! let data = b"hello world";
66-
//! let digest = Sha256::digest(data).to_vec();
67-
//! let signature = signing_key.sign_with_rng(&mut rng, &digest);
66+
//! let signature = signing_key.sign_with_rng(&mut rng, data);
6867
//! assert_ne!(signature.as_bytes(), data);
6968
//!
7069
//! // Verify
71-
//! verifying_key.verify(&digest, &signature).expect("failed to verify");
70+
//! verifying_key.verify(data, &signature).expect("failed to verify");
7271
//! ```
7372
//!
7473
//! Using PSS signatures

src/pkcs1v15.rs

Lines changed: 77 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use alloc::vec;
22
use alloc::vec::Vec;
33
use core::fmt::{Debug, Display, Formatter, LowerHex, UpperHex};
4+
use core::marker::PhantomData;
5+
use digest::Digest;
46
use rand_core::{CryptoRng, RngCore};
57
use signature::{RandomizedSigner, Signature as SignSignature, Signer, Verifier};
68
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
@@ -285,12 +287,19 @@ fn non_zero_random_bytes<R: RngCore + CryptoRng>(rng: &mut R, data: &mut [u8]) {
285287
}
286288
}
287289

288-
pub struct SigningKey {
290+
pub struct SigningKey<D>
291+
where
292+
D: Digest,
293+
{
289294
inner: RsaPrivateKey,
290295
hash: Option<Hash>,
296+
phantom: PhantomData<D>,
291297
}
292298

293-
impl SigningKey {
299+
impl<D> SigningKey<D>
300+
where
301+
D: Digest,
302+
{
294303
pub(crate) fn key(&self) -> &RsaPrivateKey {
295304
&self.inner
296305
}
@@ -303,79 +312,118 @@ impl SigningKey {
303312
Self {
304313
inner: key,
305314
hash: None,
315+
phantom: Default::default(),
306316
}
307317
}
308318

309319
pub fn new_with_hash(key: RsaPrivateKey, hash: Hash) -> Self {
310320
Self {
311321
inner: key,
312322
hash: Some(hash),
323+
phantom: Default::default(),
313324
}
314325
}
315326
}
316327

317-
impl Signer<Signature> for SigningKey {
318-
fn try_sign(&self, digest: &[u8]) -> signature::Result<Signature> {
319-
sign::<DummyRng, _>(None, &self.inner, self.hash.as_ref(), digest)
328+
impl<D> Signer<Signature> for SigningKey<D>
329+
where
330+
D: Digest,
331+
{
332+
fn try_sign(&self, msg: &[u8]) -> signature::Result<Signature> {
333+
sign::<DummyRng, _>(None, &self.inner, self.hash.as_ref(), &D::digest(msg))
320334
.map(|v| v.into())
321335
.map_err(|e| e.into())
322336
}
323337
}
324338

325-
impl RandomizedSigner<Signature> for SigningKey {
339+
impl<D> RandomizedSigner<Signature> for SigningKey<D>
340+
where
341+
D: Digest,
342+
{
326343
fn try_sign_with_rng(
327344
&self,
328345
mut rng: impl CryptoRng + RngCore,
329-
digest: &[u8],
346+
msg: &[u8],
330347
) -> signature::Result<Signature> {
331-
sign(Some(&mut rng), &self.inner, self.hash.as_ref(), digest)
332-
.map(|v| v.into())
333-
.map_err(|e| e.into())
348+
sign(
349+
Some(&mut rng),
350+
&self.inner,
351+
self.hash.as_ref(),
352+
&D::digest(msg),
353+
)
354+
.map(|v| v.into())
355+
.map_err(|e| e.into())
334356
}
335357
}
336358

337-
pub struct VerifyingKey {
359+
pub struct VerifyingKey<D>
360+
where
361+
D: Digest,
362+
{
338363
inner: RsaPublicKey,
339364
hash: Option<Hash>,
365+
phantom: PhantomData<D>,
340366
}
341367

342-
impl VerifyingKey {
368+
impl<D> VerifyingKey<D>
369+
where
370+
D: Digest,
371+
{
343372
pub fn new(key: RsaPublicKey) -> Self {
344373
Self {
345374
inner: key,
346375
hash: None,
376+
phantom: Default::default(),
347377
}
348378
}
349379

350380
pub fn new_with_hash(key: RsaPublicKey, hash: Hash) -> Self {
351381
Self {
352382
inner: key,
353383
hash: Some(hash),
384+
phantom: Default::default(),
354385
}
355386
}
356387
}
357388

358-
impl From<SigningKey> for VerifyingKey {
359-
fn from(key: SigningKey) -> Self {
389+
impl<D> From<SigningKey<D>> for VerifyingKey<D>
390+
where
391+
D: Digest,
392+
{
393+
fn from(key: SigningKey<D>) -> Self {
360394
Self {
361395
inner: key.key().into(),
362396
hash: key.hash(),
397+
phantom: Default::default(),
363398
}
364399
}
365400
}
366401

367-
impl From<&SigningKey> for VerifyingKey {
368-
fn from(key: &SigningKey) -> Self {
402+
impl<D> From<&SigningKey<D>> for VerifyingKey<D>
403+
where
404+
D: Digest,
405+
{
406+
fn from(key: &SigningKey<D>) -> Self {
369407
Self {
370408
inner: key.key().into(),
371409
hash: key.hash(),
410+
phantom: Default::default(),
372411
}
373412
}
374413
}
375414

376-
impl Verifier<Signature> for VerifyingKey {
415+
impl<D> Verifier<Signature> for VerifyingKey<D>
416+
where
417+
D: Digest,
418+
{
377419
fn verify(&self, msg: &[u8], signature: &Signature) -> signature::Result<()> {
378-
verify(&self.inner, self.hash.as_ref(), msg, signature.as_ref()).map_err(|e| e.into())
420+
verify(
421+
&self.inner,
422+
self.hash.as_ref(),
423+
&D::digest(msg),
424+
signature.as_ref(),
425+
)
426+
.map_err(|e| e.into())
379427
}
380428
}
381429

@@ -526,17 +574,16 @@ mod tests {
526574
),
527575
)];
528576

529-
let signing_key = SigningKey::new_with_hash(priv_key, Hash::SHA1);
577+
let signing_key = SigningKey::<Sha1>::new_with_hash(priv_key, Hash::SHA1);
530578

531579
for (text, expected) in &tests {
532-
let digest = Sha1::digest(text.as_bytes()).to_vec();
533-
534-
let out = signing_key.sign(&digest);
535-
assert_ne!(out.as_ref(), digest);
580+
let out = signing_key.sign(text.as_bytes());
581+
assert_ne!(out.as_ref(), text.as_bytes());
582+
assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec());
536583
assert_eq!(out.as_ref(), expected);
537584

538585
let mut rng = ChaCha8Rng::from_seed([42; 32]);
539-
let out2 = signing_key.sign_with_rng(&mut rng, &digest);
586+
let out2 = signing_key.sign_with_rng(&mut rng, text.as_bytes());
540587
assert_eq!(out2.as_ref(), expected);
541588
}
542589
}
@@ -606,12 +653,11 @@ mod tests {
606653
),
607654
];
608655
let pub_key: RsaPublicKey = priv_key.into();
609-
let verifying_key = VerifyingKey::new_with_hash(pub_key, Hash::SHA1);
656+
let verifying_key = VerifyingKey::<Sha1>::new_with_hash(pub_key, Hash::SHA1);
610657

611658
for (text, sig, expected) in &tests {
612-
let digest = Sha1::digest(text.as_bytes()).to_vec();
613-
614-
let result = verifying_key.verify(&digest, &Signature::from_bytes(sig).unwrap());
659+
let result =
660+
verifying_key.verify(text.as_bytes(), &Signature::from_bytes(sig).unwrap());
615661
match expected {
616662
true => result.expect("failed to verify"),
617663
false => {
@@ -642,14 +688,14 @@ mod tests {
642688
#[test]
643689
fn test_unpadded_signature_signer() {
644690
let msg = b"Thu Dec 19 18:06:16 EST 2013\n";
645-
let expected_sig = Base64::decode_vec("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==").unwrap();
691+
let expected_sig = Base64::decode_vec("F8rxGUnrRLYr9nTWrYMZYk3Y0msVzfl9daWt32AZHJNCVENOWUS17OwcFawgmYhyJZDG3leTT6S5QZLaozun/A==").unwrap();
646692
let priv_key = get_private_key();
647693

648-
let signing_key = SigningKey::new(priv_key);
694+
let signing_key = SigningKey::<Sha1>::new(priv_key);
649695
let sig = signing_key.sign(msg);
650696
assert_eq!(sig.as_ref(), expected_sig);
651697

652-
let verifying_key: VerifyingKey = (&signing_key).into();
698+
let verifying_key: VerifyingKey<_> = (&signing_key).into();
653699
verifying_key
654700
.verify(msg, &Signature::from_bytes(&expected_sig).unwrap())
655701
.expect("failed to verify");

0 commit comments

Comments
 (0)