Skip to content

Commit f48a0cc

Browse files
committed
signer/verifier: implement Signer and Verifier traits for the RSA
Signed-off-by: Dmitry Baryshkov <[email protected]>
1 parent 431df7d commit f48a0cc

File tree

4 files changed

+165
-0
lines changed

4 files changed

+165
-0
lines changed

src/key.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ pub trait PublicKey: EncryptionPrimitive + PublicKeyParts {
187187
/// passed in through `hash`.
188188
/// If the message is valid `Ok(())` is returned, otherwiese an `Err` indicating failure.
189189
fn verify(&self, padding: PaddingScheme, hashed: &[u8], sig: &[u8]) -> Result<()>;
190+
191+
fn to_verifier(&self, padding: PaddingScheme) -> RsaVerifier;
190192
}
191193

192194
impl PublicKeyParts for RsaPublicKey {
@@ -227,6 +229,10 @@ impl PublicKey for RsaPublicKey {
227229
_ => Err(Error::InvalidPaddingScheme),
228230
}
229231
}
232+
233+
fn to_verifier(&self, padding: PaddingScheme) -> RsaVerifier {
234+
RsaVerifier::new(&self, padding)
235+
}
230236
}
231237

232238
impl RsaPublicKey {
@@ -264,6 +270,10 @@ impl<'a> PublicKey for &'a RsaPublicKey {
264270
fn verify(&self, padding: PaddingScheme, hashed: &[u8], sig: &[u8]) -> Result<()> {
265271
(*self).verify(padding, hashed, sig)
266272
}
273+
274+
fn to_verifier(&self, padding: PaddingScheme) -> RsaVerifier {
275+
(*self).to_verifier(padding)
276+
}
267277
}
268278

269279
impl PublicKeyParts for RsaPrivateKey {

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ mod oaep;
173173
mod pkcs1v15;
174174
mod pss;
175175
mod raw;
176+
mod signer;
177+
mod verifier;
176178

177179
pub use pkcs1;
178180
pub use pkcs8;

src/signer.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
use crate::dummy_rng::DummyRng;
2+
use crate::errors::Error;
3+
use crate::rsa_core::*;
4+
use crate::RsaPrivateKey;
5+
use crate::{pkcs1v15, pss};
6+
use rand_core::{CryptoRng, RngCore};
7+
use signature::RandomizedSigner;
8+
use signature::Signature;
9+
use signature::Signer;
10+
11+
#[cfg(feature = "std")]
12+
fn to_sig_error(e: Error) -> signature::Error {
13+
signature::Error::from_source(e)
14+
}
15+
16+
#[cfg(not(feature = "std"))]
17+
fn to_sig_error(_e: Error) -> signature::Error {
18+
signature::Error::new()
19+
}
20+
21+
pub struct RsaSigner<'a> {
22+
key: &'a RsaPrivateKey,
23+
padding: PaddingScheme,
24+
}
25+
26+
impl<'a> RsaSigner<'a> {
27+
pub fn new(key: &'a RsaPrivateKey, padding: PaddingScheme) -> RsaSigner<'a> {
28+
RsaSigner { key, padding }
29+
}
30+
}
31+
32+
impl Signer<RsaSignature> for RsaSigner<'_> {
33+
fn try_sign(&self, msg: &[u8]) -> signature::Result<RsaSignature> {
34+
match self.padding {
35+
PaddingScheme::PKCS1v15Sign { ref hash } => {
36+
pkcs1v15::sign::<DummyRng, _>(None, self.key, hash.as_ref(), msg)
37+
}
38+
_ => Err(Error::InvalidPaddingScheme),
39+
}
40+
.map_err(|e| to_sig_error(e))
41+
.and_then(|v| RsaSignature::from_bytes(v.as_slice()))
42+
}
43+
}
44+
45+
impl RandomizedSigner<RsaSignature> for RsaSigner<'_> {
46+
fn try_sign_with_rng(
47+
&self,
48+
mut rng: impl CryptoRng + RngCore,
49+
msg: &[u8],
50+
) -> Result<RsaSignature, signature::Error> {
51+
match &self.padding {
52+
PaddingScheme::PKCS1v15Sign { ref hash } => {
53+
pkcs1v15::sign::<DummyRng, _>(None, self.key, hash.as_ref(), msg)
54+
}
55+
PaddingScheme::PSS {
56+
digest, salt_len, ..
57+
} => pss::sign::<_, _>(
58+
&mut rng,
59+
false,
60+
self.key,
61+
msg,
62+
*salt_len,
63+
&mut *digest.box_clone(),
64+
),
65+
_ => Err(Error::InvalidPaddingScheme),
66+
}
67+
.map_err(|e| to_sig_error(e))
68+
.and_then(|v| RsaSignature::from_bytes(v.as_slice()))
69+
}
70+
}
71+
72+
pub struct RsaBlindedSigner<'a> {
73+
key: &'a RsaPrivateKey,
74+
padding: PaddingScheme,
75+
}
76+
77+
impl<'a> RsaBlindedSigner<'a> {
78+
pub fn new(key: &'a RsaPrivateKey, padding: PaddingScheme) -> RsaBlindedSigner<'a> {
79+
RsaBlindedSigner { key, padding }
80+
}
81+
}
82+
83+
impl RandomizedSigner<RsaSignature> for RsaBlindedSigner<'_> {
84+
fn try_sign_with_rng(
85+
&self,
86+
mut rng: impl CryptoRng + RngCore,
87+
msg: &[u8],
88+
) -> Result<RsaSignature, signature::Error> {
89+
match &self.padding {
90+
PaddingScheme::PKCS1v15Sign { ref hash } => {
91+
pkcs1v15::sign::<_, _>(Some(&mut rng), self.key, hash.as_ref(), msg)
92+
}
93+
PaddingScheme::PSS {
94+
digest, salt_len, ..
95+
} => pss::sign::<_, _>(
96+
&mut rng,
97+
true,
98+
self.key,
99+
msg,
100+
*salt_len,
101+
&mut *digest.box_clone(),
102+
),
103+
_ => Err(Error::InvalidPaddingScheme),
104+
}
105+
.map_err(|e| to_sig_error(e))
106+
.and_then(|v| RsaSignature::from_bytes(v.as_slice()))
107+
}
108+
}

src/verifier.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use crate::errors::Error;
2+
use crate::rsa_core::*;
3+
use crate::RsaPublicKey;
4+
use crate::{pkcs1v15, pss};
5+
use signature::Signature;
6+
use signature::Verifier;
7+
8+
#[cfg(feature = "std")]
9+
fn to_sig_error(e: Error) -> signature::Error {
10+
signature::Error::from_source(e)
11+
}
12+
13+
#[cfg(not(feature = "std"))]
14+
fn to_sig_error(_e: Error) -> signature::Error {
15+
signature::Error::new()
16+
}
17+
18+
pub struct RsaVerifier<'a> {
19+
key: &'a RsaPublicKey,
20+
padding: PaddingScheme,
21+
}
22+
23+
impl<'a> RsaVerifier<'a> {
24+
pub fn new(key: &'a RsaPublicKey, padding: PaddingScheme) -> RsaVerifier<'a> {
25+
RsaVerifier { key, padding }
26+
}
27+
}
28+
29+
impl Verifier<RsaSignature> for RsaVerifier<'_> {
30+
fn verify(&self, msg: &[u8], signature: &RsaSignature) -> Result<(), signature::Error> {
31+
match &self.padding {
32+
PaddingScheme::PKCS1v15Sign { ref hash } => {
33+
pkcs1v15::verify(self.key, hash.as_ref(), msg, signature.as_bytes())
34+
}
35+
PaddingScheme::PSS { digest, .. } => pss::verify(
36+
self.key,
37+
msg,
38+
signature.as_bytes(),
39+
&mut *digest.box_clone(),
40+
),
41+
_ => Err(Error::InvalidPaddingScheme),
42+
}
43+
.map_err(|e| to_sig_error(e))
44+
}
45+
}

0 commit comments

Comments
 (0)