You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-08-07 17:03:01 +03:00
Fix RSA JWT signature and add snapshot tests for JWT signature
This commit is contained in:
@@ -13,8 +13,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
use mas_iana::jose::{JsonWebKeyEcEllipticCurve, JsonWebSignatureAlg};
|
||||
use rand::thread_rng;
|
||||
use signature::RandomizedSigner;
|
||||
use thiserror::Error;
|
||||
|
||||
use super::signature::Signature;
|
||||
@@ -159,43 +157,47 @@ impl From<super::Es256KSigningKey> for AsymmetricSigningKey {
|
||||
}
|
||||
}
|
||||
|
||||
impl signature::Signer<Signature> for AsymmetricSigningKey {
|
||||
fn try_sign(&self, msg: &[u8]) -> Result<Signature, signature::Error> {
|
||||
impl signature::RandomizedSigner<Signature> for AsymmetricSigningKey {
|
||||
fn try_sign_with_rng(
|
||||
&self,
|
||||
rng: impl rand::CryptoRng + rand::RngCore,
|
||||
msg: &[u8],
|
||||
) -> Result<Signature, signature::Error> {
|
||||
match self {
|
||||
Self::Rs256(key) => {
|
||||
let signature = key.try_sign(msg)?;
|
||||
let signature = key.try_sign_with_rng(rng, msg)?;
|
||||
Ok(Signature::from_signature(&signature))
|
||||
}
|
||||
Self::Rs384(key) => {
|
||||
let signature = key.try_sign(msg)?;
|
||||
let signature = key.try_sign_with_rng(rng, msg)?;
|
||||
Ok(Signature::from_signature(&signature))
|
||||
}
|
||||
Self::Rs512(key) => {
|
||||
let signature = key.try_sign(msg)?;
|
||||
let signature = key.try_sign_with_rng(rng, msg)?;
|
||||
Ok(Signature::from_signature(&signature))
|
||||
}
|
||||
Self::Ps256(key) => {
|
||||
let signature = key.try_sign_with_rng(thread_rng(), msg)?;
|
||||
let signature = key.try_sign_with_rng(rng, msg)?;
|
||||
Ok(Signature::from_signature(&signature))
|
||||
}
|
||||
Self::Ps384(key) => {
|
||||
let signature = key.try_sign_with_rng(thread_rng(), msg)?;
|
||||
let signature = key.try_sign_with_rng(rng, msg)?;
|
||||
Ok(Signature::from_signature(&signature))
|
||||
}
|
||||
Self::Ps512(key) => {
|
||||
let signature = key.try_sign_with_rng(thread_rng(), msg)?;
|
||||
let signature = key.try_sign_with_rng(rng, msg)?;
|
||||
Ok(Signature::from_signature(&signature))
|
||||
}
|
||||
Self::Es256(key) => {
|
||||
let signature = key.try_sign(msg)?;
|
||||
let signature = key.try_sign_with_rng(rng, msg)?;
|
||||
Ok(Signature::from_signature(&signature))
|
||||
}
|
||||
Self::Es384(key) => {
|
||||
let signature = key.try_sign(msg)?;
|
||||
let signature = key.try_sign_with_rng(rng, msg)?;
|
||||
Ok(Signature::from_signature(&signature))
|
||||
}
|
||||
Self::Es256K(key) => {
|
||||
let signature = key.try_sign(msg)?;
|
||||
let signature = key.try_sign_with_rng(rng, msg)?;
|
||||
Ok(Signature::from_signature(&signature))
|
||||
}
|
||||
}
|
||||
|
@@ -79,6 +79,17 @@ impl From<super::Hs512Key> for SymmetricKey {
|
||||
}
|
||||
}
|
||||
|
||||
impl signature::RandomizedSigner<Signature> for SymmetricKey {
|
||||
fn try_sign_with_rng(
|
||||
&self,
|
||||
_rng: impl rand::CryptoRng + rand::RngCore,
|
||||
msg: &[u8],
|
||||
) -> Result<Signature, signature::Error> {
|
||||
// XXX: is that implementation alright?
|
||||
signature::Signer::try_sign(self, msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl signature::Signer<Signature> for SymmetricKey {
|
||||
fn try_sign(&self, msg: &[u8]) -> Result<Signature, signature::Error> {
|
||||
match self {
|
||||
|
@@ -271,7 +271,7 @@ mod rsa_impls {
|
||||
type Error = rsa::errors::Error;
|
||||
fn try_from(value: &RsaPrivateParameters) -> Result<Self, Self::Error> {
|
||||
let key: RsaPrivateKey = value.try_into()?;
|
||||
Ok(Self::new(key))
|
||||
Ok(Self::new_with_salt_len(key, <H as Digest>::output_size()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -13,8 +13,9 @@
|
||||
// limitations under the License.
|
||||
|
||||
use base64ct::{Base64UrlUnpadded, Encoding};
|
||||
use rand::{thread_rng, CryptoRng, RngCore};
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use signature::{Signature, Signer, Verifier};
|
||||
use signature::{RandomizedSigner, Signature, Verifier};
|
||||
use thiserror::Error;
|
||||
|
||||
use super::{header::JsonWebSignatureHeader, raw::RawJwt};
|
||||
@@ -279,6 +280,12 @@ pub enum JwtSignatureError {
|
||||
#[source]
|
||||
inner: serde_json::Error,
|
||||
},
|
||||
|
||||
#[error("failed to sign")]
|
||||
Signature {
|
||||
#[from]
|
||||
inner: signature::Error,
|
||||
},
|
||||
}
|
||||
|
||||
impl JwtSignatureError {
|
||||
@@ -298,7 +305,22 @@ impl<T> Jwt<'static, T> {
|
||||
key: &K,
|
||||
) -> Result<Self, JwtSignatureError>
|
||||
where
|
||||
K: Signer<S>,
|
||||
K: RandomizedSigner<S>,
|
||||
S: Signature,
|
||||
T: Serialize,
|
||||
{
|
||||
Self::sign_with_rng(thread_rng(), header, payload, key)
|
||||
}
|
||||
|
||||
pub fn sign_with_rng<R, K, S>(
|
||||
rng: R,
|
||||
header: JsonWebSignatureHeader,
|
||||
payload: T,
|
||||
key: &K,
|
||||
) -> Result<Self, JwtSignatureError>
|
||||
where
|
||||
R: CryptoRng + RngCore,
|
||||
K: RandomizedSigner<S>,
|
||||
S: Signature,
|
||||
T: Serialize,
|
||||
{
|
||||
@@ -313,7 +335,10 @@ impl<T> Jwt<'static, T> {
|
||||
let first_dot = header_.len();
|
||||
let second_dot = inner.len();
|
||||
|
||||
let signature = key.sign(inner.as_bytes()).as_bytes().to_vec();
|
||||
let signature = key
|
||||
.try_sign_with_rng(rng, inner.as_bytes())?
|
||||
.as_bytes()
|
||||
.to_vec();
|
||||
let signature_ = Base64UrlUnpadded::encode_string(&signature);
|
||||
inner.reserve_exact(1 + signature_.len());
|
||||
inner.push('.');
|
||||
|
Reference in New Issue
Block a user