1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-08-09 04:22:45 +03:00

Use a published version of RSA again

This commit is contained in:
Quentin Gliech
2022-09-01 15:23:51 +02:00
parent a70032c8e1
commit 97ed342ca0
8 changed files with 95 additions and 126 deletions

4
Cargo.lock generated
View File

@@ -3811,7 +3811,8 @@ dependencies = [
[[package]] [[package]]
name = "rsa" name = "rsa"
version = "0.7.0-pre" version = "0.7.0-pre"
source = "git+https://github.com/RustCrypto/RSA.git#40242fbbb019cac4af216145bfa468a0d24d12ef" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6168b9a0f38e487db90dc109ad6d8f37fc5590183b7bfe8d8687e0b86116d53f"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"digest 0.10.3", "digest 0.10.3",
@@ -3822,7 +3823,6 @@ dependencies = [
"pkcs1", "pkcs1",
"pkcs8", "pkcs8",
"rand_core", "rand_core",
"signature",
"smallvec", "smallvec",
"subtle", "subtle",
"zeroize", "zeroize",

View File

@@ -18,7 +18,7 @@ k256 = { version = "0.11.2", features = ["ecdsa"] }
p256 = { version = "0.11.1", features = ["ecdsa"] } p256 = { version = "0.11.1", features = ["ecdsa"] }
p384 = { version = "0.11.2", features = ["ecdsa"] } p384 = { version = "0.11.2", features = ["ecdsa"] }
rand = "0.8.5" rand = "0.8.5"
rsa = { git = "https://github.com/RustCrypto/RSA.git" } rsa = "0.7.0-pre"
schemars = "0.8.10" schemars = "0.8.10"
sec1 = "0.3.0" sec1 = "0.3.0"
serde = { version = "1.0.144", features = ["derive"] } serde = { version = "1.0.144", features = ["derive"] }

View File

@@ -15,6 +15,8 @@
// This is a temporary wrapper until the RSA crate actually hashes the input // This is a temporary wrapper until the RSA crate actually hashes the input
// See <https://github.com/RustCrypto/RSA/pull/174#issuecomment-1227330296> // See <https://github.com/RustCrypto/RSA/pull/174#issuecomment-1227330296>
use super::signature::Signature;
pub trait RsaHashIdentifier { pub trait RsaHashIdentifier {
const HASH: rsa::Hash; const HASH: rsa::Hash;
} }
@@ -39,67 +41,62 @@ pub(crate) mod pkcs1v15 {
use std::marker::PhantomData; use std::marker::PhantomData;
use digest::Digest; use digest::Digest;
use rsa::{RsaPrivateKey, RsaPublicKey}; use rsa::{PaddingScheme, PublicKey, RsaPrivateKey, RsaPublicKey};
use super::RsaHashIdentifier; use super::{RsaHashIdentifier, Signature};
pub struct VerifyingKey<H> { pub struct VerifyingKey<H> {
inner: rsa::pkcs1v15::VerifyingKey, inner: RsaPublicKey,
hash: PhantomData<H>, hash: PhantomData<H>,
} }
impl<H> From<RsaPublicKey> for VerifyingKey<H> impl<H> From<RsaPublicKey> for VerifyingKey<H> {
where fn from(inner: RsaPublicKey) -> Self {
H: RsaHashIdentifier,
{
fn from(key: RsaPublicKey) -> Self {
let inner = rsa::pkcs1v15::VerifyingKey::new_with_hash(key, H::HASH);
Self { Self {
inner, inner,
hash: PhantomData::default(), hash: PhantomData,
} }
} }
} }
impl<H> signature::Verifier<rsa::pkcs1v15::Signature> for VerifyingKey<H> impl<H> signature::Verifier<Signature> for VerifyingKey<H>
where where
H: Digest, H: Digest + RsaHashIdentifier,
{ {
fn verify( fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), signature::Error> {
&self,
msg: &[u8],
signature: &rsa::pkcs1v15::Signature,
) -> Result<(), signature::Error> {
let digest = H::digest(msg); let digest = H::digest(msg);
self.inner.verify(&digest, signature) let padding = PaddingScheme::new_pkcs1v15_sign(Some(H::HASH));
self.inner
.verify(padding, &digest, signature.as_ref())
.map_err(signature::Error::from_source)
} }
} }
pub struct SigningKey<H> { pub struct SigningKey<H> {
inner: rsa::pkcs1v15::SigningKey, inner: RsaPrivateKey,
hash: PhantomData<H>, hash: PhantomData<H>,
} }
impl<H> From<RsaPrivateKey> for SigningKey<H> impl<H> From<RsaPrivateKey> for SigningKey<H> {
where fn from(inner: RsaPrivateKey) -> Self {
H: RsaHashIdentifier,
{
fn from(key: RsaPrivateKey) -> Self {
let inner = rsa::pkcs1v15::SigningKey::new_with_hash(key, H::HASH);
Self { Self {
inner, inner,
hash: PhantomData::default(), hash: PhantomData,
} }
} }
} }
impl<H> signature::Signer<rsa::pkcs1v15::Signature> for SigningKey<H> impl<H> signature::Signer<Signature> for SigningKey<H>
where where
H: Digest, H: Digest + RsaHashIdentifier,
{ {
fn try_sign(&self, msg: &[u8]) -> Result<rsa::pkcs1v15::Signature, signature::Error> { fn try_sign(&self, msg: &[u8]) -> Result<Signature, signature::Error> {
let digest = H::digest(msg); let digest = H::digest(msg);
self.inner.try_sign(&digest) let padding = PaddingScheme::new_pkcs1v15_sign(Some(H::HASH));
self.inner
.sign(padding, &digest)
.map_err(signature::Error::from_source)
.map(Signature::new)
} }
} }
} }
@@ -109,66 +106,62 @@ pub(crate) mod pss {
use digest::{Digest, DynDigest}; use digest::{Digest, DynDigest};
use rand::thread_rng; use rand::thread_rng;
use rsa::{RsaPrivateKey, RsaPublicKey}; use rsa::{PaddingScheme, PublicKey, RsaPrivateKey, RsaPublicKey};
use signature::RandomizedSigner;
use super::Signature;
pub struct VerifyingKey<H> { pub struct VerifyingKey<H> {
inner: rsa::pss::VerifyingKey, inner: RsaPublicKey,
hash: PhantomData<H>, hash: PhantomData<H>,
} }
impl<H> From<RsaPublicKey> for VerifyingKey<H> impl<H> From<RsaPublicKey> for VerifyingKey<H> {
where fn from(inner: RsaPublicKey) -> Self {
H: DynDigest + Default + 'static,
{
fn from(key: RsaPublicKey) -> Self {
let inner = rsa::pss::VerifyingKey::new(key, Box::new(H::default()));
Self { Self {
inner, inner,
hash: PhantomData::default(), hash: PhantomData,
} }
} }
} }
impl<H> signature::Verifier<rsa::pss::Signature> for VerifyingKey<H> impl<H> signature::Verifier<Signature> for VerifyingKey<H>
where where
H: Digest, H: Digest + DynDigest + 'static,
{ {
fn verify( fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), signature::Error> {
&self,
msg: &[u8],
signature: &rsa::pss::Signature,
) -> Result<(), signature::Error> {
let digest = H::digest(msg); let digest = H::digest(msg);
self.inner.verify(&digest, signature) let padding = PaddingScheme::new_pss::<H, _>(thread_rng());
self.inner
.verify(padding, &digest, signature.as_ref())
.map_err(signature::Error::from_source)
} }
} }
pub struct SigningKey<H> { pub struct SigningKey<H> {
inner: rsa::pss::SigningKey, inner: RsaPrivateKey,
hash: PhantomData<H>, hash: PhantomData<H>,
} }
impl<H> From<RsaPrivateKey> for SigningKey<H> impl<H> From<RsaPrivateKey> for SigningKey<H> {
where fn from(inner: RsaPrivateKey) -> Self {
H: DynDigest + Default + 'static,
{
fn from(key: RsaPrivateKey) -> Self {
let inner = rsa::pss::SigningKey::new(key, Box::new(H::default()));
Self { Self {
inner, inner,
hash: PhantomData::default(), hash: PhantomData,
} }
} }
} }
impl<H> signature::Signer<rsa::pss::Signature> for SigningKey<H> impl<H> signature::Signer<Signature> for SigningKey<H>
where where
H: Digest, H: Digest + DynDigest + 'static,
{ {
fn try_sign(&self, msg: &[u8]) -> Result<rsa::pss::Signature, signature::Error> { fn try_sign(&self, msg: &[u8]) -> Result<Signature, signature::Error> {
let digest = H::digest(msg); let digest = H::digest(msg);
self.inner.try_sign_with_rng(thread_rng(), &digest) let padding = PaddingScheme::new_pss::<H, _>(thread_rng());
self.inner
.sign(padding, &digest)
.map_err(signature::Error::from_source)
.map(Signature::new)
} }
} }
} }

View File

@@ -34,6 +34,10 @@ impl signature::Signature for Signature {
} }
impl Signature { impl Signature {
pub fn new(bytes: Vec<u8>) -> Self {
Self { bytes }
}
pub fn from_signature<S>(signature: &S) -> Self pub fn from_signature<S>(signature: &S) -> Self
where where
S: signature::Signature, S: signature::Signature,

View File

@@ -298,7 +298,11 @@ mod rsa_impls {
.map(|i| BigUint::from_bytes_be(i)) .map(|i| BigUint::from_bytes_be(i))
.collect(); .collect();
RsaPrivateKey::from_components(n, e, d, primes) let key = RsaPrivateKey::from_components(n, e, d, primes);
key.validate()?;
Ok(key)
} }
} }
} }

View File

@@ -20,7 +20,7 @@ pem-rfc7468 = { version = "0.6.0", features = ["std"] }
pkcs1 = { version = "0.4.0", features = ["std"] } pkcs1 = { version = "0.4.0", features = ["std"] }
pkcs8 = { version = "0.9.0", features = ["std", "pkcs5", "encryption"] } pkcs8 = { version = "0.9.0", features = ["std", "pkcs5", "encryption"] }
rand = "0.8.5" rand = "0.8.5"
rsa = { git = "https://github.com/RustCrypto/RSA.git", features = ["std", "pem"] } rsa = { version = "0.7.0-pre", features = ["std", "pem"] }
sec1 = { version = "0.3.0", features = ["std"] } sec1 = { version = "0.3.0", features = ["std"] }
spki = { version = "0.6.0", features = ["std"] } spki = { version = "0.6.0", features = ["std"] }
thiserror = "1.0.32" thiserror = "1.0.32"

View File

@@ -144,7 +144,7 @@ impl PrivateKey {
let first_prime = BigUint::from_bytes_be(pkcs1_key.prime1.as_bytes()); let first_prime = BigUint::from_bytes_be(pkcs1_key.prime1.as_bytes());
let second_prime = BigUint::from_bytes_be(pkcs1_key.prime2.as_bytes()); let second_prime = BigUint::from_bytes_be(pkcs1_key.prime2.as_bytes());
let primes = vec![first_prime, second_prime]; let primes = vec![first_prime, second_prime];
let key = rsa::RsaPrivateKey::from_components(n, e, d, primes)?; let key = rsa::RsaPrivateKey::from_components(n, e, d, primes);
Ok(Self::Rsa(Box::new(key))) Ok(Self::Rsa(Box::new(key)))
} }

View File

@@ -20,22 +20,22 @@ use mas_keystore::PrivateKey;
static PASSWORD: &str = "hunter2"; static PASSWORD: &str = "hunter2";
macro_rules! load_test { macro_rules! plain_test {
($name:ident, $kind:ident, $path:literal) => { ($name:ident, $kind:ident, $path:literal) => {
#[test] #[test]
fn $name() { fn $name() {
let bytes = include_bytes!($path); let bytes = include_bytes!(concat!("./keys/", $path));
let key = PrivateKey::load(bytes).unwrap(); let key = PrivateKey::load(bytes).unwrap();
assert!(matches!(key, PrivateKey::$kind(_)), "wrong key type"); assert!(matches!(key, PrivateKey::$kind(_)), "wrong key type");
} }
}; };
} }
macro_rules! load_encrypted_test { macro_rules! enc_test {
($name:ident, $kind:ident, $path:literal) => { ($name:ident, $kind:ident, $path:literal) => {
#[test] #[test]
fn $name() { fn $name() {
let bytes = include_bytes!($path); let bytes = include_bytes!(concat!("./keys/", $path));
let key = PrivateKey::load_encrypted(bytes, PASSWORD).unwrap(); let key = PrivateKey::load_encrypted(bytes, PASSWORD).unwrap();
assert!(matches!(key, PrivateKey::$kind(_)), "wrong key type"); assert!(matches!(key, PrivateKey::$kind(_)), "wrong key type");
@@ -54,60 +54,28 @@ macro_rules! load_encrypted_test {
}; };
} }
load_test!(load_rsa_pkcs1_pem, Rsa, "./keys/rsa.pkcs1.pem"); plain_test!(plain_rsa_pkcs1_pem, Rsa, "rsa.pkcs1.pem");
load_test!(load_rsa_pkcs1_der, Rsa, "./keys/rsa.pkcs1.der"); plain_test!(plain_rsa_pkcs1_der, Rsa, "rsa.pkcs1.der");
load_test!(load_rsa_pkcs8_pem, Rsa, "./keys/rsa.pkcs8.pem"); plain_test!(plain_rsa_pkcs8_pem, Rsa, "rsa.pkcs8.pem");
load_test!(load_rsa_pkcs8_der, Rsa, "./keys/rsa.pkcs8.der"); plain_test!(plain_rsa_pkcs8_der, Rsa, "rsa.pkcs8.der");
load_test!(load_ec_p256_sec1_pem, EcP256, "./keys/ec-p256.sec1.pem"); plain_test!(plain_ec_p256_sec1_pem, EcP256, "ec-p256.sec1.pem");
load_test!(load_ec_p256_sec1_der, EcP256, "./keys/ec-p256.sec1.der"); plain_test!(plain_ec_p256_sec1_der, EcP256, "ec-p256.sec1.der");
load_test!(load_ec_p256_pkcs8_pem, EcP256, "./keys/ec-p256.pkcs8.pem"); plain_test!(plain_ec_p256_pkcs8_pem, EcP256, "ec-p256.pkcs8.pem");
load_test!(load_ec_p256_pkcs8_der, EcP256, "./keys/ec-p256.pkcs8.der"); plain_test!(plain_ec_p256_pkcs8_der, EcP256, "ec-p256.pkcs8.der");
load_test!(load_ec_p384_sec1_pem, EcP384, "./keys/ec-p384.sec1.pem"); plain_test!(plain_ec_p384_sec1_pem, EcP384, "ec-p384.sec1.pem");
load_test!(load_ec_p384_sec1_der, EcP384, "./keys/ec-p384.sec1.der"); plain_test!(plain_ec_p384_sec1_der, EcP384, "ec-p384.sec1.der");
load_test!(load_ec_p384_pkcs8_pem, EcP384, "./keys/ec-p384.pkcs8.pem"); plain_test!(plain_ec_p384_pkcs8_pem, EcP384, "ec-p384.pkcs8.pem");
load_test!(load_ec_p384_pkcs8_der, EcP384, "./keys/ec-p384.pkcs8.der"); plain_test!(plain_ec_p384_pkcs8_der, EcP384, "ec-p384.pkcs8.der");
load_test!(load_ec_k256_sec1_pem, EcK256, "./keys/ec-k256.sec1.pem"); plain_test!(plain_ec_k256_sec1_pem, EcK256, "ec-k256.sec1.pem");
load_test!(load_ec_k256_sec1_der, EcK256, "./keys/ec-k256.sec1.der"); plain_test!(plain_ec_k256_sec1_der, EcK256, "ec-k256.sec1.der");
load_test!(load_ec_k256_pkcs8_pem, EcK256, "./keys/ec-k256.pkcs8.pem"); plain_test!(plain_ec_k256_pkcs8_pem, EcK256, "ec-k256.pkcs8.pem");
load_test!(load_ec_k256_pkcs8_der, EcK256, "./keys/ec-k256.pkcs8.der"); plain_test!(plain_ec_k256_pkcs8_der, EcK256, "ec-k256.pkcs8.der");
load_encrypted_test!( enc_test!(enc_rsa_pkcs8_pem, Rsa, "rsa.pkcs8.encrypted.pem");
load_encrypted_rsa_pkcs8_pem, enc_test!(enc_rsa_pkcs8_der, Rsa, "rsa.pkcs8.encrypted.der");
Rsa, enc_test!(enc_ec_p256_pkcs8_pem, EcP256, "ec-p256.pkcs8.encrypted.pem");
"./keys/rsa.pkcs8.encrypted.pem" enc_test!(enc_ec_p256_pkcs8_der, EcP256, "ec-p256.pkcs8.encrypted.der");
); enc_test!(enc_ec_p384_pkcs8_pem, EcP384, "ec-p384.pkcs8.encrypted.pem");
load_encrypted_test!( enc_test!(enc_ec_p384_pkcs8_der, EcP384, "ec-p384.pkcs8.encrypted.der");
load_encrypted_rsa_pkcs8_der, enc_test!(enc_ec_k256_pkcs8_pem, EcK256, "ec-k256.pkcs8.encrypted.pem");
Rsa, enc_test!(enc_ec_k256_pkcs8_der, EcK256, "ec-k256.pkcs8.encrypted.der");
"./keys/rsa.pkcs8.encrypted.der"
);
load_encrypted_test!(
load_encrypted_ec_p256_pkcs8_pem,
EcP256,
"./keys/ec-p256.pkcs8.encrypted.pem"
);
load_encrypted_test!(
load_encrypted_ec_p256_pkcs8_der,
EcP256,
"./keys/ec-p256.pkcs8.encrypted.der"
);
load_encrypted_test!(
load_encrypted_ec_p384_pkcs8_pem,
EcP384,
"./keys/ec-p384.pkcs8.encrypted.pem"
);
load_encrypted_test!(
load_encrypted_ec_p384_pkcs8_der,
EcP384,
"./keys/ec-p384.pkcs8.encrypted.der"
);
load_encrypted_test!(
load_encrypted_ec_k256_pkcs8_pem,
EcK256,
"./keys/ec-k256.pkcs8.encrypted.pem"
);
load_encrypted_test!(
load_encrypted_ec_k256_pkcs8_der,
EcK256,
"./keys/ec-k256.pkcs8.encrypted.der"
);