jwt_next/algorithm/
mod.rs

1//! Algorithms capable of signing and verifying tokens. By default only the
2//! `hmac` crate's `Hmac` type is supported. For more algorithms, enable the
3//! feature `openssl` and see the [openssl](openssl/index.html)
4//! module. The `none` algorithm is explicitly not supported.
5//! ## Examples
6//! ```
7//! use hmac::{Hmac, Mac};
8//! use sha2::Sha256;
9//!
10//! let hs256_key: Hmac<Sha256> = Hmac::new_from_slice(b"some-secret").unwrap();
11//! ```
12
13use base64::Engine;
14use serde::{Deserialize, Serialize};
15
16use crate::error::Error;
17
18#[cfg(feature = "openssl")]
19pub mod openssl;
20
21pub mod rust_crypto;
22pub mod store;
23
24/// The type of an algorithm, corresponding to the
25/// [JWA](https://tools.ietf.org/html/rfc7518) specification.
26#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
27#[serde(rename_all = "UPPERCASE")]
28#[derive(Default)]
29pub enum AlgorithmType {
30    #[default]
31    Hs256,
32    Hs384,
33    Hs512,
34    Rs256,
35    Rs384,
36    Rs512,
37    Es256,
38    Es384,
39    Es512,
40    Ps256,
41    Ps384,
42    Ps512,
43    #[serde(rename = "none")]
44    None,
45}
46
47/// An algorithm capable of signing base64 encoded header and claims strings.
48/// strings.
49pub trait SigningAlgorithm {
50    fn algorithm_type(&self) -> AlgorithmType;
51
52    fn sign(&self, header: &str, claims: &str) -> Result<String, Error>;
53}
54
55/// An algorithm capable of verifying base64 encoded header and claims strings.
56pub trait VerifyingAlgorithm {
57    fn algorithm_type(&self) -> AlgorithmType;
58
59    fn verify_bytes(&self, header: &str, claims: &str, signature: &[u8]) -> Result<bool, Error>;
60
61    fn verify(&self, header: &str, claims: &str, signature: &str) -> Result<bool, Error> {
62        let signature_bytes = base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(signature)?;
63        self.verify_bytes(header, claims, &signature_bytes)
64    }
65}
66
67// TODO: investigate if these AsRef impls are necessary
68impl<T: AsRef<dyn VerifyingAlgorithm>> VerifyingAlgorithm for T {
69    fn algorithm_type(&self) -> AlgorithmType {
70        self.as_ref().algorithm_type()
71    }
72
73    fn verify_bytes(&self, header: &str, claims: &str, signature: &[u8]) -> Result<bool, Error> {
74        self.as_ref().verify_bytes(header, claims, signature)
75    }
76}
77
78impl<T: AsRef<dyn SigningAlgorithm>> SigningAlgorithm for T {
79    fn algorithm_type(&self) -> AlgorithmType {
80        self.as_ref().algorithm_type()
81    }
82
83    fn sign(&self, header: &str, claims: &str) -> Result<String, Error> {
84        self.as_ref().sign(header, claims)
85    }
86}