You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-31 09:24:31 +03:00
Split the asymmetric and symmetric keys enums
This commit is contained in:
@ -136,7 +136,7 @@ impl Credentials {
|
|||||||
.await
|
.await
|
||||||
.map_err(|_| CredentialsVerificationError::JwksFetchFailed)?;
|
.map_err(|_| CredentialsVerificationError::JwksFetchFailed)?;
|
||||||
|
|
||||||
jwt.verify_from_jwks(&jwks)
|
jwt.verify_with_jwks(&jwks)
|
||||||
.map_err(|_| CredentialsVerificationError::InvalidAssertionSignature)?;
|
.map_err(|_| CredentialsVerificationError::InvalidAssertionSignature)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ impl Credentials {
|
|||||||
.decrypt_string(encrypted_client_secret)
|
.decrypt_string(encrypted_client_secret)
|
||||||
.map_err(|_e| CredentialsVerificationError::DecryptionError)?;
|
.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)?;
|
.map_err(|_| CredentialsVerificationError::InvalidAssertionSignature)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,7 +570,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(client_id, "client-id");
|
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();
|
.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>,
|
digest: PhantomData<D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<D> Hmac<D> {
|
||||||
|
pub const fn new(key: Vec<u8>) -> Self {
|
||||||
|
Self {
|
||||||
|
key,
|
||||||
|
digest: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
#[error("invalid length")]
|
#[error("invalid length")]
|
||||||
pub struct InvalidLength;
|
pub struct InvalidLength;
|
||||||
@ -71,7 +80,7 @@ impl<D> From<Vec<u8>> for Hmac<D> {
|
|||||||
fn from(key: Vec<u8>) -> Self {
|
fn from(key: Vec<u8>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
key,
|
key,
|
||||||
digest: PhantomData::default(),
|
digest: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,16 @@
|
|||||||
|
|
||||||
use sha2::{Sha256, Sha384, Sha512};
|
use sha2::{Sha256, Sha384, Sha512};
|
||||||
|
|
||||||
|
mod asymmetric;
|
||||||
pub(crate) mod hmac;
|
pub(crate) mod hmac;
|
||||||
pub(crate) mod rsa;
|
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 Hs256Key = self::hmac::Hmac<Sha256>;
|
||||||
pub type Hs384Key = self::hmac::Hmac<Sha384>;
|
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)
|
.map_err(JwtVerificationError::verify)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify_from_shared_secret(&self, secret: Vec<u8>) -> Result<(), NoKeyWorked> {
|
pub fn verify_with_shared_secret(&self, secret: Vec<u8>) -> Result<(), NoKeyWorked> {
|
||||||
let verifier = crate::verifier::Verifier::for_oct_and_alg(secret, self.header().alg())
|
let verifier = crate::jwa::SymmetricKey::new_for_alg(secret, self.header().alg())
|
||||||
.map_err(|_| NoKeyWorked::default())?;
|
.map_err(|_| NoKeyWorked::default())?;
|
||||||
|
|
||||||
self.verify(&verifier).map_err(|_| NoKeyWorked::default())?;
|
self.verify(&verifier).map_err(|_| NoKeyWorked::default())?;
|
||||||
@ -231,12 +231,12 @@ impl<'a, T> Jwt<'a, T> {
|
|||||||
Ok(())
|
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 constraints = ConstraintSet::from(self.header());
|
||||||
let candidates = constraints.filter(&**jwks);
|
let candidates = constraints.filter(&**jwks);
|
||||||
|
|
||||||
for candidate in candidates {
|
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(),
|
candidate.params(),
|
||||||
self.header().alg(),
|
self.header().alg(),
|
||||||
) {
|
) {
|
||||||
@ -244,7 +244,7 @@ impl<'a, T> Jwt<'a, T> {
|
|||||||
Err(_) => continue,
|
Err(_) => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
match self.verify(&verifier) {
|
match self.verify(&key) {
|
||||||
Ok(_) => return Ok(()),
|
Ok(_) => return Ok(()),
|
||||||
Err(_) => continue,
|
Err(_) => continue,
|
||||||
}
|
}
|
||||||
|
@ -22,5 +22,3 @@ pub mod constraints;
|
|||||||
pub mod jwa;
|
pub mod jwa;
|
||||||
pub mod jwk;
|
pub mod jwk;
|
||||||
pub mod jwt;
|
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())
|
let key = ConstraintSet::from(jwt.header())
|
||||||
.filter(jwks.deref())[0];
|
.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(),
|
key.params(),
|
||||||
JsonWebSignatureAlg::$alg
|
JsonWebSignatureAlg::$alg
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
jwt.verify(&verifier).unwrap();
|
jwt.verify(&key).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -126,26 +126,26 @@ macro_rules! asymetric_jwt_test {
|
|||||||
])
|
])
|
||||||
.filter(jwks.deref())[0];
|
.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(),
|
key.params(),
|
||||||
JsonWebSignatureAlg::$alg,
|
JsonWebSignatureAlg::$alg,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let jwks = public_jwks();
|
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 jwt: Jwt<'_, Payload> = Jwt::try_from(jwt.as_str()).unwrap();
|
||||||
|
|
||||||
let key = ConstraintSet::from(jwt.header())
|
let key = ConstraintSet::from(jwt.header())
|
||||||
.filter(jwks.deref())[0];
|
.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(),
|
key.params(),
|
||||||
JsonWebSignatureAlg::$alg
|
JsonWebSignatureAlg::$alg
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
jwt.verify(&verifier).unwrap();
|
jwt.verify(&key).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,12 +170,10 @@ macro_rules! symetric_jwt_test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn verify_jwt() {
|
fn verify_jwt() {
|
||||||
let jwt: Jwt<'_, Payload> = Jwt::try_from($jwt).unwrap();
|
let jwt: Jwt<'_, Payload> = Jwt::try_from($jwt).unwrap();
|
||||||
let verifier = mas_jose::verifier::Verifier::for_oct_and_alg(
|
let key =
|
||||||
oct_key(),
|
mas_jose::jwa::SymmetricKey::new_for_alg(oct_key(), JsonWebSignatureAlg::$alg)
|
||||||
JsonWebSignatureAlg::$alg,
|
.unwrap();
|
||||||
)
|
jwt.verify(&key).unwrap();
|
||||||
.unwrap();
|
|
||||||
jwt.verify(&verifier).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -185,20 +183,14 @@ macro_rules! symetric_jwt_test {
|
|||||||
};
|
};
|
||||||
let header = JsonWebSignatureHeader::new(JsonWebSignatureAlg::$alg);
|
let header = JsonWebSignatureHeader::new(JsonWebSignatureAlg::$alg);
|
||||||
|
|
||||||
let signer =
|
let key =
|
||||||
mas_jose::signer::Signer::for_oct_and_alg(oct_key(), JsonWebSignatureAlg::$alg)
|
mas_jose::jwa::SymmetricKey::new_for_alg(oct_key(), JsonWebSignatureAlg::$alg)
|
||||||
.unwrap();
|
.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 jwt: Jwt<'_, Payload> = Jwt::try_from(jwt.as_str()).unwrap();
|
||||||
|
|
||||||
let verifier = mas_jose::verifier::Verifier::for_oct_and_alg(
|
jwt.verify(&key).unwrap();
|
||||||
oct_key(),
|
|
||||||
JsonWebSignatureAlg::$alg,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
jwt.verify(&verifier).unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -30,9 +30,8 @@ use mas_iana::jose::{JsonWebKeyType, JsonWebSignatureAlg};
|
|||||||
pub use mas_jose::jwk::{JsonWebKey, JsonWebKeySet};
|
pub use mas_jose::jwk::{JsonWebKey, JsonWebKeySet};
|
||||||
use mas_jose::{
|
use mas_jose::{
|
||||||
constraints::{Constraint, ConstraintSet},
|
constraints::{Constraint, ConstraintSet},
|
||||||
|
jwa::{AsymmetricSigningKey, AsymmetricVerifyingKey},
|
||||||
jwk::{JsonWebKeyPublicParameters, ParametersInfo, PublicJsonWebKeySet},
|
jwk::{JsonWebKeyPublicParameters, ParametersInfo, PublicJsonWebKeySet},
|
||||||
signer::Signer,
|
|
||||||
verifier::Verifier,
|
|
||||||
};
|
};
|
||||||
use pem_rfc7468::PemLabel;
|
use pem_rfc7468::PemLabel;
|
||||||
use pkcs1::EncodeRsaPrivateKey;
|
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`]
|
/// [`JsonWebSignatureAlg`]
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
@ -399,98 +398,79 @@ impl PrivateKey {
|
|||||||
pub fn verifier_for_alg(
|
pub fn verifier_for_alg(
|
||||||
&self,
|
&self,
|
||||||
alg: JsonWebSignatureAlg,
|
alg: JsonWebSignatureAlg,
|
||||||
) -> Result<Verifier, WrongAlgorithmError> {
|
) -> Result<AsymmetricVerifyingKey, WrongAlgorithmError> {
|
||||||
let signer = match (self, alg) {
|
let key = match (self, alg) {
|
||||||
(Self::Rsa(key), JsonWebSignatureAlg::Rs256) => {
|
(Self::Rsa(key), _) => {
|
||||||
mas_jose::jwa::Rs256VerifyingKey::from(key.to_public_key()).into()
|
let key: rsa::RsaPublicKey = key.to_public_key();
|
||||||
}
|
match alg {
|
||||||
|
JsonWebSignatureAlg::Rs256 => AsymmetricVerifyingKey::Rs256(key.into()),
|
||||||
(Self::Rsa(key), JsonWebSignatureAlg::Rs384) => {
|
JsonWebSignatureAlg::Rs384 => AsymmetricVerifyingKey::Rs384(key.into()),
|
||||||
mas_jose::jwa::Rs384VerifyingKey::from(key.to_public_key()).into()
|
JsonWebSignatureAlg::Rs512 => AsymmetricVerifyingKey::Rs512(key.into()),
|
||||||
}
|
JsonWebSignatureAlg::Ps256 => AsymmetricVerifyingKey::Ps256(key.into()),
|
||||||
|
JsonWebSignatureAlg::Ps384 => AsymmetricVerifyingKey::Ps384(key.into()),
|
||||||
(Self::Rsa(key), JsonWebSignatureAlg::Rs512) => {
|
JsonWebSignatureAlg::Ps512 => AsymmetricVerifyingKey::Ps512(key.into()),
|
||||||
mas_jose::jwa::Rs512VerifyingKey::from(key.to_public_key()).into()
|
_ => return Err(WrongAlgorithmError),
|
||||||
}
|
}
|
||||||
|
|
||||||
(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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(Self::EcP256(key), JsonWebSignatureAlg::Es256) => {
|
(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) => {
|
(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) => {
|
(Self::EcK256(key), JsonWebSignatureAlg::Es256K) => {
|
||||||
mas_jose::jwa::Es256KVerifyingKey::from(key.public_key()).into()
|
AsymmetricVerifyingKey::Es256K(key.public_key().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => return Err(WrongAlgorithmError),
|
_ => 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`]
|
/// [`JsonWebSignatureAlg`]
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Returns an error if the key is not suited for the selected algorithm
|
/// Returns an error if the key is not suited for the selected algorithm
|
||||||
pub fn signer_for_alg(&self, alg: JsonWebSignatureAlg) -> Result<Signer, WrongAlgorithmError> {
|
pub fn signer_for_alg(
|
||||||
let signer = match (self, alg) {
|
&self,
|
||||||
(Self::Rsa(key), JsonWebSignatureAlg::Rs256) => {
|
alg: JsonWebSignatureAlg,
|
||||||
mas_jose::jwa::Rs256SigningKey::from(*key.clone()).into()
|
) -> Result<AsymmetricSigningKey, WrongAlgorithmError> {
|
||||||
}
|
let key = match (self, alg) {
|
||||||
|
(Self::Rsa(key), _) => {
|
||||||
(Self::Rsa(key), JsonWebSignatureAlg::Rs384) => {
|
let key: rsa::RsaPrivateKey = *key.clone();
|
||||||
mas_jose::jwa::Rs384SigningKey::from(*key.clone()).into()
|
match alg {
|
||||||
}
|
JsonWebSignatureAlg::Rs256 => AsymmetricSigningKey::Rs256(key.into()),
|
||||||
|
JsonWebSignatureAlg::Rs384 => AsymmetricSigningKey::Rs384(key.into()),
|
||||||
(Self::Rsa(key), JsonWebSignatureAlg::Rs512) => {
|
JsonWebSignatureAlg::Rs512 => AsymmetricSigningKey::Rs512(key.into()),
|
||||||
mas_jose::jwa::Rs512SigningKey::from(*key.clone()).into()
|
JsonWebSignatureAlg::Ps256 => AsymmetricSigningKey::Ps256(key.into()),
|
||||||
}
|
JsonWebSignatureAlg::Ps384 => AsymmetricSigningKey::Ps384(key.into()),
|
||||||
|
JsonWebSignatureAlg::Ps512 => AsymmetricSigningKey::Ps512(key.into()),
|
||||||
(Self::Rsa(key), JsonWebSignatureAlg::Ps256) => {
|
_ => return Err(WrongAlgorithmError),
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(Self::EcP256(key), JsonWebSignatureAlg::Es256) => {
|
(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) => {
|
(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) => {
|
(Self::EcK256(key), JsonWebSignatureAlg::Es256K) => {
|
||||||
mas_jose::jwa::Es256KSigningKey::from(key.as_ref()).into()
|
AsymmetricSigningKey::Es256K(key.as_ref().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => return Err(WrongAlgorithmError),
|
_ => return Err(WrongAlgorithmError),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(signer)
|
Ok(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a RSA key with 2048 bit size
|
/// Generate a RSA key with 2048 bit size
|
||||||
|
Reference in New Issue
Block a user