1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-31 09:24:31 +03:00

More key loading tests

This commit is contained in:
Quentin Gliech
2022-09-01 17:05:49 +02:00
parent 21da8e9f79
commit 7816d534cc
3 changed files with 67 additions and 30 deletions

View File

@ -94,20 +94,18 @@ macro_rules! asymetric_jwt_test {
} }
conditional! { $supported => conditional! { $supported =>
use mas_iana::jose::JsonWebKeyUse; use mas_jose::jwt::JsonWebSignatureHeader;
use mas_jose::{constraints::Constraint, jwt::JsonWebSignatureHeader};
#[test] #[test]
fn verify_jwt() { fn verify_jwt() {
let jwks = public_jwks(); let jwks = public_jwks();
let jwt: Jwt<'_, Payload> = Jwt::try_from($jwt).unwrap(); let jwt: Jwt<'_, Payload> = Jwt::try_from($jwt).unwrap();
let key = ConstraintSet::from(jwt.header()) let key = jwks.find_key(&jwt.header().into()).unwrap();
.filter(jwks.deref())[0];
let key = mas_jose::jwa::AsymmetricVerifyingKey::from_jwk_and_alg( let key = mas_jose::jwa::AsymmetricVerifyingKey::from_jwk_and_alg(
key.params(), key.params(),
JsonWebSignatureAlg::$alg JsonWebSignatureAlg::$alg,
) )
.unwrap(); .unwrap();
@ -116,34 +114,27 @@ macro_rules! asymetric_jwt_test {
#[test] #[test]
fn sign_and_verify_jwt() { fn sign_and_verify_jwt() {
let payload = Payload { hello: "world".to_string() }; let alg = JsonWebSignatureAlg::$alg;
let header = JsonWebSignatureHeader::new(JsonWebSignatureAlg::$alg); let payload = Payload {
hello: "world".to_string(),
};
let header = JsonWebSignatureHeader::new(alg);
let jwks = private_jwks(); let jwks = private_jwks();
let key = ConstraintSet::new(vec![ let key = jwks.signing_key_for_algorithm(alg).unwrap();
Constraint::alg(JsonWebSignatureAlg::$alg),
Constraint::use_(JsonWebKeyUse::Sig),
])
.filter(jwks.deref())[0];
let key = mas_jose::jwa::AsymmetricSigningKey::from_jwk_and_alg( let key = mas_jose::jwa::AsymmetricSigningKey::from_jwk_and_alg(key.params(), alg)
key.params(), .unwrap();
JsonWebSignatureAlg::$alg,
)
.unwrap();
let jwks = public_jwks();
let jwt: Jwt<'_, Payload> = Jwt::sign(header, payload, &key).unwrap(); let jwt: Jwt<'_, Payload> = Jwt::sign(header, payload, &key).unwrap();
let jwt: Jwt<'_, Payload> = Jwt::try_from(jwt.as_str()).unwrap(); let jwt: Jwt<'_, Payload> = Jwt::try_from(jwt.as_str()).unwrap();
let key = ConstraintSet::from(jwt.header()) let jwks = public_jwks();
.filter(jwks.deref())[0]; let key = jwks.find_key(&jwt.header().into()).unwrap();
let key = mas_jose::jwa::AsymmetricVerifyingKey::from_jwk_and_alg( let key =
key.params(), mas_jose::jwa::AsymmetricVerifyingKey::from_jwk_and_alg(key.params(), alg)
JsonWebSignatureAlg::$alg .unwrap();
)
.unwrap();
jwt.verify(&key).unwrap(); jwt.verify(&key).unwrap();
} }
@ -178,14 +169,13 @@ macro_rules! symetric_jwt_test {
#[test] #[test]
fn sign_and_verify_jwt() { fn sign_and_verify_jwt() {
let alg = JsonWebSignatureAlg::$alg;
let payload = Payload { let payload = Payload {
hello: "world".to_string(), hello: "world".to_string(),
}; };
let header = JsonWebSignatureHeader::new(JsonWebSignatureAlg::$alg); let header = JsonWebSignatureHeader::new(alg);
let key = let key = mas_jose::jwa::SymmetricKey::new_for_alg(oct_key(), alg).unwrap();
mas_jose::jwa::SymmetricKey::new_for_alg(oct_key(), JsonWebSignatureAlg::$alg)
.unwrap();
let jwt: Jwt<'_, Payload> = Jwt::sign(header, payload, &key).unwrap(); let jwt: Jwt<'_, Payload> = Jwt::sign(header, payload, &key).unwrap();
let jwt: Jwt<'_, Payload> = Jwt::try_from(jwt.as_str()).unwrap(); let jwt: Jwt<'_, Payload> = Jwt::try_from(jwt.as_str()).unwrap();

View File

@ -114,8 +114,27 @@ pub enum LoadError {
}, },
} }
impl LoadError {
/// Returns `true` if the load error is [`Encrypted`].
///
/// [`Encrypted`]: LoadError::Encrypted
#[must_use]
pub fn is_encrypted(&self) -> bool {
matches!(self, Self::Encrypted)
}
/// Returns `true` if the load error is [`Unencrypted`].
///
/// [`Unencrypted`]: LoadError::Unencrypted
#[must_use]
pub fn is_unencrypted(&self) -> bool {
matches!(self, Self::Unencrypted)
}
}
/// A single private key /// A single private key
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug)]
pub enum PrivateKey { pub enum PrivateKey {
Rsa(Box<rsa::RsaPrivateKey>), Rsa(Box<rsa::RsaPrivateKey>),
EcP256(Box<elliptic_curve::SecretKey<p256::NistP256>>), EcP256(Box<elliptic_curve::SecretKey<p256::NistP256>>),
@ -278,7 +297,7 @@ impl PrivateKey {
|| sec1::EcPrivateKey::from_der(der).is_ok() || sec1::EcPrivateKey::from_der(der).is_ok()
|| pkcs1::RsaPrivateKey::from_der(der).is_ok() || pkcs1::RsaPrivateKey::from_der(der).is_ok()
{ {
return Err(LoadError::Encrypted); return Err(LoadError::Unencrypted);
} }
Err(LoadError::UnsupportedFormat) Err(LoadError::UnsupportedFormat)

View File

@ -20,6 +20,8 @@ use mas_keystore::PrivateKey;
static PASSWORD: &str = "hunter2"; static PASSWORD: &str = "hunter2";
/// Generate a test which loads a key, and then tries signing and verifying a
/// JWT for each available algorithm
macro_rules! plain_test { macro_rules! plain_test {
($name:ident, $kind:ident, $path:literal) => { ($name:ident, $kind:ident, $path:literal) => {
#[test] #[test]
@ -43,6 +45,8 @@ macro_rules! plain_test {
}; };
} }
/// Generate a test which loads an encrypted key, and then tries signing and
/// verifying a JWT for each available algorithm
macro_rules! enc_test { macro_rules! enc_test {
($name:ident, $kind:ident, $path:literal) => { ($name:ident, $kind:ident, $path:literal) => {
#[test] #[test]
@ -66,6 +70,7 @@ macro_rules! enc_test {
}; };
} }
/// Generate a PEM decoding and encoding test
macro_rules! pem_test { macro_rules! pem_test {
($name:ident, $path:literal) => { ($name:ident, $path:literal) => {
pem_test!($name, $path, compare = true); pem_test!($name, $path, compare = true);
@ -84,6 +89,7 @@ macro_rules! pem_test {
}; };
} }
/// Generate a DER decoding and encoding test
macro_rules! der_test { macro_rules! der_test {
($name:ident, $path:literal) => { ($name:ident, $path:literal) => {
der_test!($name, $path, compare = true); der_test!($name, $path, compare = true);
@ -138,3 +144,25 @@ pem_test!(serialize_ec_p384_sec1_pem, "ec-p384.sec1");
der_test!(serialize_ec_p384_sec1_der, "ec-p384.sec1", compare = false); der_test!(serialize_ec_p384_sec1_der, "ec-p384.sec1", compare = false);
pem_test!(serialize_ec_k256_sec1_pem, "ec-k256.sec1"); pem_test!(serialize_ec_k256_sec1_pem, "ec-k256.sec1");
der_test!(serialize_ec_k256_sec1_der, "ec-k256.sec1", compare = false); der_test!(serialize_ec_k256_sec1_der, "ec-k256.sec1", compare = false);
#[test]
fn load_encrypted_as_unencrypted_error() {
let pem = include_str!("./keys/rsa.pkcs8.encrypted.pem");
assert!(PrivateKey::load_pem(pem).unwrap_err().is_encrypted());
let der = include_bytes!("./keys/rsa.pkcs8.encrypted.der");
assert!(PrivateKey::load_der(der).unwrap_err().is_encrypted());
}
#[test]
fn load_unencrypted_as_encrypted_error() {
let pem = include_str!("./keys/rsa.pkcs8.pem");
assert!(PrivateKey::load_encrypted_pem(pem, PASSWORD)
.unwrap_err()
.is_unencrypted());
let der = include_bytes!("./keys/rsa.pkcs8.der");
assert!(PrivateKey::load_encrypted_der(der, PASSWORD)
.unwrap_err()
.is_unencrypted());
}