Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Signer/Verifier/Signature interfaces for the RSA signatures #174

Merged
merged 5 commits into from Aug 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.toml
Expand Up @@ -23,6 +23,8 @@ subtle = { version = "2.1.1", default-features = false }
digest = { version = "0.10.0", default-features = false, features = ["alloc"] }
pkcs1 = { version = "0.4", default-features = false, features = ["pkcs8", "alloc"] }
pkcs8 = { version = "0.9", default-features = false, features = ["alloc"] }
#To keep the rand_core versions properly pinnen, specify exact version
signature = { version = ">=1.5, <1.7", default-features = false , features = ["rand-preview"] }
zeroize = { version = "1", features = ["alloc"] }

# Temporary workaround until https://github.com/dignifiedquire/num-bigint/pull/42 lands
Expand Down Expand Up @@ -55,7 +57,7 @@ default = ["std", "pem"]
nightly = ["num-bigint/nightly"]
serde = ["num-bigint/serde", "serde_crate"]
expose-internals = []
std = ["digest/std", "pkcs1/std", "pkcs8/std", "rand_core/std"]
std = ["digest/std", "pkcs1/std", "pkcs8/std", "rand_core/std", "signature/std"]
pem = ["pkcs1/pem", "pkcs8/pem"]
pkcs5 = ["pkcs8/encryption"]
getrandom = ["rand_core/getrandom"]
Expand Down
26 changes: 26 additions & 0 deletions src/dummy_rng.rs
@@ -0,0 +1,26 @@
use rand_core::{CryptoRng, RngCore};

/// This is a dummy RNG for cases when we need a concrete RNG type
/// which does not get used.
#[derive(Copy, Clone)]
pub(crate) struct DummyRng;

impl RngCore for DummyRng {
fn next_u32(&mut self) -> u32 {
unimplemented!();
}

fn next_u64(&mut self) -> u64 {
unimplemented!();
}

fn fill_bytes(&mut self, _: &mut [u8]) {
unimplemented!();
}

fn try_fill_bytes(&mut self, _: &mut [u8]) -> core::result::Result<(), rand_core::Error> {
unimplemented!();
}
}

impl CryptoRng for DummyRng {}
14 changes: 14 additions & 0 deletions src/errors.rs
Expand Up @@ -64,3 +64,17 @@ impl From<pkcs8::Error> for Error {
Error::Pkcs8(err)
}
}

#[cfg(feature = "std")]
impl From<Error> for signature::Error {
fn from(err: Error) -> Self {
Self::from_source(err)
}
}

#[cfg(not(feature = "std"))]
impl From<Error> for signature::Error {
fn from(_err: Error) -> Self {
Self::new()
}
}
26 changes: 1 addition & 25 deletions src/key.rs
Expand Up @@ -10,6 +10,7 @@ use serde_crate::{Deserialize, Serialize};
use zeroize::Zeroize;

use crate::algorithms::{generate_multi_prime_key, generate_multi_prime_key_with_exp};
use crate::dummy_rng::DummyRng;
use crate::errors::{Error, Result};

use crate::padding::PaddingScheme;
Expand Down Expand Up @@ -586,31 +587,6 @@ fn check_public_with_max_size(public_key: &impl PublicKeyParts, max_size: usize)
Ok(())
}

/// This is a dummy RNG for cases when we need a concrete RNG type
/// which does not get used.
#[derive(Copy, Clone)]
struct DummyRng;

impl RngCore for DummyRng {
fn next_u32(&mut self) -> u32 {
unimplemented!();
}

fn next_u64(&mut self) -> u64 {
unimplemented!();
}

fn fill_bytes(&mut self, _: &mut [u8]) {
unimplemented!();
}

fn try_fill_bytes(&mut self, _: &mut [u8]) -> core::result::Result<(), rand_core::Error> {
unimplemented!();
}
}

impl CryptoRng for DummyRng {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
55 changes: 53 additions & 2 deletions src/lib.rs
Expand Up @@ -47,6 +47,54 @@
//! assert_eq!(&data[..], &dec_data[..]);
//! ```
//!
//! Using PKCS1v15 signatures
//! ```
//! use rsa::{Hash, RsaPrivateKey};
//! use rsa::pkcs1v15::{SigningKey, VerifyingKey};
//! use sha2::{Digest, Sha256};
//! use signature::{RandomizedSigner, Signature, Verifier};
//!
//! let mut rng = rand::thread_rng();
//!
//! let bits = 2048;
//! let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
//! let signing_key = SigningKey::new_with_hash(private_key, Hash::SHA2_256);
//! let verifying_key: VerifyingKey = (&signing_key).into();
//!
//! // Sign
//! let data = b"hello world";
//! let digest = Sha256::digest(data).to_vec();
//! let signature = signing_key.sign_with_rng(&mut rng, &digest);
//! assert_ne!(signature.as_bytes(), data);
//!
//! // Verify
//! verifying_key.verify(&digest, &signature).expect("failed to verify");
//! ```
//!
//! Using PSS signatures
//! ```
//! use rsa::{Hash, RsaPrivateKey};
//! use rsa::pss::{BlindedSigningKey, VerifyingKey};
//! use sha2::{Digest, Sha256};
//! use signature::{RandomizedSigner, Signature, Verifier};
//!
//! let mut rng = rand::thread_rng();
//!
//! let bits = 2048;
//! let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
//! let signing_key = BlindedSigningKey::new(private_key, Box::new(Sha256::new()));
//! let verifying_key: VerifyingKey = (&signing_key).into();
//!
//! // Sign
//! let data = b"hello world";
//! let digest = Sha256::digest(data).to_vec();
//! let signature = signing_key.sign_with_rng(&mut rng, &digest);
//! assert_ne!(signature.as_bytes(), data);
//!
//! // Verify
//! verifying_key.verify(&digest, &signature).expect("failed to verify");
//! ```
//!
//! ## PKCS#1 RSA Key Encoding
//!
//! PKCS#1 is a legacy format for encoding RSA keys as binary (DER) or text
Expand Down Expand Up @@ -158,12 +206,15 @@ pub mod errors;
pub mod hash;
/// Supported padding schemes.
pub mod padding;
/// RSASSA-PKCS1-v1_5 Signature support
pub mod pkcs1v15;
/// RSASSA-PSS Signature support
pub mod pss;

mod dummy_rng;
mod encoding;
mod key;
mod oaep;
mod pkcs1v15;
mod pss;
mod raw;

pub use pkcs1;
Expand Down