1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-08-07 17:03:01 +03:00

Split the asymmetric and symmetric keys enums

This commit is contained in:
Quentin Gliech
2022-09-01 14:49:58 +02:00
parent 4e94584a4a
commit a70032c8e1
12 changed files with 617 additions and 747 deletions

View File

@@ -0,0 +1,367 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use mas_iana::jose::{JsonWebKeyEcEllipticCurve, JsonWebSignatureAlg};
use thiserror::Error;
use super::signature::Signature;
use crate::jwk::{JsonWebKeyPrivateParameters, JsonWebKeyPublicParameters};
#[derive(Debug, Error)]
pub enum AsymmetricKeyFromJwkError {
#[error("Invalid RSA parameters")]
Rsa {
#[from]
inner: rsa::errors::Error,
},
#[error("Invalid Elliptic Curve parameters")]
Ecdsa {
#[from]
inner: ecdsa::Error,
},
#[error("Unsupported algorithm {alg}")]
UnsupportedAlgorithm { alg: JsonWebSignatureAlg },
#[error("Key not suitable for algorithm {alg}")]
KeyNotSuitable { alg: JsonWebSignatureAlg },
}
/// An enum of all supported asymmetric signature algorithms verifying keys
#[non_exhaustive]
pub enum AsymmetricSigningKey {
Rs256(super::Rs256SigningKey),
Rs384(super::Rs384SigningKey),
Rs512(super::Rs512SigningKey),
Ps256(super::Ps256SigningKey),
Ps384(super::Ps384SigningKey),
Ps512(super::Ps512SigningKey),
Es256(super::Es256SigningKey),
Es384(super::Es384SigningKey),
Es256K(super::Es256KSigningKey),
}
impl AsymmetricSigningKey {
#[allow(dead_code)]
pub fn from_jwk_and_alg(
params: &JsonWebKeyPrivateParameters,
alg: JsonWebSignatureAlg,
) -> Result<Self, AsymmetricKeyFromJwkError> {
match (params, alg) {
(JsonWebKeyPrivateParameters::Rsa(params), alg) => {
let key = rsa::RsaPrivateKey::try_from(params)?;
match alg {
JsonWebSignatureAlg::Rs256 => Ok(Self::Rs256(key.into())),
JsonWebSignatureAlg::Rs384 => Ok(Self::Rs384(key.into())),
JsonWebSignatureAlg::Rs512 => Ok(Self::Rs512(key.into())),
JsonWebSignatureAlg::Ps256 => Ok(Self::Ps256(key.into())),
JsonWebSignatureAlg::Ps384 => Ok(Self::Ps384(key.into())),
JsonWebSignatureAlg::Ps512 => Ok(Self::Ps512(key.into())),
_ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg }),
}
}
(JsonWebKeyPrivateParameters::Ec(params), JsonWebSignatureAlg::Es256)
if params.crv == JsonWebKeyEcEllipticCurve::P256 =>
{
Ok(Self::Es256(params.try_into()?))
}
(JsonWebKeyPrivateParameters::Ec(params), JsonWebSignatureAlg::Es384)
if params.crv == JsonWebKeyEcEllipticCurve::P384 =>
{
Ok(Self::Es384(params.try_into()?))
}
(JsonWebKeyPrivateParameters::Ec(params), JsonWebSignatureAlg::Es512)
if params.crv == JsonWebKeyEcEllipticCurve::P521 =>
{
Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg })
}
(JsonWebKeyPrivateParameters::Ec(params), JsonWebSignatureAlg::Es256K)
if params.crv == JsonWebKeyEcEllipticCurve::Secp256K1 =>
{
Ok(Self::Es256K(params.try_into()?))
}
(JsonWebKeyPrivateParameters::Okp(_params), JsonWebSignatureAlg::EdDsa) => {
Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg })
}
_ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg }),
}
}
}
impl From<super::Rs256SigningKey> for AsymmetricSigningKey {
fn from(key: super::Rs256SigningKey) -> Self {
Self::Rs256(key)
}
}
impl From<super::Rs384SigningKey> for AsymmetricSigningKey {
fn from(key: super::Rs384SigningKey) -> Self {
Self::Rs384(key)
}
}
impl From<super::Rs512SigningKey> for AsymmetricSigningKey {
fn from(key: super::Rs512SigningKey) -> Self {
Self::Rs512(key)
}
}
impl From<super::Ps256SigningKey> for AsymmetricSigningKey {
fn from(key: super::Ps256SigningKey) -> Self {
Self::Ps256(key)
}
}
impl From<super::Ps384SigningKey> for AsymmetricSigningKey {
fn from(key: super::Ps384SigningKey) -> Self {
Self::Ps384(key)
}
}
impl From<super::Ps512SigningKey> for AsymmetricSigningKey {
fn from(key: super::Ps512SigningKey) -> Self {
Self::Ps512(key)
}
}
impl From<super::Es256SigningKey> for AsymmetricSigningKey {
fn from(key: super::Es256SigningKey) -> Self {
Self::Es256(key)
}
}
impl From<super::Es384SigningKey> for AsymmetricSigningKey {
fn from(key: super::Es384SigningKey) -> Self {
Self::Es384(key)
}
}
impl From<super::Es256KSigningKey> for AsymmetricSigningKey {
fn from(key: super::Es256KSigningKey) -> Self {
Self::Es256K(key)
}
}
impl signature::Signer<Signature> for AsymmetricSigningKey {
fn try_sign(&self, msg: &[u8]) -> Result<Signature, signature::Error> {
match self {
Self::Rs256(key) => {
let signature = key.try_sign(msg)?;
Ok(Signature::from_signature(&signature))
}
Self::Rs384(key) => {
let signature = key.try_sign(msg)?;
Ok(Signature::from_signature(&signature))
}
Self::Rs512(key) => {
let signature = key.try_sign(msg)?;
Ok(Signature::from_signature(&signature))
}
Self::Ps256(key) => {
let signature = key.try_sign(msg)?;
Ok(Signature::from_signature(&signature))
}
Self::Ps384(key) => {
let signature = key.try_sign(msg)?;
Ok(Signature::from_signature(&signature))
}
Self::Ps512(key) => {
let signature = key.try_sign(msg)?;
Ok(Signature::from_signature(&signature))
}
Self::Es256(key) => {
let signature = key.try_sign(msg)?;
Ok(Signature::from_signature(&signature))
}
Self::Es384(key) => {
let signature = key.try_sign(msg)?;
Ok(Signature::from_signature(&signature))
}
Self::Es256K(key) => {
let signature = key.try_sign(msg)?;
Ok(Signature::from_signature(&signature))
}
}
}
}
/// An enum of all supported asymmetric signature algorithms signing keys
#[non_exhaustive]
pub enum AsymmetricVerifyingKey {
Rs256(super::Rs256VerifyingKey),
Rs384(super::Rs384VerifyingKey),
Rs512(super::Rs512VerifyingKey),
Ps256(super::Ps256VerifyingKey),
Ps384(super::Ps384VerifyingKey),
Ps512(super::Ps512VerifyingKey),
Es256(super::Es256VerifyingKey),
Es384(super::Es384VerifyingKey),
Es256K(super::Es256KVerifyingKey),
}
impl AsymmetricVerifyingKey {
pub fn from_jwk_and_alg(
params: &JsonWebKeyPublicParameters,
alg: JsonWebSignatureAlg,
) -> Result<Self, AsymmetricKeyFromJwkError> {
match (params, alg) {
(JsonWebKeyPublicParameters::Rsa(params), alg) => {
let key = rsa::RsaPublicKey::try_from(params)?;
match alg {
JsonWebSignatureAlg::Rs256 => Ok(Self::Rs256(key.into())),
JsonWebSignatureAlg::Rs384 => Ok(Self::Rs384(key.into())),
JsonWebSignatureAlg::Rs512 => Ok(Self::Rs512(key.into())),
JsonWebSignatureAlg::Ps256 => Ok(Self::Ps256(key.into())),
JsonWebSignatureAlg::Ps384 => Ok(Self::Ps384(key.into())),
JsonWebSignatureAlg::Ps512 => Ok(Self::Ps512(key.into())),
_ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg }),
}
}
(JsonWebKeyPublicParameters::Ec(params), JsonWebSignatureAlg::Es256)
if params.crv == JsonWebKeyEcEllipticCurve::P256 =>
{
Ok(Self::Es256(params.try_into()?))
}
(JsonWebKeyPublicParameters::Ec(params), JsonWebSignatureAlg::Es384)
if params.crv == JsonWebKeyEcEllipticCurve::P384 =>
{
Ok(Self::Es384(params.try_into()?))
}
(JsonWebKeyPublicParameters::Ec(params), JsonWebSignatureAlg::Es512)
if params.crv == JsonWebKeyEcEllipticCurve::P521 =>
{
Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg })
}
(JsonWebKeyPublicParameters::Ec(params), JsonWebSignatureAlg::Es256K)
if params.crv == JsonWebKeyEcEllipticCurve::Secp256K1 =>
{
Ok(Self::Es256K(params.try_into()?))
}
(JsonWebKeyPublicParameters::Okp(_params), JsonWebSignatureAlg::EdDsa) => {
Err(AsymmetricKeyFromJwkError::UnsupportedAlgorithm { alg })
}
_ => Err(AsymmetricKeyFromJwkError::KeyNotSuitable { alg }),
}
}
}
impl From<super::Rs256VerifyingKey> for AsymmetricVerifyingKey {
fn from(key: super::Rs256VerifyingKey) -> Self {
Self::Rs256(key)
}
}
impl From<super::Rs384VerifyingKey> for AsymmetricVerifyingKey {
fn from(key: super::Rs384VerifyingKey) -> Self {
Self::Rs384(key)
}
}
impl From<super::Rs512VerifyingKey> for AsymmetricVerifyingKey {
fn from(key: super::Rs512VerifyingKey) -> Self {
Self::Rs512(key)
}
}
impl From<super::Ps256VerifyingKey> for AsymmetricVerifyingKey {
fn from(key: super::Ps256VerifyingKey) -> Self {
Self::Ps256(key)
}
}
impl From<super::Ps384VerifyingKey> for AsymmetricVerifyingKey {
fn from(key: super::Ps384VerifyingKey) -> Self {
Self::Ps384(key)
}
}
impl From<super::Ps512VerifyingKey> for AsymmetricVerifyingKey {
fn from(key: super::Ps512VerifyingKey) -> Self {
Self::Ps512(key)
}
}
impl From<super::Es256VerifyingKey> for AsymmetricVerifyingKey {
fn from(key: super::Es256VerifyingKey) -> Self {
Self::Es256(key)
}
}
impl From<super::Es384VerifyingKey> for AsymmetricVerifyingKey {
fn from(key: super::Es384VerifyingKey) -> Self {
Self::Es384(key)
}
}
impl From<super::Es256KVerifyingKey> for AsymmetricVerifyingKey {
fn from(key: super::Es256KVerifyingKey) -> Self {
Self::Es256K(key)
}
}
impl signature::Verifier<Signature> for AsymmetricVerifyingKey {
fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), ecdsa::Error> {
match self {
Self::Rs256(key) => {
let signature = signature.to_signature()?;
key.verify(msg, &signature)
}
Self::Rs384(key) => {
let signature = signature.to_signature()?;
key.verify(msg, &signature)
}
Self::Rs512(key) => {
let signature = signature.to_signature()?;
key.verify(msg, &signature)
}
Self::Ps256(key) => {
let signature = signature.to_signature()?;
key.verify(msg, &signature)
}
Self::Ps384(key) => {
let signature = signature.to_signature()?;
key.verify(msg, &signature)
}
Self::Ps512(key) => {
let signature = signature.to_signature()?;
key.verify(msg, &signature)
}
Self::Es256(key) => {
let signature = signature.to_signature()?;
key.verify(msg, &signature)
}
Self::Es384(key) => {
let signature = signature.to_signature()?;
key.verify(msg, &signature)
}
Self::Es256K(key) => {
let signature = signature.to_signature()?;
key.verify(msg, &signature)
}
}
}
}

View File

@@ -63,6 +63,15 @@ pub struct Hmac<D> {
digest: PhantomData<D>,
}
impl<D> Hmac<D> {
pub const fn new(key: Vec<u8>) -> Self {
Self {
key,
digest: PhantomData,
}
}
}
#[derive(Error, Debug)]
#[error("invalid length")]
pub struct InvalidLength;
@@ -71,7 +80,7 @@ impl<D> From<Vec<u8>> for Hmac<D> {
fn from(key: Vec<u8>) -> Self {
Self {
key,
digest: PhantomData::default(),
digest: PhantomData,
}
}
}

View File

@@ -14,8 +14,16 @@
use sha2::{Sha256, Sha384, Sha512};
mod asymmetric;
pub(crate) mod hmac;
pub(crate) mod rsa;
pub(self) mod signature;
mod symmetric;
pub use self::{
asymmetric::{AsymmetricKeyFromJwkError, AsymmetricSigningKey, AsymmetricVerifyingKey},
symmetric::{InvalidAlgorithm, SymmetricKey},
};
pub type Hs256Key = self::hmac::Hmac<Sha256>;
pub type Hs384Key = self::hmac::Hmac<Sha384>;

View File

@@ -0,0 +1,52 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use signature::Signature as _;
#[derive(Debug)]
pub struct Signature {
bytes: Vec<u8>,
}
impl AsRef<[u8]> for Signature {
fn as_ref(&self) -> &[u8] {
&self.bytes
}
}
impl signature::Signature for Signature {
fn from_bytes(bytes: &[u8]) -> Result<Self, signature::Error> {
Ok(Self {
bytes: bytes.to_vec(),
})
}
}
impl Signature {
pub fn from_signature<S>(signature: &S) -> Self
where
S: signature::Signature,
{
Self {
bytes: signature.as_bytes().to_vec(),
}
}
pub fn to_signature<S>(&self) -> Result<S, signature::Error>
where
S: signature::Signature,
{
S::from_bytes(self.as_bytes())
}
}

View File

@@ -0,0 +1,118 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use mas_iana::jose::JsonWebSignatureAlg;
use thiserror::Error;
use super::signature::Signature;
// An enum of all supported symmetric signing algorithms keys
#[non_exhaustive]
pub enum SymmetricKey {
Hs256(super::Hs256Key),
Hs384(super::Hs384Key),
Hs512(super::Hs512Key),
}
#[derive(Debug, Error)]
#[error("Invalid algorithm {alg} used for symetric key")]
pub struct InvalidAlgorithm {
pub alg: JsonWebSignatureAlg,
pub key: Vec<u8>,
}
impl SymmetricKey {
pub const fn new_for_alg(
key: Vec<u8>,
alg: JsonWebSignatureAlg,
) -> Result<Self, InvalidAlgorithm> {
match alg {
JsonWebSignatureAlg::Hs256 => Ok(Self::hs256(key)),
JsonWebSignatureAlg::Hs384 => Ok(Self::hs384(key)),
JsonWebSignatureAlg::Hs512 => Ok(Self::hs512(key)),
_ => Err(InvalidAlgorithm { alg, key }),
}
}
#[must_use]
pub const fn hs256(key: Vec<u8>) -> Self {
Self::Hs256(super::Hs256Key::new(key))
}
#[must_use]
pub const fn hs384(key: Vec<u8>) -> Self {
Self::Hs384(super::Hs384Key::new(key))
}
#[must_use]
pub const fn hs512(key: Vec<u8>) -> Self {
Self::Hs512(super::Hs512Key::new(key))
}
}
impl From<super::Hs256Key> for SymmetricKey {
fn from(key: super::Hs256Key) -> Self {
Self::Hs256(key)
}
}
impl From<super::Hs384Key> for SymmetricKey {
fn from(key: super::Hs384Key) -> Self {
Self::Hs384(key)
}
}
impl From<super::Hs512Key> for SymmetricKey {
fn from(key: super::Hs512Key) -> Self {
Self::Hs512(key)
}
}
impl signature::Signer<Signature> for SymmetricKey {
fn try_sign(&self, msg: &[u8]) -> Result<Signature, signature::Error> {
match self {
Self::Hs256(key) => {
let signature = key.try_sign(msg)?;
Ok(Signature::from_signature(&signature))
}
Self::Hs384(key) => {
let signature = key.try_sign(msg)?;
Ok(Signature::from_signature(&signature))
}
Self::Hs512(key) => {
let signature = key.try_sign(msg)?;
Ok(Signature::from_signature(&signature))
}
}
}
}
impl signature::Verifier<Signature> for SymmetricKey {
fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), signature::Error> {
match self {
Self::Hs256(key) => {
let signature = signature.to_signature()?;
key.verify(msg, &signature)
}
Self::Hs384(key) => {
let signature = signature.to_signature()?;
key.verify(msg, &signature)
}
Self::Hs512(key) => {
let signature = signature.to_signature()?;
key.verify(msg, &signature)
}
}
}
}

View File

@@ -222,8 +222,8 @@ impl<'a, T> Jwt<'a, T> {
.map_err(JwtVerificationError::verify)
}
pub fn verify_from_shared_secret(&self, secret: Vec<u8>) -> Result<(), NoKeyWorked> {
let verifier = crate::verifier::Verifier::for_oct_and_alg(secret, self.header().alg())
pub fn verify_with_shared_secret(&self, secret: Vec<u8>) -> Result<(), NoKeyWorked> {
let verifier = crate::jwa::SymmetricKey::new_for_alg(secret, self.header().alg())
.map_err(|_| NoKeyWorked::default())?;
self.verify(&verifier).map_err(|_| NoKeyWorked::default())?;
@@ -231,12 +231,12 @@ impl<'a, T> Jwt<'a, T> {
Ok(())
}
pub fn verify_from_jwks(&self, jwks: &PublicJsonWebKeySet) -> Result<(), NoKeyWorked> {
pub fn verify_with_jwks(&self, jwks: &PublicJsonWebKeySet) -> Result<(), NoKeyWorked> {
let constraints = ConstraintSet::from(self.header());
let candidates = constraints.filter(&**jwks);
for candidate in candidates {
let verifier = match crate::verifier::Verifier::for_jwk_and_alg(
let key = match crate::jwa::AsymmetricVerifyingKey::from_jwk_and_alg(
candidate.params(),
self.header().alg(),
) {
@@ -244,7 +244,7 @@ impl<'a, T> Jwt<'a, T> {
Err(_) => continue,
};
match self.verify(&verifier) {
match self.verify(&key) {
Ok(_) => return Ok(()),
Err(_) => continue,
}

View File

@@ -22,5 +22,3 @@ pub mod constraints;
pub mod jwa;
pub mod jwk;
pub mod jwt;
pub mod signer;
pub mod verifier;

View File

@@ -1,321 +0,0 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use mas_iana::jose::{JsonWebKeyEcEllipticCurve, JsonWebSignatureAlg};
use signature::Signature;
use thiserror::Error;
use crate::{
jwa,
jwk::private_parameters::{EcPrivateParameters, JsonWebKeyPrivateParameters},
};
pub enum Signer {
Hs256 { key: jwa::Hs256Key },
Hs384 { key: jwa::Hs384Key },
Hs512 { key: jwa::Hs512Key },
Rs256 { key: jwa::Rs256SigningKey },
Rs384 { key: jwa::Rs384SigningKey },
Rs512 { key: jwa::Rs512SigningKey },
Ps256 { key: jwa::Ps256SigningKey },
Ps384 { key: jwa::Ps384SigningKey },
Ps512 { key: jwa::Ps512SigningKey },
Es256 { key: jwa::Es256SigningKey },
Es384 { key: jwa::Es384SigningKey },
Es256K { key: jwa::Es256KSigningKey },
}
impl From<jwa::Hs256Key> for Signer {
fn from(key: jwa::Hs256Key) -> Self {
Self::Hs256 { key }
}
}
impl From<jwa::Hs384Key> for Signer {
fn from(key: jwa::Hs384Key) -> Self {
Self::Hs384 { key }
}
}
impl From<jwa::Hs512Key> for Signer {
fn from(key: jwa::Hs512Key) -> Self {
Self::Hs512 { key }
}
}
impl From<jwa::Rs256SigningKey> for Signer {
fn from(key: jwa::Rs256SigningKey) -> Self {
Self::Rs256 { key }
}
}
impl From<jwa::Rs384SigningKey> for Signer {
fn from(key: jwa::Rs384SigningKey) -> Self {
Self::Rs384 { key }
}
}
impl From<jwa::Rs512SigningKey> for Signer {
fn from(key: jwa::Rs512SigningKey) -> Self {
Self::Rs512 { key }
}
}
impl From<jwa::Ps256SigningKey> for Signer {
fn from(key: jwa::Ps256SigningKey) -> Self {
Self::Ps256 { key }
}
}
impl From<jwa::Ps384SigningKey> for Signer {
fn from(key: jwa::Ps384SigningKey) -> Self {
Self::Ps384 { key }
}
}
impl From<jwa::Ps512SigningKey> for Signer {
fn from(key: jwa::Ps512SigningKey) -> Self {
Self::Ps512 { key }
}
}
impl From<jwa::Es256SigningKey> for Signer {
fn from(key: jwa::Es256SigningKey) -> Self {
Self::Es256 { key }
}
}
impl From<jwa::Es384SigningKey> for Signer {
fn from(key: jwa::Es384SigningKey) -> Self {
Self::Es384 { key }
}
}
impl From<jwa::Es256KSigningKey> for Signer {
fn from(key: jwa::Es256KSigningKey) -> Self {
Self::Es256K { key }
}
}
#[derive(Debug, Error)]
pub enum SignerFromJwkError {
#[error("invalid RSA key")]
InvalidRsaKey {
#[from]
inner: rsa::errors::Error,
},
#[error("invalid elliptic curve key")]
InvalidEcKey {
#[from]
inner: ecdsa::Error,
},
#[error("algorithm {algorithm} is not supported")]
UnsupportedAlgorithm { algorithm: JsonWebSignatureAlg },
#[error("key is not suitable for algorithm {algorithm}")]
KeyNotSuitable { algorithm: JsonWebSignatureAlg },
}
#[derive(Debug, Error)]
pub enum SignerFromOctError {
#[error("algorithm {algorithm} is not supported")]
UnsupportedAlgorithm { algorithm: JsonWebSignatureAlg },
}
impl Signer {
pub fn for_oct_and_alg(
key: Vec<u8>,
alg: JsonWebSignatureAlg,
) -> Result<Self, SignerFromOctError> {
match alg {
JsonWebSignatureAlg::Hs256 => Ok(Self::Hs256 { key: key.into() }),
JsonWebSignatureAlg::Hs384 => Ok(Self::Hs384 { key: key.into() }),
JsonWebSignatureAlg::Hs512 => Ok(Self::Hs512 { key: key.into() }),
algorithm => Err(SignerFromOctError::UnsupportedAlgorithm { algorithm }),
}
}
pub fn for_jwk_and_alg(
key: &JsonWebKeyPrivateParameters,
alg: JsonWebSignatureAlg,
) -> Result<Self, SignerFromJwkError> {
match (key, alg) {
(JsonWebKeyPrivateParameters::Rsa(params), JsonWebSignatureAlg::Rs256) => {
Ok(Self::Rs256 {
key: params.try_into()?,
})
}
(JsonWebKeyPrivateParameters::Rsa(params), JsonWebSignatureAlg::Rs384) => {
Ok(Self::Rs384 {
key: params.try_into()?,
})
}
(JsonWebKeyPrivateParameters::Rsa(params), JsonWebSignatureAlg::Rs512) => {
Ok(Self::Rs512 {
key: params.try_into()?,
})
}
(JsonWebKeyPrivateParameters::Rsa(params), JsonWebSignatureAlg::Ps256) => {
Ok(Self::Ps256 {
key: params.try_into()?,
})
}
(JsonWebKeyPrivateParameters::Rsa(params), JsonWebSignatureAlg::Ps384) => {
Ok(Self::Ps384 {
key: params.try_into()?,
})
}
(JsonWebKeyPrivateParameters::Rsa(params), JsonWebSignatureAlg::Ps512) => {
Ok(Self::Ps512 {
key: params.try_into()?,
})
}
(
JsonWebKeyPrivateParameters::Ec(
params @ EcPrivateParameters {
crv: JsonWebKeyEcEllipticCurve::P256,
..
},
),
JsonWebSignatureAlg::Es256,
) => Ok(Self::Es256 {
key: params.try_into()?,
}),
(
JsonWebKeyPrivateParameters::Ec(
params @ EcPrivateParameters {
crv: JsonWebKeyEcEllipticCurve::P384,
..
},
),
JsonWebSignatureAlg::Es384,
) => Ok(Self::Es384 {
key: params.try_into()?,
}),
(
JsonWebKeyPrivateParameters::Ec(EcPrivateParameters {
crv: JsonWebKeyEcEllipticCurve::P521,
..
}),
JsonWebSignatureAlg::Es512,
) => Err(SignerFromJwkError::UnsupportedAlgorithm {
algorithm: JsonWebSignatureAlg::Es512,
}),
(
JsonWebKeyPrivateParameters::Ec(
params @ EcPrivateParameters {
crv: JsonWebKeyEcEllipticCurve::Secp256K1,
..
},
),
JsonWebSignatureAlg::Es256K,
) => Ok(Self::Es256K {
key: params.try_into()?,
}),
(JsonWebKeyPrivateParameters::Okp(_params), JsonWebSignatureAlg::EdDsa) => {
Err(SignerFromJwkError::UnsupportedAlgorithm {
algorithm: JsonWebSignatureAlg::EdDsa,
})
}
(_, algorithm) => Err(SignerFromJwkError::KeyNotSuitable { algorithm }),
}
}
}
#[derive(Debug)]
pub struct GenericSignature {
bytes: Vec<u8>,
}
impl AsRef<[u8]> for GenericSignature {
fn as_ref(&self) -> &[u8] {
&self.bytes
}
}
impl signature::Signature for GenericSignature {
fn from_bytes(bytes: &[u8]) -> Result<Self, signature::Error> {
Ok(Self {
bytes: bytes.to_vec(),
})
}
}
impl signature::Signer<GenericSignature> for Signer {
fn try_sign(&self, msg: &[u8]) -> Result<GenericSignature, signature::Error> {
match self {
Signer::Hs256 { key } => {
let signature = key.try_sign(msg)?;
GenericSignature::from_bytes(signature.as_bytes())
}
Signer::Hs384 { key } => {
let signature = key.try_sign(msg)?;
GenericSignature::from_bytes(signature.as_bytes())
}
Signer::Hs512 { key } => {
let signature = key.try_sign(msg)?;
GenericSignature::from_bytes(signature.as_bytes())
}
Signer::Rs256 { key } => {
let signature = key.try_sign(msg)?;
GenericSignature::from_bytes(signature.as_bytes())
}
Signer::Rs384 { key } => {
let signature = key.try_sign(msg)?;
GenericSignature::from_bytes(signature.as_bytes())
}
Signer::Rs512 { key } => {
let signature = key.try_sign(msg)?;
GenericSignature::from_bytes(signature.as_bytes())
}
Signer::Ps256 { key } => {
let signature = key.try_sign(msg)?;
GenericSignature::from_bytes(signature.as_bytes())
}
Signer::Ps384 { key } => {
let signature = key.try_sign(msg)?;
GenericSignature::from_bytes(signature.as_bytes())
}
Signer::Ps512 { key } => {
let signature = key.try_sign(msg)?;
GenericSignature::from_bytes(signature.as_bytes())
}
Signer::Es256 { key } => {
let signature = key.try_sign(msg)?;
GenericSignature::from_bytes(signature.as_bytes())
}
Signer::Es384 { key } => {
let signature = key.try_sign(msg)?;
GenericSignature::from_bytes(signature.as_bytes())
}
Signer::Es256K { key } => {
let signature = key.try_sign(msg)?;
GenericSignature::from_bytes(signature.as_bytes())
}
}
}
}

View File

@@ -1,333 +0,0 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use mas_iana::jose::{JsonWebKeyEcEllipticCurve, JsonWebSignatureAlg};
use signature::Signature;
use thiserror::Error;
use crate::{
jwa,
jwk::{public_parameters::EcPublicParameters, JsonWebKeyPublicParameters},
};
pub enum Verifier {
Hs256 { key: jwa::Hs256Key },
Hs384 { key: jwa::Hs384Key },
Hs512 { key: jwa::Hs512Key },
Rs256 { key: jwa::Rs256VerifyingKey },
Rs384 { key: jwa::Rs384VerifyingKey },
Rs512 { key: jwa::Rs512VerifyingKey },
Ps256 { key: jwa::Ps256VerifyingKey },
Ps384 { key: jwa::Ps384VerifyingKey },
Ps512 { key: jwa::Ps512VerifyingKey },
Es256 { key: jwa::Es256VerifyingKey },
Es384 { key: jwa::Es384VerifyingKey },
Es256K { key: jwa::Es256KVerifyingKey },
}
impl From<jwa::Hs256Key> for Verifier {
fn from(key: jwa::Hs256Key) -> Self {
Self::Hs256 { key }
}
}
impl From<jwa::Hs384Key> for Verifier {
fn from(key: jwa::Hs384Key) -> Self {
Self::Hs384 { key }
}
}
impl From<jwa::Hs512Key> for Verifier {
fn from(key: jwa::Hs512Key) -> Self {
Self::Hs512 { key }
}
}
impl From<jwa::Rs256VerifyingKey> for Verifier {
fn from(key: jwa::Rs256VerifyingKey) -> Self {
Self::Rs256 { key }
}
}
impl From<jwa::Rs384VerifyingKey> for Verifier {
fn from(key: jwa::Rs384VerifyingKey) -> Self {
Self::Rs384 { key }
}
}
impl From<jwa::Rs512VerifyingKey> for Verifier {
fn from(key: jwa::Rs512VerifyingKey) -> Self {
Self::Rs512 { key }
}
}
impl From<jwa::Ps256VerifyingKey> for Verifier {
fn from(key: jwa::Ps256VerifyingKey) -> Self {
Self::Ps256 { key }
}
}
impl From<jwa::Ps384VerifyingKey> for Verifier {
fn from(key: jwa::Ps384VerifyingKey) -> Self {
Self::Ps384 { key }
}
}
impl From<jwa::Ps512VerifyingKey> for Verifier {
fn from(key: jwa::Ps512VerifyingKey) -> Self {
Self::Ps512 { key }
}
}
impl From<jwa::Es256VerifyingKey> for Verifier {
fn from(key: jwa::Es256VerifyingKey) -> Self {
Self::Es256 { key }
}
}
impl From<jwa::Es384VerifyingKey> for Verifier {
fn from(key: jwa::Es384VerifyingKey) -> Self {
Self::Es384 { key }
}
}
impl From<jwa::Es256KVerifyingKey> for Verifier {
fn from(key: jwa::Es256KVerifyingKey) -> Self {
Self::Es256K { key }
}
}
#[derive(Debug, Error)]
pub enum VerifierFromJwkError {
#[error("invalid RSA key")]
InvalidRsaKey {
#[from]
inner: rsa::errors::Error,
},
#[error("invalid elliptic curve key")]
InvalidEcKey {
#[from]
inner: ecdsa::Error,
},
#[error("algorithm {algorithm} is not supported")]
UnsupportedAlgorithm { algorithm: JsonWebSignatureAlg },
#[error("key is not suitable for algorithm {algorithm}")]
KeyNotSuitable { algorithm: JsonWebSignatureAlg },
}
#[derive(Debug, Error)]
pub enum VerifierFromOctError {
#[error("algorithm {algorithm} is not supported")]
UnsupportedAlgorithm { algorithm: JsonWebSignatureAlg },
}
impl Verifier {
pub fn for_oct_and_alg(
key: Vec<u8>,
alg: JsonWebSignatureAlg,
) -> Result<Self, VerifierFromOctError> {
match alg {
JsonWebSignatureAlg::Hs256 => Ok(Self::Hs256 { key: key.into() }),
JsonWebSignatureAlg::Hs384 => Ok(Self::Hs384 { key: key.into() }),
JsonWebSignatureAlg::Hs512 => Ok(Self::Hs512 { key: key.into() }),
algorithm => Err(VerifierFromOctError::UnsupportedAlgorithm { algorithm }),
}
}
pub fn for_jwk_and_alg(
key: &JsonWebKeyPublicParameters,
alg: JsonWebSignatureAlg,
) -> Result<Self, VerifierFromJwkError> {
match (key, alg) {
(JsonWebKeyPublicParameters::Rsa(params), JsonWebSignatureAlg::Rs256) => {
Ok(Self::Rs256 {
key: params.try_into()?,
})
}
(JsonWebKeyPublicParameters::Rsa(params), JsonWebSignatureAlg::Rs384) => {
Ok(Self::Rs384 {
key: params.try_into()?,
})
}
(JsonWebKeyPublicParameters::Rsa(params), JsonWebSignatureAlg::Rs512) => {
Ok(Self::Rs512 {
key: params.try_into()?,
})
}
(JsonWebKeyPublicParameters::Rsa(params), JsonWebSignatureAlg::Ps256) => {
Ok(Self::Ps256 {
key: params.try_into()?,
})
}
(JsonWebKeyPublicParameters::Rsa(params), JsonWebSignatureAlg::Ps384) => {
Ok(Self::Ps384 {
key: params.try_into()?,
})
}
(JsonWebKeyPublicParameters::Rsa(params), JsonWebSignatureAlg::Ps512) => {
Ok(Self::Ps512 {
key: params.try_into()?,
})
}
(
JsonWebKeyPublicParameters::Ec(
params @ EcPublicParameters {
crv: JsonWebKeyEcEllipticCurve::P256,
..
},
),
JsonWebSignatureAlg::Es256,
) => Ok(Self::Es256 {
key: params.try_into()?,
}),
(
JsonWebKeyPublicParameters::Ec(
params @ EcPublicParameters {
crv: JsonWebKeyEcEllipticCurve::P384,
..
},
),
JsonWebSignatureAlg::Es384,
) => Ok(Self::Es384 {
key: params.try_into()?,
}),
(
JsonWebKeyPublicParameters::Ec(EcPublicParameters {
crv: JsonWebKeyEcEllipticCurve::P521,
..
}),
JsonWebSignatureAlg::Es512,
) => Err(VerifierFromJwkError::UnsupportedAlgorithm {
algorithm: JsonWebSignatureAlg::Es512,
}),
(
JsonWebKeyPublicParameters::Ec(
params @ EcPublicParameters {
crv: JsonWebKeyEcEllipticCurve::Secp256K1,
..
},
),
JsonWebSignatureAlg::Es256K,
) => Ok(Self::Es256K {
key: params.try_into()?,
}),
(JsonWebKeyPublicParameters::Okp(_params), JsonWebSignatureAlg::EdDsa) => {
Err(VerifierFromJwkError::UnsupportedAlgorithm {
algorithm: JsonWebSignatureAlg::EdDsa,
})
}
(_, algorithm) => Err(VerifierFromJwkError::KeyNotSuitable { algorithm }),
}
}
}
#[derive(Debug)]
pub struct GenericSignature {
bytes: Vec<u8>,
}
impl AsRef<[u8]> for GenericSignature {
fn as_ref(&self) -> &[u8] {
&self.bytes
}
}
impl signature::Signature for GenericSignature {
fn from_bytes(bytes: &[u8]) -> Result<Self, signature::Error> {
Ok(Self {
bytes: bytes.to_vec(),
})
}
}
impl signature::Verifier<GenericSignature> for Verifier {
fn verify(&self, msg: &[u8], signature: &GenericSignature) -> Result<(), signature::Error> {
match self {
Verifier::Hs256 { key } => {
let signature = signature::Signature::from_bytes(signature.as_bytes())?;
key.verify(msg, &signature)?;
Ok(())
}
Verifier::Hs384 { key } => {
let signature = signature::Signature::from_bytes(signature.as_bytes())?;
key.verify(msg, &signature)?;
Ok(())
}
Verifier::Hs512 { key } => {
let signature = signature::Signature::from_bytes(signature.as_bytes())?;
key.verify(msg, &signature)?;
Ok(())
}
Verifier::Rs256 { key } => {
let signature = signature::Signature::from_bytes(signature.as_bytes())?;
key.verify(msg, &signature)?;
Ok(())
}
Verifier::Rs384 { key } => {
let signature = signature::Signature::from_bytes(signature.as_bytes())?;
key.verify(msg, &signature)?;
Ok(())
}
Verifier::Rs512 { key } => {
let signature = signature::Signature::from_bytes(signature.as_bytes())?;
key.verify(msg, &signature)?;
Ok(())
}
Verifier::Ps256 { key } => {
let signature = signature::Signature::from_bytes(signature.as_bytes())?;
key.verify(msg, &signature)?;
Ok(())
}
Verifier::Ps384 { key } => {
let signature = signature::Signature::from_bytes(signature.as_bytes())?;
key.verify(msg, &signature)?;
Ok(())
}
Verifier::Ps512 { key } => {
let signature = signature::Signature::from_bytes(signature.as_bytes())?;
key.verify(msg, &signature)?;
Ok(())
}
Verifier::Es256 { key } => {
let signature = signature::Signature::from_bytes(signature.as_bytes())?;
key.verify(msg, &signature)?;
Ok(())
}
Verifier::Es384 { key } => {
let signature = signature::Signature::from_bytes(signature.as_bytes())?;
key.verify(msg, &signature)?;
Ok(())
}
Verifier::Es256K { key } => {
let signature = signature::Signature::from_bytes(signature.as_bytes())?;
key.verify(msg, &signature)?;
Ok(())
}
}
}
}