diff --git a/Cargo.toml b/Cargo.toml index 4865ea2f..b1cd6434 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,19 +9,27 @@ repository = "http://github.com/mikkyang/rust-jwt" readme = "README.md" keywords = ["JWT", "token", "web"] license = "MIT" -edition = "2018" +edition = "2021" -[package.metadata.docs.rs] -features = ["openssl"] +[features] +openssl = ["dep:openssl"] +openssl-vendored = ["openssl", "openssl/vendored"] +default = [] [dependencies] -base64 = "0.13" +base64 = "0.21" crypto-common = "0.1" -digest = "0.10" +digest = { version = "0.10", features = ["oid"] } +signature = { version = "2.2", features = ["digest"] } hmac = { version = "0.12", features = ["reset"] } sha2 = "0.10" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +ecdsa = { version = "0.16", features = ["verifying", "signing"] } +rsa = { version = "0.9", features = ["sha2"] } +p256 = { version = "0.13", features = ["pem"] } +p384 = { version = "0.13", features = ["pem"] } +pem = "3.0" [dependencies.openssl] version = "0.10" diff --git a/examples/custom_claims.rs b/examples/custom_claims.rs index 1495265c..8d5a1eba 100644 --- a/examples/custom_claims.rs +++ b/examples/custom_claims.rs @@ -43,7 +43,7 @@ fn login(token: &str) -> Result { fn main() -> Result<(), &'static str> { let token = new_token("Michael Yang", "password")?; - let logged_in_user = login(&*token)?; + let logged_in_user = login(&token)?; assert_eq!(logged_in_user, "Michael Yang"); Ok(()) diff --git a/examples/hs256.rs b/examples/hs256.rs index d27730a8..6af1c78d 100644 --- a/examples/hs256.rs +++ b/examples/hs256.rs @@ -32,7 +32,7 @@ fn login(token: &str) -> Result { fn main() -> Result<(), &'static str> { let token = new_token("Michael Yang", "password")?; - let logged_in_user = login(&*token)?; + let logged_in_user = login(&token)?; assert_eq!(logged_in_user, "Michael Yang"); Ok(()) diff --git a/src/algorithm/mod.rs b/src/algorithm/mod.rs index 3e98a832..f59a17f4 100644 --- a/src/algorithm/mod.rs +++ b/src/algorithm/mod.rs @@ -10,12 +10,14 @@ //! let hs256_key: Hmac = Hmac::new_from_slice(b"some-secret").unwrap(); //! ``` +use base64::Engine; use serde::{Deserialize, Serialize}; use crate::error::Error; #[cfg(feature = "openssl")] pub mod openssl; + pub mod rust_crypto; pub mod store; @@ -23,7 +25,9 @@ pub mod store; /// [JWA](https://tools.ietf.org/html/rfc7518) specification. #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "UPPERCASE")] +#[derive(Default)] pub enum AlgorithmType { + #[default] Hs256, Hs384, Hs512, @@ -40,12 +44,6 @@ pub enum AlgorithmType { None, } -impl Default for AlgorithmType { - fn default() -> Self { - AlgorithmType::Hs256 - } -} - /// An algorithm capable of signing base64 encoded header and claims strings. /// strings. pub trait SigningAlgorithm { @@ -61,8 +59,8 @@ pub trait VerifyingAlgorithm { fn verify_bytes(&self, header: &str, claims: &str, signature: &[u8]) -> Result; fn verify(&self, header: &str, claims: &str, signature: &str) -> Result { - let signature_bytes = base64::decode_config(signature, base64::URL_SAFE_NO_PAD)?; - self.verify_bytes(header, claims, &*signature_bytes) + let signature_bytes = base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(signature)?; + self.verify_bytes(header, claims, &signature_bytes) } } diff --git a/src/algorithm/openssl.rs b/src/algorithm/openssl.rs index fce0daaa..ca61b8e3 100644 --- a/src/algorithm/openssl.rs +++ b/src/algorithm/openssl.rs @@ -17,6 +17,7 @@ use crate::algorithm::{AlgorithmType, SigningAlgorithm, VerifyingAlgorithm}; use crate::error::Error; use crate::SEPARATOR; +use base64::Engine; use openssl::bn::BigNum; use openssl::ecdsa::EcdsaSig; use openssl::hash::MessageDigest; @@ -52,7 +53,7 @@ impl SigningAlgorithm for PKeyWithDigest { } fn sign(&self, header: &str, claims: &str) -> Result { - let mut signer = Signer::new(self.digest.clone(), &self.key)?; + let mut signer = Signer::new(self.digest, &self.key)?; signer.update(header.as_bytes())?; signer.update(SEPARATOR.as_bytes())?; signer.update(claims.as_bytes())?; @@ -64,7 +65,7 @@ impl SigningAlgorithm for PKeyWithDigest { signer_signature }; - Ok(base64::encode_config(&signature, base64::URL_SAFE_NO_PAD)) + Ok(base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(signature)) } } @@ -74,7 +75,7 @@ impl VerifyingAlgorithm for PKeyWithDigest { } fn verify_bytes(&self, header: &str, claims: &str, signature: &[u8]) -> Result { - let mut verifier = Verifier::new(self.digest.clone(), &self.key)?; + let mut verifier = Verifier::new(self.digest, &self.key)?; verifier.update(header.as_bytes())?; verifier.update(SEPARATOR.as_bytes())?; verifier.update(claims.as_bytes())?; @@ -92,7 +93,7 @@ impl VerifyingAlgorithm for PKeyWithDigest { /// OpenSSL by default signs ECDSA in DER, but JOSE expects them in a concatenated (R, S) format fn der_to_jose(der: &[u8]) -> Result, Error> { - let signature = EcdsaSig::from_der(&der)?; + let signature = EcdsaSig::from_der(der)?; let r = signature.r().to_vec(); let s = signature.s().to_vec(); Ok([r, s].concat()) @@ -119,12 +120,14 @@ mod tests { use openssl::pkey::PKey; // {"sub":"1234567890","name":"John Doe","admin":true} - const CLAIMS: &'static str = - "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9"; + const CLAIMS: &str = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9"; - const RS256_SIGNATURE: &'static str = + const RS256_SIGNATURE: &str = "cQsAHF2jHvPGFP5zTD8BgoJrnzEx6JNQCpupebWLFnOc2r_punDDTylI6Ia4JZNkvy2dQP-7W-DEbFQ3oaarHsDndqUgwf9iYlDQxz4Rr2nEZX1FX0-FMEgFPeQpdwveCgjtTYUbVy37ijUySN_rW-xZTrsh_Ug-ica8t-zHRIw"; + const PREGENERATED_ES256_SIGNATURE: &str = + "6SgeIURSNz_qFcxsKQOWZmi_ALiBctj_ZINvce4AOa-OQn9QI6lh8P78FTZx5LQtOleF3XeBlGIAdYms_VPecA"; + #[test] fn rs256_sign() -> Result<(), Error> { let pem = include_bytes!("../../test/rs256-private.pem"); @@ -155,7 +158,7 @@ mod tests { } #[test] - fn es256() -> Result<(), Error> { + fn es256_sign() -> Result<(), Error> { let private_pem = include_bytes!("../../test/es256-private.pem"); let private_key = PKeyWithDigest { digest: MessageDigest::sha256(), @@ -163,17 +166,34 @@ mod tests { }; let signature = private_key.sign(&AlgOnly(Es256).to_base64()?, CLAIMS)?; - let public_pem = include_bytes!("../../test/es256-public.pem"); - let public_key = PKeyWithDigest { digest: MessageDigest::sha256(), key: PKey::public_key_from_pem(public_pem)?, }; let verification_result = - public_key.verify(&AlgOnly(Es256).to_base64()?, CLAIMS, &*signature)?; + public_key.verify(&AlgOnly(Es256).to_base64()?, CLAIMS, &signature)?; + + assert!(verification_result); + Ok(()) + } + + #[test] + fn es256_verify() -> Result<(), Error> { + let public_pem = include_bytes!("../../test/es256-public.pem"); + let public_key = PKeyWithDigest { + digest: MessageDigest::sha256(), + key: PKey::public_key_from_pem(public_pem)?, + }; + + let verification_result = public_key.verify( + &AlgOnly(Es256).to_base64()?, + CLAIMS, + PREGENERATED_ES256_SIGNATURE, + )?; assert!(verification_result); + Ok(()) } } diff --git a/src/algorithm/rust_crypto.rs b/src/algorithm/rust_crypto.rs index ed7cc53d..35c5b89d 100644 --- a/src/algorithm/rust_crypto.rs +++ b/src/algorithm/rust_crypto.rs @@ -2,6 +2,7 @@ //! According to that organization, only hmac is safely implemented at the //! moment. +use base64::Engine; use digest::{ block_buffer::Eager, consts::U256, @@ -14,6 +15,9 @@ use hmac::{Hmac, Mac}; use crate::algorithm::{AlgorithmType, SigningAlgorithm, VerifyingAlgorithm}; use crate::error::Error; use crate::SEPARATOR; + +pub mod asymmetric; + /// A trait used to make the implementation of `SigningAlgorithm` and /// `VerifyingAlgorithm` easier. /// RustCrypto crates tend to have algorithm types defined at the type level, @@ -56,7 +60,7 @@ where let hmac = get_hmac_with_data(self, header, claims); let mac_result = hmac.finalize(); let code = mac_result.into_bytes(); - Ok(base64::encode_config(&code, base64::URL_SAFE_NO_PAD)) + Ok(base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(code)) } } diff --git a/src/algorithm/rust_crypto/asymmetric.rs b/src/algorithm/rust_crypto/asymmetric.rs new file mode 100644 index 00000000..e5af4de4 --- /dev/null +++ b/src/algorithm/rust_crypto/asymmetric.rs @@ -0,0 +1,377 @@ +use crate::algorithm::{AlgorithmType, SigningAlgorithm, VerifyingAlgorithm}; +use crate::error::Error; +use crate::SEPARATOR; + +use base64::Engine; +use digest::Digest; +use p256::pkcs8::{DecodePrivateKey, DecodePublicKey}; +use rsa::pkcs1::DecodeRsaPrivateKey; +use rsa::{RsaPrivateKey, RsaPublicKey}; +use signature::{DigestSigner, DigestVerifier, SignatureEncoding}; + +#[derive(Clone, Debug)] +pub enum VerifyingKey { + RS256(Box>), + RS384(Box>), + RS512(Box>), + EC256(Box), + EC384(Box), +} + +impl VerifyingKey { + pub fn from_ec256(key: p256::PublicKey) -> Self { + Self::EC256(p256::ecdsa::VerifyingKey::from(key).into()) + } + + pub fn from_ec384(key: p384::PublicKey) -> Self { + Self::EC384(p384::ecdsa::VerifyingKey::from(key).into()) + } + + pub fn from_rsa256(key: RsaPublicKey) -> Self { + Self::RS256(rsa::pkcs1v15::VerifyingKey::new(key).into()) + } + + pub fn from_rsa384(key: RsaPublicKey) -> Self { + Self::RS384(rsa::pkcs1v15::VerifyingKey::new(key).into()) + } + + pub fn from_rsa512(key: RsaPublicKey) -> Self { + Self::RS512(rsa::pkcs1v15::VerifyingKey::new(key).into()) + } +} + +#[derive(Clone, Debug)] +pub enum SigningKey { + RS256(Box>), + RS384(Box>), + RS512(Box>), + EC256(Box), + EC384(Box), +} + +impl SigningKey { + pub fn from_ec256(key: p256::SecretKey) -> Self { + Self::EC256(p256::ecdsa::SigningKey::from(key).into()) + } + + pub fn from_ec384(key: p384::SecretKey) -> Self { + Self::EC384(p384::ecdsa::SigningKey::from(key).into()) + } + + pub fn from_rsa256(key: RsaPrivateKey) -> Self { + Self::RS256(rsa::pkcs1v15::SigningKey::new(key).into()) + } + + pub fn from_rsa384(key: RsaPrivateKey) -> Self { + Self::RS384(rsa::pkcs1v15::SigningKey::new(key).into()) + } + + pub fn from_rsa512(key: RsaPrivateKey) -> Self { + Self::RS512(rsa::pkcs1v15::SigningKey::new(key).into()) + } +} + +pub use ::{digest, ecdsa, p256, rsa, signature}; + +#[derive(Clone, Debug)] +pub enum PublicKey { + RSA(Box), + EC256(Box), + EC384(Box), +} + +impl PublicKey { + pub fn from_pem_bytes(encoded: &[u8]) -> Result { + Self::from_pem(std::str::from_utf8(encoded).map_err(|_| Error::InvalidKey)?) + } + + pub fn from_pem(encoded: &str) -> Result { + if let Ok(ec) = encoded.parse::() { + Ok(PublicKey::EC384(ec.into())) + } else if let Ok(ec) = encoded.parse::() { + Ok(PublicKey::EC256(ec.into())) + } else if let Ok(rsa) = rsa::RsaPublicKey::from_public_key_pem(encoded) { + Ok(PublicKey::RSA(rsa.into())) + } else { + Err(Error::InvalidKey) + } + } + + pub fn into_rsa(self) -> Result { + match self { + PublicKey::RSA(rsa) => Ok(*rsa), + _ => Err(self), + } + } + + pub fn into_ec256(self) -> Result { + match self { + PublicKey::EC256(ec) => Ok(*ec), + _ => Err(self), + } + } + + pub fn into_ec384(self) -> Result { + match self { + PublicKey::EC384(ec) => Ok(*ec), + _ => Err(self), + } + } +} + +#[derive(Clone, Debug)] +pub enum PrivateKey { + RSA(Box), + EC256(Box), + EC384(Box), +} + +impl PrivateKey { + pub fn from_pem_bytes(encoded: &[u8]) -> Result { + Self::from_pem(std::str::from_utf8(encoded).map_err(|_| Error::InvalidKey)?) + } + + pub fn from_pem(pem: &str) -> Result { + if let Ok(ec) = pem.parse::() { + Ok(PrivateKey::EC384(ec.into())) + } else if let Ok(ec) = pem.parse::() { + Ok(PrivateKey::EC256(ec.into())) + } else if let Ok(rsa) = rsa::RsaPrivateKey::from_pkcs8_pem(pem) { + Ok(PrivateKey::RSA(rsa.into())) + } else if let Ok(rsa) = rsa::RsaPrivateKey::from_pkcs1_pem(pem) { + Ok(PrivateKey::RSA(rsa.into())) + } else { + Err(Error::InvalidKey) + } + } + + pub fn into_rsa(self) -> Result { + match self { + PrivateKey::RSA(rsa) => Ok(*rsa), + _ => Err(self), + } + } + + pub fn into_ec256(self) -> Result { + match self { + PrivateKey::EC256(ec) => Ok(*ec), + _ => Err(self), + } + } + + pub fn into_ec384(self) -> Result { + match self { + PrivateKey::EC384(ec) => Ok(*ec), + _ => Err(self), + } + } +} + +pub struct AsymmetricKeyWithDigest { + key: K, +} + +impl AsymmetricKeyWithDigest { + pub fn new(key: K) -> Self { + Self { key } + } +} + +impl SigningAlgorithm for AsymmetricKeyWithDigest { + fn algorithm_type(&self) -> AlgorithmType { + match self.key { + SigningKey::RS256(_) => AlgorithmType::Rs256, + SigningKey::RS384(_) => AlgorithmType::Rs384, + SigningKey::RS512(_) => AlgorithmType::Rs512, + SigningKey::EC256(_) => AlgorithmType::Es256, + SigningKey::EC384(_) => AlgorithmType::Es384, + } + } + + fn sign(&self, header: &str, claims: &str) -> Result { + macro_rules! short_hand { + ($key:ident, $hash:ty, $sig:ty) => { + let mut digest = <$hash>::new(); + + digest.update(header.as_bytes()); + digest.update(SEPARATOR.as_bytes()); + digest.update(claims.as_bytes()); + + let signed: $sig = $key.try_sign_digest(digest)?; + + return Ok( + base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(signed.to_bytes()) + ); + }; + } + + match &self.key { + SigningKey::RS256(key) => { + short_hand!(key, sha2::Sha256, rsa::pkcs1v15::Signature); + } + SigningKey::RS384(key) => { + short_hand!(key, sha2::Sha384, rsa::pkcs1v15::Signature); + } + SigningKey::RS512(key) => { + short_hand!(key, sha2::Sha512, rsa::pkcs1v15::Signature); + } + SigningKey::EC256(key) => { + short_hand!(key, sha2::Sha256, p256::ecdsa::Signature); + } + SigningKey::EC384(key) => { + short_hand!(key, sha2::Sha384, p384::ecdsa::Signature); + } + } + } +} + +impl VerifyingAlgorithm for AsymmetricKeyWithDigest { + fn algorithm_type(&self) -> AlgorithmType { + match self.key { + VerifyingKey::RS256(_) => AlgorithmType::Rs256, + VerifyingKey::RS384(_) => AlgorithmType::Rs384, + VerifyingKey::RS512(_) => AlgorithmType::Rs512, + VerifyingKey::EC256(_) => AlgorithmType::Es256, + VerifyingKey::EC384(_) => AlgorithmType::Es384, + } + } + + fn verify_bytes(&self, header: &str, claims: &str, signature: &[u8]) -> Result { + macro_rules! short_hand { + ($key:ident, $hash:ty, $sig:ty) => { + let mut digest = <$hash>::new(); + + digest.update(header.as_bytes()); + digest.update(SEPARATOR.as_bytes()); + digest.update(claims.as_bytes()); + + let signature = <$sig>::try_from(signature).map_err(|_| Error::InvalidSignature)?; + + return Ok($key.verify_digest(digest, &signature).is_ok()); + }; + } + + match &self.key { + VerifyingKey::RS256(key) => { + short_hand!(key, sha2::Sha256, rsa::pkcs1v15::Signature); + } + VerifyingKey::RS384(key) => { + short_hand!(key, sha2::Sha384, rsa::pkcs1v15::Signature); + } + VerifyingKey::RS512(key) => { + short_hand!(key, sha2::Sha512, rsa::pkcs1v15::Signature); + } + VerifyingKey::EC256(key) => { + short_hand!(key, sha2::Sha256, p256::ecdsa::Signature); + } + VerifyingKey::EC384(key) => { + short_hand!(key, sha2::Sha384, p384::ecdsa::Signature); + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::algorithm::AlgorithmType::*; + use crate::algorithm::{SigningAlgorithm, VerifyingAlgorithm}; + use crate::error::Error; + use crate::header::PrecomputedAlgorithmOnlyHeader as AlgOnly; + use crate::ToBase64; + + // {"sub":"1234567890","name":"John Doe","admin":true} + const CLAIMS: &str = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9"; + + const RS256_SIGNATURE: &str = + "cQsAHF2jHvPGFP5zTD8BgoJrnzEx6JNQCpupebWLFnOc2r_punDDTylI6Ia4JZNkvy2dQP-7W-DEbFQ3oaarHsDndqUgwf9iYlDQxz4Rr2nEZX1FX0-FMEgFPeQpdwveCgjtTYUbVy37ijUySN_rW-xZTrsh_Ug-ica8t-zHRIw"; + + const PREGENERATED_ES256_SIGNATURE: &str = + "6SgeIURSNz_qFcxsKQOWZmi_ALiBctj_ZINvce4AOa-OQn9QI6lh8P78FTZx5LQtOleF3XeBlGIAdYms_VPecA"; + + #[test] + fn rs256_sign() -> Result<(), Error> { + let key = PrivateKey::from_pem_bytes(include_bytes!("../../../test/rs256-private.pem"))?; + let signer = AsymmetricKeyWithDigest::new(SigningKey::from_rsa256(key.into_rsa().unwrap())); + let result = signer.sign(&AlgOnly(Rs256).to_base64()?, CLAIMS)?; + assert_eq!(result, RS256_SIGNATURE); + Ok(()) + } + + #[test] + fn rs256_verify() -> Result<(), Error> { + let key = PublicKey::from_pem_bytes(include_bytes!("../../../test/rs256-public.pem"))?; + let verifier = + AsymmetricKeyWithDigest::new(VerifyingKey::from_rsa256(key.into_rsa().unwrap())); + assert!( + verifier.verify(&AlgOnly(Rs256).to_base64()?, CLAIMS, RS256_SIGNATURE)?, + "signature should be valid" + ); + Ok(()) + } + + #[test] + fn es256_sign() -> Result<(), Error> { + let key = PrivateKey::from_pem_bytes(include_bytes!("../../../test/es256-private.pem"))?; + let signer = + AsymmetricKeyWithDigest::new(SigningKey::from_ec256(key.into_ec256().unwrap())); + let signature = signer.sign(&AlgOnly(Es256).to_base64()?, CLAIMS)?; + + let key = PublicKey::from_pem_bytes(include_bytes!("../../../test/es256-public.pem"))?; + let verifier = + AsymmetricKeyWithDigest::new(VerifyingKey::from_ec256(key.into_ec256().unwrap())); + assert!( + verifier.verify(&AlgOnly(Es256).to_base64()?, CLAIMS, &signature)?, + "signature should be valid" + ); + Ok(()) + } + + #[test] + fn es256_verify() -> Result<(), Error> { + let key = PublicKey::from_pem_bytes(include_bytes!("../../../test/es256-public.pem"))?; + let verifier = + AsymmetricKeyWithDigest::new(VerifyingKey::from_ec256(key.into_ec256().unwrap())); + assert!( + verifier.verify( + &AlgOnly(Es256).to_base64()?, + CLAIMS, + PREGENERATED_ES256_SIGNATURE + )?, + "signature should be valid" + ); + + Ok(()) + } + + #[test] + fn genric_public_key_parse() -> Result<(), Error> { + match PublicKey::from_pem_bytes(include_bytes!("../../../test/rs256-public.pem")) { + Ok(PublicKey::RSA(_)) => {} + _ => panic!("invalid rsa key"), + } + + match PublicKey::from_pem_bytes(include_bytes!("../../../test/es256-public.pem")) { + Ok(PublicKey::EC256(_)) => {} + _ => panic!("invalid ec key"), + } + + Ok(()) + } + + #[test] + fn genric_private_key_parse() -> Result<(), Error> { + match PrivateKey::from_pem_bytes(include_bytes!("../../../test/rs256-private.pem")) { + Ok(PrivateKey::RSA(_)) => {} + _ => panic!("invalid rsa key"), + } + + match PrivateKey::from_pem_bytes(include_bytes!("../../../test/es256-private.pem")) { + Ok(PrivateKey::EC256(_)) => {} + _ => panic!("invalid ec key"), + } + + Ok(()) + } +} diff --git a/src/error.rs b/src/error.rs index 1e9f3762..5912fdff 100644 --- a/src/error.rs +++ b/src/error.rs @@ -25,6 +25,8 @@ pub enum Error { RustCryptoMacKeyLength(InvalidLength), TooManyComponents, Utf8(FromUtf8Error), + Signature(signature::Error), + InvalidKey, #[cfg(feature = "openssl")] OpenSsl(openssl::error::ErrorStack), } @@ -48,6 +50,8 @@ impl fmt::Display for Error { Utf8(ref x) => write!(f, "{}", x), RustCryptoMac(ref x) => write!(f, "{}", x), RustCryptoMacKeyLength(ref x) => write!(f, "{}", x), + Signature(ref x) => write!(f, "{}", x), + InvalidKey => write!(f, "Invalid key"), #[cfg(feature = "openssl")] OpenSsl(ref x) => write!(f, "{}", x), } @@ -71,5 +75,6 @@ error_wrap!(JsonError, Json); error_wrap!(FromUtf8Error, Utf8); error_wrap!(MacError, RustCryptoMac); error_wrap!(InvalidLength, RustCryptoMacKeyLength); +error_wrap!(signature::Error, Signature); #[cfg(feature = "openssl")] error_wrap!(openssl::error::ErrorStack, Error::OpenSsl); diff --git a/src/lib.rs b/src/lib.rs index 85a99cd6..f9095ea9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -94,12 +94,14 @@ doctest!("../README.md"); use std::borrow::Cow; +use base64::Engine; #[cfg(doctest)] use doc_comment::doctest; use serde::{Deserialize, Serialize}; #[cfg(feature = "openssl")] pub use crate::algorithm::openssl::PKeyWithDigest; +pub use crate::algorithm::rust_crypto::asymmetric; pub use crate::algorithm::store::Store; pub use crate::algorithm::{AlgorithmType, SigningAlgorithm, VerifyingAlgorithm}; pub use crate::claims::Claims; @@ -163,7 +165,8 @@ pub trait ToBase64 { impl ToBase64 for T { fn to_base64(&self) -> Result, Error> { let json_bytes = serde_json::to_vec(&self)?; - let encoded_json_bytes = base64::encode_config(&json_bytes, base64::URL_SAFE_NO_PAD); + let encoded_json_bytes = + base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(json_bytes); Ok(Cow::Owned(encoded_json_bytes)) } } @@ -180,7 +183,7 @@ pub trait FromBase64: Sized { impl Deserialize<'de> + Sized> FromBase64 for T { fn from_base64>(raw: &Input) -> Result { - let json_bytes = base64::decode_config(raw, base64::URL_SAFE_NO_PAD)?; + let json_bytes = base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(raw)?; Ok(serde_json::from_slice(&json_bytes)?) } } diff --git a/src/token/signed.rs b/src/token/signed.rs index 6cda0123..014f86fb 100644 --- a/src/token/signed.rs +++ b/src/token/signed.rs @@ -124,7 +124,7 @@ where } } -impl<'a, H, C> Token { +impl Token { /// Get the string representation of the token. pub fn as_str(&self) -> &str { &self.signature.token_string diff --git a/test/es256-private.pem b/test/es256-private.pem index 8548ca88..4d834eaf 100644 --- a/test/es256-private.pem +++ b/test/es256-private.pem @@ -1,5 +1,5 @@ ------BEGIN EC PRIVATE KEY----- -MHcCAQEEIDaCNjB5eSARlkILmSrpnfoI8TYi7tJ7xzpy4Bb1D6HVoAoGCCqGSM49 -AwEHoUQDQgAEU9PK2chNDTNdJygt1lkhLwuhLOkcuG90J5kHbnHNC/PG9ww1D7q0 -d9dWWzfRfZfx3Duw+3j8NnBt6zBgnUG5Uw== ------END EC PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgNoI2MHl5IBGWQguZ +Kumd+gjxNiLu0nvHOnLgFvUPodWhRANCAART08rZyE0NM10nKC3WWSEvC6Es6Ry4 +b3QnmQducc0L88b3DDUPurR311ZbN9F9l/HcO7D7ePw2cG3rMGCdQblT +-----END PRIVATE KEY----- diff --git a/test/rs256-private.pem b/test/rs256-private.pem index 3b15b704..5202dfbc 100644 --- a/test/rs256-private.pem +++ b/test/rs256-private.pem @@ -1,3 +1,16 @@ ------BEGIN RSA PRIVATE KEY----- -MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQABAoGAD+onAtVye4ic7VR7V50DF9bOnwRwNXrARcDhq9LWNRrRGElESYYTQ6EbatXS3MCyjjX2eMhu/aF5YhXBwkppwxg+EOmXeh+MzL7Zh284OuPbkglAaGhV9bb6/5CpuGb1esyPbYW+Ty2PC0GSZfIXkXs76jXAu9TOBvD0ybc2YlkCQQDywg2R/7t3Q2OE2+yo382CLJdrlSLVROWKwb4tb2PjhY4XAwV8d1vy0RenxTB+K5Mu57uVSTHtrMK0GAtFr833AkEA6avx20OHo61Yela/4k5kQDtjEf1N0LfI+BcWZtxsS3jDM3i1Hp0KSu5rsCPb8acJo5RO26gGVrfAsDcIXKC+bQJAZZ2XIpsitLyPpuiMOvBbzPavd4gY6Z8KWrfYzJoI/Q9FuBo6rKwl4BFoToD7WIUS+hpkagwWiz+6zLoX1dbOZwJACmH5fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/SySDOxQ4G/523Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDabxrE9MNUZ2aPFaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw== ------END RSA PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAN2Vq1GNGOiCjdai +OAYcUdgu6B1RYBj2JHd/LhqtY0DUqhLyRXDfdwmJtevxu/BQBSlqsLCW91sfp28Q +5+i7T+AIVCwdR9CtIO/4y5JQwB7yPMoTipb6Mr7FBT1rTcZScoeSSV75DSlf+DqN +dnuvX/EArkOjaRD5fnEr1yKlGAQrAgMBAAECgYAP6icC1XJ7iJztVHtXnQMX1s6f +BHA1esBFwOGr0tY1GtEYSURJhhNDoRtq1dLcwLKONfZ4yG79oXliFcHCSmnDGD4Q +6Zd6H4zMvtmHbzg649uSCUBoaFX1tvr/kKm4ZvV6zI9thb5PLY8LQZJl8heRezvq +NcC71M4G8PTJtzZiWQJBAPLCDZH/u3dDY4Tb7KjfzYIsl2uVItVE5YrBvi1vY+OF +jhcDBXx3W/LRF6fFMH4rky7nu5VJMe2swrQYC0WvzfcCQQDpq/HbQ4ejrVh6Vr/i +TmRAO2MR/U3Qt8j4FxZm3GxLeMMzeLUenQpK7muwI9vxpwmjlE7bqAZWt8CwNwhc +oL5tAkBlnZcimyK0vI+m6Iw68FvM9q93iBjpnwpat9jMmgj9D0W4GjqsrCXgEWhO +gPtYhRL6GmRqDBaLP7rMuhfV1s5nAkAKYfl9JKMCQtGLng8onxMVR44/XmH2xDPJ +0jzMlT66m8MQpmxlz9SFP9LJIM7FDgb/nbdjSzP85m1JZyiX9QyBAkAt6zL74Z2+ +ggMt8lfkYFCm4WAV6dGJENpvGsT0w1RnZo8VoWn4PIB75vicPC4lpbYtRFuvwARm +BruhCPS5jFxj +-----END PRIVATE KEY----- diff --git a/test/rs256-public.pem b/test/rs256-public.pem index 4f194663..c6bbd08e 100644 --- a/test/rs256-public.pem +++ b/test/rs256-public.pem @@ -1,3 +1,6 @@ -----BEGIN PUBLIC KEY----- -MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQAB +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd +UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs +HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D +o2kQ+X5xK9cipRgEKwIDAQAB -----END PUBLIC KEY-----