From c9442834edf8161c77421c6f76e02ff2577ad4bb Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Fri, 19 Feb 2021 21:41:08 +0100 Subject: [PATCH] Make DecodingKey own all the data Closes #120 Supersedes #128 --- src/crypto/rsa.rs | 7 ++-- src/decoding.rs | 85 +++++++++++++++++++++-------------------------- tests/hmac.rs | 3 +- tests/rsa/mod.rs | 2 +- 4 files changed, 41 insertions(+), 56 deletions(-) diff --git a/src/crypto/rsa.rs b/src/crypto/rsa.rs index d0b2f4d..687ca97 100644 --- a/src/crypto/rsa.rs +++ b/src/crypto/rsa.rs @@ -1,5 +1,4 @@ use ring::{rand, signature}; -use simple_asn1::BigUint; use crate::algorithms::Algorithm; use crate::errors::{ErrorKind, Result}; @@ -54,12 +53,10 @@ pub(crate) fn verify_from_components( alg: &'static signature::RsaParameters, signature: &str, message: &[u8], - components: (&str, &str), + components: (&[u8], &[u8]), ) -> Result { let signature_bytes = b64_decode(signature)?; - let n = BigUint::from_bytes_be(&b64_decode(components.0)?).to_bytes_be(); - let e = BigUint::from_bytes_be(&b64_decode(components.1)?).to_bytes_be(); - let pubkey = signature::RsaPublicKeyComponents { n, e }; + let pubkey = signature::RsaPublicKeyComponents { n: components.0, e: components.1 }; let res = pubkey.verify(alg, message, &signature_bytes); Ok(res.is_ok()) } diff --git a/src/decoding.rs b/src/decoding.rs index 43d2214..9e3e0d0 100644 --- a/src/decoding.rs +++ b/src/decoding.rs @@ -1,5 +1,3 @@ -use std::borrow::Cow; - use serde::de::DeserializeOwned; use crate::algorithms::AlgorithmFamily; @@ -7,7 +5,7 @@ use crate::crypto::verify; use crate::errors::{new_error, ErrorKind, Result}; use crate::header::Header; use crate::pem::decoder::PemEncodedKey; -use crate::serialization::from_jwt_part_claims; +use crate::serialization::{b64_decode, from_jwt_part_claims}; use crate::validation::{validate, Validation}; /// The return type of a successful call to [decode](fn.decode.html). @@ -32,115 +30,106 @@ macro_rules! expect_two { } #[derive(Debug, Clone, PartialEq)] -pub(crate) enum DecodingKeyKind<'a> { - SecretOrDer(Cow<'a, [u8]>), - RsaModulusExponent { n: Cow<'a, str>, e: Cow<'a, str> }, +pub(crate) enum DecodingKeyKind { + SecretOrDer(Vec), + RsaModulusExponent { n: Vec, e: Vec }, } /// All the different kind of keys we can use to decode a JWT /// This key can be re-used so make sure you only initialize it once if you can for better performance #[derive(Debug, Clone, PartialEq)] -pub struct DecodingKey<'a> { +pub struct DecodingKey { pub(crate) family: AlgorithmFamily, - pub(crate) kind: DecodingKeyKind<'a>, + pub(crate) kind: DecodingKeyKind, } -impl<'a> DecodingKey<'a> { +impl DecodingKey { /// If you're using HMAC, use this. - pub fn from_secret(secret: &'a [u8]) -> Self { + pub fn from_secret(secret: &[u8]) -> Self { DecodingKey { family: AlgorithmFamily::Hmac, - kind: DecodingKeyKind::SecretOrDer(Cow::Borrowed(secret)), + kind: DecodingKeyKind::SecretOrDer(secret.to_vec()), } } - /// If you're using HMAC with a base64 encoded, use this. + /// If you're using HMAC with a base64 encoded secret, use this. pub fn from_base64_secret(secret: &str) -> Result { let out = base64::decode(&secret)?; - Ok(DecodingKey { - family: AlgorithmFamily::Hmac, - kind: DecodingKeyKind::SecretOrDer(Cow::Owned(out)), - }) + Ok(DecodingKey { family: AlgorithmFamily::Hmac, kind: DecodingKeyKind::SecretOrDer(out) }) } /// If you are loading a public RSA key in a PEM format, use this. - pub fn from_rsa_pem(key: &'a [u8]) -> Result { + pub fn from_rsa_pem(key: &[u8]) -> Result { let pem_key = PemEncodedKey::new(key)?; let content = pem_key.as_rsa_key()?; Ok(DecodingKey { family: AlgorithmFamily::Rsa, - kind: DecodingKeyKind::SecretOrDer(Cow::Owned(content.to_vec())), + kind: DecodingKeyKind::SecretOrDer(content.to_vec()), }) } - /// If you have (n, e) RSA public key components, use this. - pub fn from_rsa_components(modulus: &'a str, exponent: &'a str) -> Self { + /// If you have (n, e) RSA public key components as strings, use this. + pub fn from_rsa_components(modulus: &str, exponent: &str) -> Result { + let n = b64_decode(modulus)?; + let e = b64_decode(exponent)?; + Ok(DecodingKey { + family: AlgorithmFamily::Rsa, + kind: DecodingKeyKind::RsaModulusExponent { n, e }, + }) + } + + /// If you have (n, e) RSA public key components already decoded, use this. + /// TODO: do we need that? + pub fn from_rsa_raw_components(modulus: &[u8], exponent: &[u8]) -> Self { DecodingKey { family: AlgorithmFamily::Rsa, - kind: DecodingKeyKind::RsaModulusExponent { - n: Cow::Borrowed(modulus), - e: Cow::Borrowed(exponent), - }, + kind: DecodingKeyKind::RsaModulusExponent { n: modulus.to_vec(), e: exponent.to_vec() }, } } /// If you have a ECDSA public key in PEM format, use this. - pub fn from_ec_pem(key: &'a [u8]) -> Result { + pub fn from_ec_pem(key: &[u8]) -> Result { let pem_key = PemEncodedKey::new(key)?; let content = pem_key.as_ec_public_key()?; Ok(DecodingKey { family: AlgorithmFamily::Ec, - kind: DecodingKeyKind::SecretOrDer(Cow::Owned(content.to_vec())), + kind: DecodingKeyKind::SecretOrDer(content.to_vec()), }) } /// If you have a EdDSA public key in PEM format, use this. - pub fn from_ed_pem(key: &'a [u8]) -> Result { + pub fn from_ed_pem(key: &[u8]) -> Result { let pem_key = PemEncodedKey::new(key)?; let content = pem_key.as_ed_public_key()?; Ok(DecodingKey { family: AlgorithmFamily::Ed, - kind: DecodingKeyKind::SecretOrDer(Cow::Owned(content.to_vec())), + kind: DecodingKeyKind::SecretOrDer(content.to_vec()), }) } /// If you know what you're doing and have a RSA DER encoded public key, use this. - pub fn from_rsa_der(der: &'a [u8]) -> Self { + pub fn from_rsa_der(der: &[u8]) -> Self { DecodingKey { family: AlgorithmFamily::Rsa, - kind: DecodingKeyKind::SecretOrDer(Cow::Borrowed(der)), + kind: DecodingKeyKind::SecretOrDer(der.to_vec()), } } /// If you know what you're doing and have a RSA EC encoded public key, use this. - pub fn from_ec_der(der: &'a [u8]) -> Self { + pub fn from_ec_der(der: &[u8]) -> Self { DecodingKey { family: AlgorithmFamily::Ec, - kind: DecodingKeyKind::SecretOrDer(Cow::Borrowed(der)), + kind: DecodingKeyKind::SecretOrDer(der.to_vec()), } } /// If you know what you're doing and have a Ed DER encoded public key, use this. - pub fn from_ed_der(der: &'a [u8]) -> Self { + pub fn from_ed_der(der: &[u8]) -> Self { DecodingKey { family: AlgorithmFamily::Ed, - kind: DecodingKeyKind::SecretOrDer(Cow::Borrowed(der)), + kind: DecodingKeyKind::SecretOrDer(der.to_vec()), } } - - /// Convert self to `DecodingKey<'static>`. - pub fn into_static(self) -> DecodingKey<'static> { - use DecodingKeyKind::*; - let DecodingKey { family, kind } = self; - let static_kind = match kind { - SecretOrDer(key) => SecretOrDer(Cow::Owned(key.into_owned())), - RsaModulusExponent { n, e } => { - RsaModulusExponent { n: Cow::Owned(n.into_owned()), e: Cow::Owned(e.into_owned()) } - } - }; - DecodingKey { family, kind: static_kind } - } - pub(crate) fn as_bytes(&self) -> &[u8] { match &self.kind { DecodingKeyKind::SecretOrDer(b) => &b, diff --git a/tests/hmac.rs b/tests/hmac.rs index 4ab65b2..b2785ad 100644 --- a/tests/hmac.rs +++ b/tests/hmac.rs @@ -37,8 +37,7 @@ fn encode_with_custom_header() { company: "ACME".to_string(), exp: Utc::now().timestamp() + 10000, }; - let mut header = Header::default(); - header.kid = Some("kid".to_string()); + let mut header = Header { kid: Some("kid".to_string()), ..Default::default() }; let token = encode(&header, &my_claims, &EncodingKey::from_secret(b"secret")).unwrap(); let token_data = decode::(&token, &DecodingKey::from_secret(b"secret"), &Validation::default()) diff --git a/tests/rsa/mod.rs b/tests/rsa/mod.rs index fa1f80a..a05e7b4 100644 --- a/tests/rsa/mod.rs +++ b/tests/rsa/mod.rs @@ -117,7 +117,7 @@ fn rsa_modulus_exponent() { .unwrap(); let res = decode::( &encrypted, - &DecodingKey::from_rsa_components(n, e), + &DecodingKey::from_rsa_components(n, e).unwrap(), &Validation::new(Algorithm::RS256), ); assert!(res.is_ok());