You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-29 22:01:14 +03:00
Split the asymmetric and symmetric keys enums
This commit is contained in:
@ -136,7 +136,7 @@ impl Credentials {
|
||||
.await
|
||||
.map_err(|_| CredentialsVerificationError::JwksFetchFailed)?;
|
||||
|
||||
jwt.verify_from_jwks(&jwks)
|
||||
jwt.verify_with_jwks(&jwks)
|
||||
.map_err(|_| CredentialsVerificationError::InvalidAssertionSignature)?;
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ impl Credentials {
|
||||
.decrypt_string(encrypted_client_secret)
|
||||
.map_err(|_e| CredentialsVerificationError::DecryptionError)?;
|
||||
|
||||
jwt.verify_from_shared_secret(decrypted_client_secret)
|
||||
jwt.verify_with_shared_secret(decrypted_client_secret)
|
||||
.map_err(|_| CredentialsVerificationError::InvalidAssertionSignature)?;
|
||||
}
|
||||
|
||||
@ -570,7 +570,7 @@ mod tests {
|
||||
};
|
||||
|
||||
assert_eq!(client_id, "client-id");
|
||||
jwt.verify_from_shared_secret(b"client-secret".to_vec())
|
||||
jwt.verify_with_shared_secret(b"client-secret".to_vec())
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
367
crates/jose/src/jwa/asymmetric.rs
Normal file
367
crates/jose/src/jwa/asymmetric.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>;
|
||||
|
52
crates/jose/src/jwa/signature.rs
Normal file
52
crates/jose/src/jwa/signature.rs
Normal 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())
|
||||
}
|
||||
}
|
118
crates/jose/src/jwa/symmetric.rs
Normal file
118
crates/jose/src/jwa/symmetric.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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,
|
||||
}
|
||||
|
@ -22,5 +22,3 @@ pub mod constraints;
|
||||
pub mod jwa;
|
||||
pub mod jwk;
|
||||
pub mod jwt;
|
||||
pub mod signer;
|
||||
pub mod verifier;
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -105,13 +105,13 @@ macro_rules! asymetric_jwt_test {
|
||||
let key = ConstraintSet::from(jwt.header())
|
||||
.filter(jwks.deref())[0];
|
||||
|
||||
let verifier = mas_jose::verifier::Verifier::for_jwk_and_alg(
|
||||
let key = mas_jose::jwa::AsymmetricVerifyingKey::from_jwk_and_alg(
|
||||
key.params(),
|
||||
JsonWebSignatureAlg::$alg
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
jwt.verify(&verifier).unwrap();
|
||||
jwt.verify(&key).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -126,26 +126,26 @@ macro_rules! asymetric_jwt_test {
|
||||
])
|
||||
.filter(jwks.deref())[0];
|
||||
|
||||
let signer = mas_jose::signer::Signer::for_jwk_and_alg(
|
||||
let key = mas_jose::jwa::AsymmetricSigningKey::from_jwk_and_alg(
|
||||
key.params(),
|
||||
JsonWebSignatureAlg::$alg,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let jwks = public_jwks();
|
||||
let jwt: Jwt<'_, Payload> = Jwt::sign(header, payload, &signer).unwrap();
|
||||
let jwt: Jwt<'_, Payload> = Jwt::sign(header, payload, &key).unwrap();
|
||||
let jwt: Jwt<'_, Payload> = Jwt::try_from(jwt.as_str()).unwrap();
|
||||
|
||||
let key = ConstraintSet::from(jwt.header())
|
||||
.filter(jwks.deref())[0];
|
||||
|
||||
let verifier = mas_jose::verifier::Verifier::for_jwk_and_alg(
|
||||
let key = mas_jose::jwa::AsymmetricVerifyingKey::from_jwk_and_alg(
|
||||
key.params(),
|
||||
JsonWebSignatureAlg::$alg
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
jwt.verify(&verifier).unwrap();
|
||||
jwt.verify(&key).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -170,12 +170,10 @@ macro_rules! symetric_jwt_test {
|
||||
#[test]
|
||||
fn verify_jwt() {
|
||||
let jwt: Jwt<'_, Payload> = Jwt::try_from($jwt).unwrap();
|
||||
let verifier = mas_jose::verifier::Verifier::for_oct_and_alg(
|
||||
oct_key(),
|
||||
JsonWebSignatureAlg::$alg,
|
||||
)
|
||||
.unwrap();
|
||||
jwt.verify(&verifier).unwrap();
|
||||
let key =
|
||||
mas_jose::jwa::SymmetricKey::new_for_alg(oct_key(), JsonWebSignatureAlg::$alg)
|
||||
.unwrap();
|
||||
jwt.verify(&key).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -185,20 +183,14 @@ macro_rules! symetric_jwt_test {
|
||||
};
|
||||
let header = JsonWebSignatureHeader::new(JsonWebSignatureAlg::$alg);
|
||||
|
||||
let signer =
|
||||
mas_jose::signer::Signer::for_oct_and_alg(oct_key(), JsonWebSignatureAlg::$alg)
|
||||
let key =
|
||||
mas_jose::jwa::SymmetricKey::new_for_alg(oct_key(), JsonWebSignatureAlg::$alg)
|
||||
.unwrap();
|
||||
|
||||
let jwt: Jwt<'_, Payload> = Jwt::sign(header, payload, &signer).unwrap();
|
||||
let jwt: Jwt<'_, Payload> = Jwt::sign(header, payload, &key).unwrap();
|
||||
let jwt: Jwt<'_, Payload> = Jwt::try_from(jwt.as_str()).unwrap();
|
||||
|
||||
let verifier = mas_jose::verifier::Verifier::for_oct_and_alg(
|
||||
oct_key(),
|
||||
JsonWebSignatureAlg::$alg,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
jwt.verify(&verifier).unwrap();
|
||||
jwt.verify(&key).unwrap();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -30,9 +30,8 @@ use mas_iana::jose::{JsonWebKeyType, JsonWebSignatureAlg};
|
||||
pub use mas_jose::jwk::{JsonWebKey, JsonWebKeySet};
|
||||
use mas_jose::{
|
||||
constraints::{Constraint, ConstraintSet},
|
||||
jwa::{AsymmetricSigningKey, AsymmetricVerifyingKey},
|
||||
jwk::{JsonWebKeyPublicParameters, ParametersInfo, PublicJsonWebKeySet},
|
||||
signer::Signer,
|
||||
verifier::Verifier,
|
||||
};
|
||||
use pem_rfc7468::PemLabel;
|
||||
use pkcs1::EncodeRsaPrivateKey;
|
||||
@ -390,7 +389,7 @@ impl PrivateKey {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a [`Verifier`] out of this key, for the specified
|
||||
/// Get an [`AsymmetricVerifyingKey`] out of this key, for the specified
|
||||
/// [`JsonWebSignatureAlg`]
|
||||
///
|
||||
/// # Errors
|
||||
@ -399,98 +398,79 @@ impl PrivateKey {
|
||||
pub fn verifier_for_alg(
|
||||
&self,
|
||||
alg: JsonWebSignatureAlg,
|
||||
) -> Result<Verifier, WrongAlgorithmError> {
|
||||
let signer = match (self, alg) {
|
||||
(Self::Rsa(key), JsonWebSignatureAlg::Rs256) => {
|
||||
mas_jose::jwa::Rs256VerifyingKey::from(key.to_public_key()).into()
|
||||
}
|
||||
|
||||
(Self::Rsa(key), JsonWebSignatureAlg::Rs384) => {
|
||||
mas_jose::jwa::Rs384VerifyingKey::from(key.to_public_key()).into()
|
||||
}
|
||||
|
||||
(Self::Rsa(key), JsonWebSignatureAlg::Rs512) => {
|
||||
mas_jose::jwa::Rs512VerifyingKey::from(key.to_public_key()).into()
|
||||
}
|
||||
|
||||
(Self::Rsa(key), JsonWebSignatureAlg::Ps256) => {
|
||||
mas_jose::jwa::Ps256VerifyingKey::from(key.to_public_key()).into()
|
||||
}
|
||||
|
||||
(Self::Rsa(key), JsonWebSignatureAlg::Ps384) => {
|
||||
mas_jose::jwa::Ps384VerifyingKey::from(key.to_public_key()).into()
|
||||
}
|
||||
|
||||
(Self::Rsa(key), JsonWebSignatureAlg::Ps512) => {
|
||||
mas_jose::jwa::Ps512VerifyingKey::from(key.to_public_key()).into()
|
||||
) -> Result<AsymmetricVerifyingKey, WrongAlgorithmError> {
|
||||
let key = match (self, alg) {
|
||||
(Self::Rsa(key), _) => {
|
||||
let key: rsa::RsaPublicKey = key.to_public_key();
|
||||
match alg {
|
||||
JsonWebSignatureAlg::Rs256 => AsymmetricVerifyingKey::Rs256(key.into()),
|
||||
JsonWebSignatureAlg::Rs384 => AsymmetricVerifyingKey::Rs384(key.into()),
|
||||
JsonWebSignatureAlg::Rs512 => AsymmetricVerifyingKey::Rs512(key.into()),
|
||||
JsonWebSignatureAlg::Ps256 => AsymmetricVerifyingKey::Ps256(key.into()),
|
||||
JsonWebSignatureAlg::Ps384 => AsymmetricVerifyingKey::Ps384(key.into()),
|
||||
JsonWebSignatureAlg::Ps512 => AsymmetricVerifyingKey::Ps512(key.into()),
|
||||
_ => return Err(WrongAlgorithmError),
|
||||
}
|
||||
}
|
||||
|
||||
(Self::EcP256(key), JsonWebSignatureAlg::Es256) => {
|
||||
mas_jose::jwa::Es256VerifyingKey::from(key.public_key()).into()
|
||||
AsymmetricVerifyingKey::Es256(key.public_key().into())
|
||||
}
|
||||
|
||||
(Self::EcP384(key), JsonWebSignatureAlg::Es384) => {
|
||||
mas_jose::jwa::Es384VerifyingKey::from(key.public_key()).into()
|
||||
AsymmetricVerifyingKey::Es384(key.public_key().into())
|
||||
}
|
||||
|
||||
(Self::EcK256(key), JsonWebSignatureAlg::Es256K) => {
|
||||
mas_jose::jwa::Es256KVerifyingKey::from(key.public_key()).into()
|
||||
AsymmetricVerifyingKey::Es256K(key.public_key().into())
|
||||
}
|
||||
|
||||
_ => return Err(WrongAlgorithmError),
|
||||
};
|
||||
|
||||
Ok(signer)
|
||||
Ok(key)
|
||||
}
|
||||
|
||||
/// Get a [`Signer`] out of this key, for the specified
|
||||
/// Get a [`AsymmetricSigningKey`] out of this key, for the specified
|
||||
/// [`JsonWebSignatureAlg`]
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the key is not suited for the selected algorithm
|
||||
pub fn signer_for_alg(&self, alg: JsonWebSignatureAlg) -> Result<Signer, WrongAlgorithmError> {
|
||||
let signer = match (self, alg) {
|
||||
(Self::Rsa(key), JsonWebSignatureAlg::Rs256) => {
|
||||
mas_jose::jwa::Rs256SigningKey::from(*key.clone()).into()
|
||||
}
|
||||
|
||||
(Self::Rsa(key), JsonWebSignatureAlg::Rs384) => {
|
||||
mas_jose::jwa::Rs384SigningKey::from(*key.clone()).into()
|
||||
}
|
||||
|
||||
(Self::Rsa(key), JsonWebSignatureAlg::Rs512) => {
|
||||
mas_jose::jwa::Rs512SigningKey::from(*key.clone()).into()
|
||||
}
|
||||
|
||||
(Self::Rsa(key), JsonWebSignatureAlg::Ps256) => {
|
||||
mas_jose::jwa::Ps256SigningKey::from(*key.clone()).into()
|
||||
}
|
||||
|
||||
(Self::Rsa(key), JsonWebSignatureAlg::Ps384) => {
|
||||
mas_jose::jwa::Ps384SigningKey::from(*key.clone()).into()
|
||||
}
|
||||
|
||||
(Self::Rsa(key), JsonWebSignatureAlg::Ps512) => {
|
||||
mas_jose::jwa::Ps512SigningKey::from(*key.clone()).into()
|
||||
pub fn signer_for_alg(
|
||||
&self,
|
||||
alg: JsonWebSignatureAlg,
|
||||
) -> Result<AsymmetricSigningKey, WrongAlgorithmError> {
|
||||
let key = match (self, alg) {
|
||||
(Self::Rsa(key), _) => {
|
||||
let key: rsa::RsaPrivateKey = *key.clone();
|
||||
match alg {
|
||||
JsonWebSignatureAlg::Rs256 => AsymmetricSigningKey::Rs256(key.into()),
|
||||
JsonWebSignatureAlg::Rs384 => AsymmetricSigningKey::Rs384(key.into()),
|
||||
JsonWebSignatureAlg::Rs512 => AsymmetricSigningKey::Rs512(key.into()),
|
||||
JsonWebSignatureAlg::Ps256 => AsymmetricSigningKey::Ps256(key.into()),
|
||||
JsonWebSignatureAlg::Ps384 => AsymmetricSigningKey::Ps384(key.into()),
|
||||
JsonWebSignatureAlg::Ps512 => AsymmetricSigningKey::Ps512(key.into()),
|
||||
_ => return Err(WrongAlgorithmError),
|
||||
}
|
||||
}
|
||||
|
||||
(Self::EcP256(key), JsonWebSignatureAlg::Es256) => {
|
||||
mas_jose::jwa::Es256SigningKey::from(key.as_ref()).into()
|
||||
AsymmetricSigningKey::Es256(key.as_ref().into())
|
||||
}
|
||||
|
||||
(Self::EcP384(key), JsonWebSignatureAlg::Es384) => {
|
||||
mas_jose::jwa::Es384SigningKey::from(key.as_ref()).into()
|
||||
AsymmetricSigningKey::Es384(key.as_ref().into())
|
||||
}
|
||||
|
||||
(Self::EcK256(key), JsonWebSignatureAlg::Es256K) => {
|
||||
mas_jose::jwa::Es256KSigningKey::from(key.as_ref()).into()
|
||||
AsymmetricSigningKey::Es256K(key.as_ref().into())
|
||||
}
|
||||
|
||||
_ => return Err(WrongAlgorithmError),
|
||||
};
|
||||
|
||||
Ok(signer)
|
||||
Ok(key)
|
||||
}
|
||||
|
||||
/// Generate a RSA key with 2048 bit size
|
||||
|
Reference in New Issue
Block a user