From a750d5586f0b9f3ffc3867469ea5f6b145d644b2 Mon Sep 17 00:00:00 2001 From: Hexilee Date: Fri, 28 Feb 2020 01:26:58 +0800 Subject: [PATCH] fix issue 120: DecodingKey can be converted to static --- src/decoding.rs | 80 ++++++++++++++++++++++++++++++------------------- src/errors.rs | 8 +++-- 2 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/decoding.rs b/src/decoding.rs index 36837f0..c8ea4e4 100644 --- a/src/decoding.rs +++ b/src/decoding.rs @@ -34,7 +34,7 @@ macro_rules! expect_two { #[derive(Debug, Clone, PartialEq)] pub(crate) enum DecodingKeyKind<'a> { SecretOrDer(Cow<'a, [u8]>), - RsaModulusExponent { n: &'a str, e: &'a str }, + RsaModulusExponent { n: Cow<'a, str>, e: Cow<'a, str> }, } /// All the different kind of keys we can use to decode a JWT @@ -54,43 +54,17 @@ impl<'a> DecodingKey<'a> { } } - /// If you're using HMAC with a base64 encoded, 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)), - }) - } - - /// If you are loading a public RSA key in a PEM format, use this. - pub fn from_rsa_pem(key: &'a [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())), - }) - } - /// If you have (n, e) RSA public key components, use this. pub fn from_rsa_components(modulus: &'a str, exponent: &'a str) -> Self { DecodingKey { family: AlgorithmFamily::Rsa, - kind: DecodingKeyKind::RsaModulusExponent { n: modulus, e: exponent }, + kind: DecodingKeyKind::RsaModulusExponent { + n: Cow::Borrowed(modulus), + e: Cow::Borrowed(exponent), + }, } } - /// If you have a ECDSA public key in PEM format, use this. - pub fn from_ec_pem(key: &'a [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())), - }) - } - /// 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 { DecodingKey { @@ -107,6 +81,19 @@ impl<'a> DecodingKey<'a> { } } + /// 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, @@ -115,6 +102,37 @@ impl<'a> DecodingKey<'a> { } } +impl DecodingKey<'static> { + /// If you're using HMAC with a base64 encoded, 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)), + }) + } + + /// If you are loading a public RSA key in a PEM format, use this. + 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())), + }) + } + + /// If you have a ECDSA public key in PEM format, use this. + 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())), + }) + } +} + /// Decode and validate a JWT /// /// If the token or its signature is invalid or the claims fail validation, it will return an error. diff --git a/src/errors.rs b/src/errors.rs index 49e6f09..c016be2 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -169,7 +169,9 @@ mod tests { #[test] fn test_error_rendering() { - assert_eq!("InvalidAlgorithmName", Error::from(ErrorKind::InvalidAlgorithmName).to_string()); + assert_eq!( + "InvalidAlgorithmName", + Error::from(ErrorKind::InvalidAlgorithmName).to_string() + ); } - -} \ No newline at end of file +}