Make DecodingKey own all the data

Closes #120
Supersedes #128
This commit is contained in:
Vincent Prouillet 2021-02-19 21:41:08 +01:00
parent 60c92f2882
commit c9442834ed
4 changed files with 41 additions and 56 deletions

View File

@ -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<bool> {
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())
}

View File

@ -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<u8>),
RsaModulusExponent { n: Vec<u8>, e: Vec<u8> },
}
/// 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<Self> {
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<Self> {
pub fn from_rsa_pem(key: &[u8]) -> Result<Self> {
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<Self> {
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<Self> {
pub fn from_ec_pem(key: &[u8]) -> Result<Self> {
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<Self> {
pub fn from_ed_pem(key: &[u8]) -> Result<Self> {
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,

View File

@ -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::<Claims>(&token, &DecodingKey::from_secret(b"secret"), &Validation::default())

View File

@ -117,7 +117,7 @@ fn rsa_modulus_exponent() {
.unwrap();
let res = decode::<Claims>(
&encrypted,
&DecodingKey::from_rsa_components(n, e),
&DecodingKey::from_rsa_components(n, e).unwrap(),
&Validation::new(Algorithm::RS256),
);
assert!(res.is_ok());