From e3632b3a2c874b6112516d23b4a952a2305a570f Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Wed, 6 Nov 2019 22:32:13 +0000 Subject: [PATCH] Remove Key approach in favour of &[u8] with pem --- examples/custom_chrono.rs | 13 ++- examples/custom_header.rs | 19 ++-- examples/validation.rs | 6 +- src/algorithms.rs | 4 +- src/crypto.rs | 71 ++++---------- src/errors.rs | 10 +- src/keys.rs | 16 ---- src/lib.rs | 36 +------- src/pem_decoder.rs | 63 ++++++++----- src/pem_encoder.rs | 190 +++++++++++++++++++------------------- src/serialization.rs | 3 +- tests/ec/mod.rs | 35 ++++--- tests/hmac.rs | 26 +++--- tests/rsa/mod.rs | 121 ++++++++++-------------- 14 files changed, 262 insertions(+), 351 deletions(-) delete mode 100644 src/keys.rs diff --git a/examples/custom_chrono.rs b/examples/custom_chrono.rs index fa6d868..e0b1185 100644 --- a/examples/custom_chrono.rs +++ b/examples/custom_chrono.rs @@ -1,5 +1,5 @@ use chrono::prelude::*; -use jsonwebtoken::{Header, Key, Validation}; +use jsonwebtoken::{Header, Validation}; use serde::{Deserialize, Serialize}; const SECRET: &str = "some-secret"; @@ -51,14 +51,13 @@ mod jwt_numeric_date { let claims = Claims { sub: sub.clone(), iat, exp }; - let token = encode(&Header::default(), &claims, Key::Hmac(SECRET.as_ref())) + let token = encode(&Header::default(), &claims, SECRET.as_ref()) .expect("Failed to encode claims"); assert_eq!(&token, EXPECTED_TOKEN); - let decoded = - decode::(&token, Key::Hmac(SECRET.as_ref()), &Validation::default()) - .expect("Failed to decode token"); + let decoded = decode::(&token, SECRET.as_ref(), &Validation::default()) + .expect("Failed to decode token"); assert_eq!(decoded.claims, claims); } @@ -83,12 +82,12 @@ fn main() -> Result<(), Box> { let claims = Claims { sub: sub.clone(), iat, exp }; - let token = jsonwebtoken::encode(&Header::default(), &claims, Key::Hmac(SECRET.as_ref()))?; + let token = jsonwebtoken::encode(&Header::default(), &claims, SECRET.as_ref())?; println!("serialized token: {}", &token); let token_data = - jsonwebtoken::decode::(&token, Key::Hmac(SECRET.as_ref()), &Validation::default())?; + jsonwebtoken::decode::(&token, SECRET.as_ref(), &Validation::default())?; println!("token data:\n{:#?}", &token_data); Ok(()) diff --git a/examples/custom_header.rs b/examples/custom_header.rs index d4e5c58..f298c8d 100644 --- a/examples/custom_header.rs +++ b/examples/custom_header.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use jsonwebtoken::errors::ErrorKind; -use jsonwebtoken::{decode, encode, Algorithm, Header, Key, Validation}; +use jsonwebtoken::{decode, encode, Algorithm, Header, Validation}; #[derive(Debug, Serialize, Deserialize)] struct Claims { @@ -19,20 +19,19 @@ fn main() { header.kid = Some("signing_key".to_owned()); header.alg = Algorithm::HS512; - let token = match encode(&header, &my_claims, Key::Hmac(key)) { + let token = match encode(&header, &my_claims, key) { Ok(t) => t, Err(_) => panic!(), // in practice you would return the error }; println!("{:?}", token); - let token_data = - match decode::(&token, Key::Hmac(key), &Validation::new(Algorithm::HS512)) { - Ok(c) => c, - Err(err) => match *err.kind() { - ErrorKind::InvalidToken => panic!(), // Example on how to handle a specific error - _ => panic!(), - }, - }; + let token_data = match decode::(&token, key, &Validation::new(Algorithm::HS512)) { + Ok(c) => c, + Err(err) => match *err.kind() { + ErrorKind::InvalidToken => panic!(), // Example on how to handle a specific error + _ => panic!(), + }, + }; println!("{:?}", token_data.claims); println!("{:?}", token_data.header); } diff --git a/examples/validation.rs b/examples/validation.rs index bfc6bcc..6c22d3f 100644 --- a/examples/validation.rs +++ b/examples/validation.rs @@ -1,5 +1,5 @@ use jsonwebtoken::errors::ErrorKind; -use jsonwebtoken::{decode, encode, Header, Key, Validation}; +use jsonwebtoken::{decode, encode, Header, Validation}; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] @@ -13,13 +13,13 @@ fn main() { let my_claims = Claims { sub: "b@b.com".to_owned(), company: "ACME".to_owned(), exp: 10000000000 }; let key = b"secret"; - let token = match encode(&Header::default(), &my_claims, Key::Hmac(key)) { + let token = match encode(&Header::default(), &my_claims, key) { Ok(t) => t, Err(_) => panic!(), // in practice you would return the error }; let validation = Validation { sub: Some("b@b.com".to_string()), ..Validation::default() }; - let token_data = match decode::(&token, Key::Hmac(key), &validation) { + let token_data = match decode::(&token, key, &validation) { Ok(c) => c, Err(err) => match *err.kind() { ErrorKind::InvalidToken => panic!("Token is invalid"), // Example on how to handle a specific error diff --git a/src/algorithms.rs b/src/algorithms.rs index 09c8b17..6054125 100644 --- a/src/algorithms.rs +++ b/src/algorithms.rs @@ -1,4 +1,4 @@ -use crate::errors::{new_error, Error, ErrorKind, Result}; +use crate::errors::{Error, ErrorKind, Result}; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -53,7 +53,7 @@ impl FromStr for Algorithm { "PS384" => Ok(Algorithm::PS384), "PS512" => Ok(Algorithm::PS512), "RS512" => Ok(Algorithm::RS512), - _ => Err(new_error(ErrorKind::InvalidAlgorithmName)), + _ => Err(ErrorKind::InvalidAlgorithmName.into()), } } } diff --git a/src/crypto.rs b/src/crypto.rs index 804f082..ad95dc1 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -3,32 +3,23 @@ use ring::constant_time::verify_slices_are_equal; use ring::{hmac, rand, signature}; use crate::algorithms::Algorithm; -use crate::errors::{new_error, ErrorKind, Result}; -use crate::keys::Key; +use crate::errors::{ErrorKind, Result}; +use crate::pem_decoder::PemEncodedKey; /// The actual HS signing + encoding -fn sign_hmac(alg: hmac::Algorithm, key: Key, signing_input: &str) -> Result { - let signing_key = match key { - Key::Hmac(bytes) => hmac::Key::new(alg, bytes), - _ => return Err(ErrorKind::InvalidKeyFormat.into()), - }; - let digest = hmac::sign(&signing_key, signing_input.as_bytes()); - +fn sign_hmac(alg: hmac::Algorithm, key: &[u8], signing_input: &str) -> Result { + let digest = hmac::sign(&hmac::Key::new(alg, key), signing_input.as_bytes()); Ok(base64::encode_config::(&digest, base64::URL_SAFE_NO_PAD)) } /// The actual ECDSA signing + encoding fn sign_ecdsa( alg: &'static signature::EcdsaSigningAlgorithm, - key: Key, + key: &[u8], signing_input: &str, ) -> Result { - let signing_key = match key { - Key::Pkcs8(bytes) => signature::EcdsaKeyPair::from_pkcs8(alg, bytes)?, - _ => { - return Err(new_error(ErrorKind::InvalidKeyFormat)); - } - }; + let pem_key = PemEncodedKey::new(key)?; + let signing_key = signature::EcdsaKeyPair::from_pkcs8(alg, pem_key.as_ec_private_key()?)?; let rng = rand::SystemRandom::new(); let sig = signing_key.sign(&rng, signing_input.as_bytes())?; Ok(base64::encode_config(&sig, base64::URL_SAFE_NO_PAD)) @@ -38,20 +29,12 @@ fn sign_ecdsa( /// Taken from Ring doc https://briansmith.org/rustdoc/ring/signature/index.html fn sign_rsa( alg: &'static dyn signature::RsaEncoding, - key: Key, + key: &[u8], signing_input: &str, ) -> Result { - let key_pair = match key { - Key::Der(bytes) => { - signature::RsaKeyPair::from_der(bytes).map_err(|_| ErrorKind::InvalidRsaKey)? - } - Key::Pkcs8(bytes) => { - signature::RsaKeyPair::from_pkcs8(bytes).map_err(|_| ErrorKind::InvalidRsaKey)? - } - _ => { - return Err(ErrorKind::InvalidKeyFormat.into()); - } - }; + let pem_key = PemEncodedKey::new(key)?; + let key_pair = signature::RsaKeyPair::from_der(pem_key.as_rsa_key()?) + .map_err(|_| ErrorKind::InvalidRsaKey)?; let mut signature = vec![0; key_pair.public_modulus_len()]; let rng = rand::SystemRandom::new(); @@ -66,7 +49,7 @@ fn sign_rsa( /// the base64 url safe encoded of the result. /// /// Only use this function if you want to do something other than JWT. -pub fn sign(signing_input: &str, key: Key, algorithm: Algorithm) -> Result { +pub fn sign(signing_input: &str, key: &[u8], algorithm: Algorithm) -> Result { match algorithm { Algorithm::HS256 => sign_hmac(hmac::HMAC_SHA256, key, signing_input), Algorithm::HS384 => sign_hmac(hmac::HMAC_SHA384, key, signing_input), @@ -107,36 +90,20 @@ fn verify_ring_es( alg: &'static dyn signature::VerificationAlgorithm, signature: &str, signing_input: &str, - key: Key, + key: &[u8], ) -> Result { - let bytes = match key { - Key::Pkcs8(bytes) => bytes, - _ => { - return Err(ErrorKind::InvalidKeyFormat.into()); - } - }; - verify_ring(alg, signature, signing_input, bytes) + let pem_key = PemEncodedKey::new(key)?; + verify_ring(alg, signature, signing_input, pem_key.as_ec_public_key()?) } fn verify_ring_rsa( alg: &'static signature::RsaParameters, signature: &str, signing_input: &str, - key: Key, + key: &[u8], ) -> Result { - match key { - Key::Der(bytes) | Key::Pkcs8(bytes) => verify_ring(alg, signature, signing_input, bytes), - Key::ModulusExponent(n, e) => { - let public_key = signature::RsaPublicKeyComponents { n, e }; - - let signature_bytes = base64::decode_config(signature, base64::URL_SAFE_NO_PAD)?; - - let res = public_key.verify(alg, signing_input.as_bytes(), &signature_bytes); - - Ok(res.is_ok()) - } - _ => Err(ErrorKind::InvalidKeyFormat.into()), - } + let pem_key = PemEncodedKey::new(key)?; + verify_ring(alg, signature, signing_input, pem_key.as_rsa_key()?) } /// Compares the signature given with a re-computed signature for HMAC or using the public key @@ -150,7 +117,7 @@ fn verify_ring_rsa( pub fn verify( signature: &str, signing_input: &str, - key: Key, + key: &[u8], algorithm: Algorithm, ) -> Result { match algorithm { diff --git a/src/errors.rs b/src/errors.rs index 0c8b148..3973139 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -92,11 +92,12 @@ impl StdError for Error { ErrorKind::ImmatureSignature => "immature signature", ErrorKind::InvalidAlgorithm => "algorithms don't match", ErrorKind::InvalidAlgorithmName => "not a known algorithm", + ErrorKind::InvalidKeyFormat => "invalid key format", + ErrorKind::__Nonexhaustive => "unknown error", ErrorKind::Base64(ref err) => err.description(), ErrorKind::Json(ref err) => err.description(), ErrorKind::Utf8(ref err) => err.description(), ErrorKind::Crypto(ref err) => err.description(), - _ => unreachable!(), } } @@ -113,11 +114,12 @@ impl StdError for Error { ErrorKind::ImmatureSignature => None, ErrorKind::InvalidAlgorithm => None, ErrorKind::InvalidAlgorithmName => None, + ErrorKind::InvalidKeyFormat => None, + ErrorKind::__Nonexhaustive => None, ErrorKind::Base64(ref err) => Some(err), ErrorKind::Json(ref err) => Some(err), ErrorKind::Utf8(ref err) => Some(err), ErrorKind::Crypto(ref err) => Some(err), - _ => unreachable!(), } } } @@ -135,11 +137,13 @@ impl fmt::Display for Error { | ErrorKind::InvalidSubject | ErrorKind::ImmatureSignature | ErrorKind::InvalidAlgorithm + | ErrorKind::InvalidKeyFormat | ErrorKind::InvalidAlgorithmName => write!(f, "{}", self.description()), ErrorKind::Json(ref err) => write!(f, "JSON error: {}", err), ErrorKind::Utf8(ref err) => write!(f, "UTF-8 error: {}", err), ErrorKind::Crypto(ref err) => write!(f, "Crypto error: {}", err), - _ => unreachable!(), + ErrorKind::Base64(ref err) => write!(f, "Base64 error: {}", err), + ErrorKind::__Nonexhaustive => write!(f, "Unknown error"), } } } diff --git a/src/keys.rs b/src/keys.rs deleted file mode 100644 index 0d2e6c4..0000000 --- a/src/keys.rs +++ /dev/null @@ -1,16 +0,0 @@ -/// The supported RSA key formats, see the documentation for ring::signature::RsaKeyPair -/// for more information -#[derive(Debug, PartialEq)] -pub enum Key<'a> { - /// An unencrypted PKCS#8-encoded key. Can be used with both ECDSA and RSA - /// algorithms when signing. See ring for information. - Pkcs8(&'a [u8]), - /// A binary DER-encoded ASN.1 key. Can only be used with RSA algorithms - /// when signing. See ring for more information - Der(&'a [u8]), - /// This is not a key format, but provided for convenience since HMAC is - /// a supported signing algorithm. - Hmac(&'a [u8]), - /// A Modulus/exponent for a RSA public key - ModulusExponent(&'a [u8], &'a [u8]), -} diff --git a/src/lib.rs b/src/lib.rs index 5a81b2f..c11b6a6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,6 @@ mod crypto; /// All the errors pub mod errors; mod header; -mod keys; mod pem_decoder; mod pem_encoder; mod serialization; @@ -17,8 +16,6 @@ mod validation; pub use algorithms::Algorithm; pub use crypto::{sign, verify}; pub use header::Header; -pub use keys::Key; -pub use pem_decoder::PemEncodedKey; pub use serialization::TokenData; pub use validation::Validation; @@ -49,9 +46,9 @@ use crate::validation::validate; /// /// // my_claims is a struct that implements Serialize /// // This will create a JWT using HS256 as algorithm -/// let token = encode(&Header::default(), &my_claims, Key::Hmac("secret".as_ref())).unwrap(); +/// let token = encode(&Header::default(), &my_claims, "secret".as_ref()).unwrap(); /// ``` -pub fn encode(header: &Header, claims: &T, key: Key) -> Result { +pub fn encode(header: &Header, claims: &T, key: &[u8]) -> Result { let encoded_header = encode_part(&header)?; let encoded_claims = encode_part(&claims)?; let signing_input = [encoded_header.as_ref(), encoded_claims.as_ref()].join("."); @@ -93,7 +90,7 @@ macro_rules! expect_two { /// ``` pub fn decode( token: &str, - key: Key, + key: &[u8], validation: &Validation, ) -> Result> { let (signature, signing_input) = expect_two!(token.rsplitn(2, '.')); @@ -160,33 +157,6 @@ pub fn decode_header(token: &str) -> Result
{ Header::from_encoded(header) } -/// Decode a PEM string to obtain its key -/// -/// This must be a tagged PEM encoded key, tags start with `-----BEGIN ..-----` -/// and end with a `-----END ..-----` -/// -/// ```rust -/// use jsonwebtoken::{decode_pem, sign, verify, Algorithm}; -/// -/// let pem_content = "-----BEGIN PRIVATE KEY----- -/// MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgWTFfCGljY6aw3Hrt -/// kHmPRiazukxPLb6ilpRAewjW8nihRANCAATDskChT+Altkm9X7MI69T3IUmrQU0L -/// 950IxEzvw/x5BMEINRMrXLBJhqzO9Bm+d6JbqA21YQmd1Kt4RzLJR1W+ -/// -----END PRIVATE KEY-----"; -/// -/// // First use decode_pem from jsonwebtoken -/// let privkey_pem = decode_pem(pem_content).unwrap(); -/// // If it decodes Ok, then you can start using it with a given algorithm -/// let privkey = privkey_pem.as_key().unwrap(); -/// -/// // When using the as_key function, you do not need to wrap in Key::Der or Key::Pkcs8 -/// // The same code can be used for public keys too. -/// let encrypted = sign("hello world", privkey, Algorithm::ES256).unwrap(); -/// ``` -pub fn decode_pem(content: &str) -> Result { - PemEncodedKey::read(content) -} - /// TODO pub fn encode_rsa_public_pkcs1_pem(modulus: &[u8], exponent: &[u8]) -> Result { pem_encoder::encode_rsa_public_pkcs1_pem(modulus, exponent) diff --git a/src/pem_decoder.rs b/src/pem_decoder.rs index c42b042..2c29f7d 100644 --- a/src/pem_decoder.rs +++ b/src/pem_decoder.rs @@ -1,5 +1,4 @@ use crate::errors::{ErrorKind, Result}; -use crate::keys::Key; extern crate pem; extern crate simple_asn1; @@ -9,10 +8,10 @@ use simple_asn1::{BigUint, OID}; /// Supported PEM files for EC and RSA Public and Private Keys #[derive(Debug, PartialEq)] enum PemType { - EcPublicKey, - EcPrivateKey, - RsaPublicKey, - RsaPrivateKey, + EcPublic, + EcPrivate, + RsaPublic, + RsaPrivate, } #[derive(Debug, PartialEq)] @@ -42,7 +41,7 @@ enum Classification { /// PKCS#1: https://tools.ietf.org/html/rfc8017 /// PKCS#8: https://tools.ietf.org/html/rfc5958 #[derive(Debug)] -pub struct PemEncodedKey { +pub(crate) struct PemEncodedKey { content: Vec, asn1: Vec, pem_type: PemType, @@ -51,7 +50,7 @@ pub struct PemEncodedKey { impl PemEncodedKey { /// Read the PEM file for later key use - pub fn read(input: &str) -> Result { + pub fn new(input: &[u8]) -> Result { match pem::parse(input) { Ok(content) => { let pem_contents = content.contents; @@ -65,13 +64,13 @@ impl PemEncodedKey { "RSA PRIVATE KEY" => Ok(PemEncodedKey { content: pem_contents, asn1: asn1_content, - pem_type: PemType::RsaPrivateKey, + pem_type: PemType::RsaPrivate, standard: Standard::Pkcs1, }), "RSA PUBLIC KEY" => Ok(PemEncodedKey { content: pem_contents, asn1: asn1_content, - pem_type: PemType::RsaPublicKey, + pem_type: PemType::RsaPublic, standard: Standard::Pkcs1, }), @@ -86,16 +85,16 @@ impl PemEncodedKey { let pem_type = match c { Classification::Ec => { if is_private { - PemType::EcPrivateKey + PemType::EcPrivate } else { - PemType::EcPublicKey + PemType::EcPublic } } Classification::Rsa => { if is_private { - PemType::RsaPrivateKey + PemType::RsaPrivate } else { - PemType::RsaPublicKey + PemType::RsaPublic } } }; @@ -117,18 +116,36 @@ impl PemEncodedKey { } } - /// This will do the initial parsing of a PEM file. - /// Supported tagged pems include "RSA PRIVATE KEY", "RSA PUBLIC KEY", - /// "PRIVATE KEY", "PUBLIC KEY" - /// PEMs with multiple tagged portions are not supported - pub fn as_key(&self) -> Result> { + /// Can only be PKCS8 + pub fn as_ec_private_key(&self) -> Result<&[u8]> { match self.standard { - Standard::Pkcs1 => Ok(Key::Der(self.content.as_slice())), + Standard::Pkcs1 => Err(ErrorKind::InvalidKeyFormat.into()), Standard::Pkcs8 => match self.pem_type { - PemType::RsaPrivateKey => Ok(Key::Der(extract_first_bitstring(&self.asn1)?)), - PemType::RsaPublicKey => Ok(Key::Der(extract_first_bitstring(&self.asn1)?)), - PemType::EcPrivateKey => Ok(Key::Pkcs8(self.content.as_slice())), - PemType::EcPublicKey => Ok(Key::Pkcs8(extract_first_bitstring(&self.asn1)?)), + PemType::EcPrivate => Ok(self.content.as_slice()), + _ => Err(ErrorKind::InvalidKeyFormat.into()), + }, + } + } + + /// Can only be PKCS8 + pub fn as_ec_public_key(&self) -> Result<&[u8]> { + match self.standard { + Standard::Pkcs1 => Err(ErrorKind::InvalidKeyFormat.into()), + Standard::Pkcs8 => match self.pem_type { + PemType::EcPublic => extract_first_bitstring(&self.asn1), + _ => Err(ErrorKind::InvalidKeyFormat.into()), + }, + } + } + + /// Can be PKCS1 or PKCS8 + pub fn as_rsa_key(&self) -> Result<&[u8]> { + match self.standard { + Standard::Pkcs1 => Ok(self.content.as_slice()), + Standard::Pkcs8 => match self.pem_type { + PemType::RsaPrivate => extract_first_bitstring(&self.asn1), + PemType::RsaPublic => extract_first_bitstring(&self.asn1), + _ => Err(ErrorKind::InvalidKeyFormat.into()), }, } } diff --git a/src/pem_encoder.rs b/src/pem_encoder.rs index d719fc1..ef7ba9d 100644 --- a/src/pem_encoder.rs +++ b/src/pem_encoder.rs @@ -99,102 +99,100 @@ fn encode_ec_public_asn1(x: &[u8]) -> ASN1Block { #[cfg(test)] mod tests { use super::*; - use crate::decode_pem; - use crate::keys::Key; use ring::{signature, signature::KeyPair}; - #[test] - fn public_key_encoding_pkcs1() { - let privkey_pem = - decode_pem(include_str!("../tests/rsa/private_rsa_key_pkcs8.pem")).unwrap(); - let privkey = privkey_pem.as_key().unwrap(); - let ring_key = signature::RsaKeyPair::from_der(match privkey { - Key::Der(bytes) => bytes, - _ => panic!("Unexpected"), - }) - .unwrap(); - let mut modulus = vec![0]; - modulus.extend(ring_key.public_key().modulus().big_endian_without_leading_zero()); - let exponent = ring_key.public_key().exponent(); - - let public_key_pkcs1_pem = encode_rsa_public_pkcs1_pem( - modulus.as_ref(), - exponent.big_endian_without_leading_zero(), - ) - .unwrap(); - assert_eq!( - include_str!("../tests/rsa/public_rsa_key_pkcs1.pem").trim(), - public_key_pkcs1_pem.replace('\r', "").trim() - ); - - let public_key_pkcs1_der = encode_rsa_public_pkcs1_der( - modulus.as_ref(), - exponent.big_endian_without_leading_zero(), - ) - .unwrap(); - assert_eq!( - include_bytes!("../tests/rsa/public_rsa_key.der").to_vec(), - public_key_pkcs1_der - ); - } - - #[test] - fn public_key_encoding_pkcs8() { - let privkey_pem = - decode_pem(include_str!("../tests/rsa/private_rsa_key_pkcs8.pem")).unwrap(); - let privkey = privkey_pem.as_key().unwrap(); - let ring_key = signature::RsaKeyPair::from_der(match privkey { - Key::Der(bytes) => bytes, - _ => panic!("Unexpected"), - }) - .unwrap(); - let mut modulus = vec![0]; - modulus.extend(ring_key.public_key().modulus().big_endian_without_leading_zero()); - let exponent = ring_key.public_key().exponent(); - - let public_key_pkcs8 = encode_rsa_public_pkcs8_pem( - modulus.as_ref(), - exponent.big_endian_without_leading_zero(), - ) - .unwrap(); - assert_eq!( - include_str!("../tests/rsa/public_rsa_key_pkcs8.pem").trim(), - public_key_pkcs8.replace('\r', "").trim() - ); - } - - #[test] - fn public_key_encoding() { - let privkey_pem = decode_pem(include_str!("../tests/ec/private_ecdsa_key.pem")).unwrap(); - let privkey = privkey_pem.as_key().unwrap(); - let alg = &signature::ECDSA_P256_SHA256_FIXED_SIGNING; - let ring_key = signature::EcdsaKeyPair::from_pkcs8( - alg, - match privkey { - Key::Pkcs8(bytes) => bytes, - _ => panic!("Unexpected"), - }, - ) - .unwrap(); - - let public_key_pem = encode_ec_public_pem(ring_key.public_key().as_ref()).unwrap(); - assert_eq!( - include_str!("../tests/ec/public_ecdsa_key.pem").trim(), - public_key_pem.replace('\r', "").trim() - ); - - let public_key_der = encode_ec_public_der(ring_key.public_key().as_ref()).unwrap(); - // The stored ".pk8" key is just the x coordinate of the EC key - // It's not truly a pkcs8 formatted DER - // To get around that, a prepended binary specifies the EC key, EC name, - // and X coordinate length. The length is unlikely to change.. in the - // event that it does, look at the pem file (convert base64 to hex) and find - // where 0x03, 0x42 don't match up. 0x42 is the length. - let mut stored_pk8_der = vec![ - 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, - 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, - ]; - stored_pk8_der.extend(include_bytes!("../tests/ec/public_ecdsa_key.pk8").to_vec()); - assert_eq!(stored_pk8_der, public_key_der); - } + // #[test] + // fn public_key_encoding_pkcs1() { + // let privkey_pem = + // decode_pem(include_str!("../tests/rsa/private_rsa_key_pkcs8.pem")).unwrap(); + // let privkey = privkey_pem.as_key().unwrap(); + // let ring_key = signature::RsaKeyPair::from_der(match privkey { + // Key::Der(bytes) => bytes, + // _ => panic!("Unexpected"), + // }) + // .unwrap(); + // let mut modulus = vec![0]; + // modulus.extend(ring_key.public_key().modulus().big_endian_without_leading_zero()); + // let exponent = ring_key.public_key().exponent(); + // + // let public_key_pkcs1_pem = encode_rsa_public_pkcs1_pem( + // modulus.as_ref(), + // exponent.big_endian_without_leading_zero(), + // ) + // .unwrap(); + // assert_eq!( + // include_str!("../tests/rsa/public_rsa_key_pkcs1.pem").trim(), + // public_key_pkcs1_pem.replace('\r', "").trim() + // ); + // + // let public_key_pkcs1_der = encode_rsa_public_pkcs1_der( + // modulus.as_ref(), + // exponent.big_endian_without_leading_zero(), + // ) + // .unwrap(); + // assert_eq!( + // include_bytes!("../tests/rsa/public_rsa_key.der").to_vec(), + // public_key_pkcs1_der + // ); + // } + // + // #[test] + // fn public_key_encoding_pkcs8() { + // let privkey_pem = + // decode_pem(include_str!("../tests/rsa/private_rsa_key_pkcs8.pem")).unwrap(); + // let privkey = privkey_pem.as_key().unwrap(); + // let ring_key = signature::RsaKeyPair::from_der(match privkey { + // Key::Der(bytes) => bytes, + // _ => panic!("Unexpected"), + // }) + // .unwrap(); + // let mut modulus = vec![0]; + // modulus.extend(ring_key.public_key().modulus().big_endian_without_leading_zero()); + // let exponent = ring_key.public_key().exponent(); + // + // let public_key_pkcs8 = encode_rsa_public_pkcs8_pem( + // modulus.as_ref(), + // exponent.big_endian_without_leading_zero(), + // ) + // .unwrap(); + // assert_eq!( + // include_str!("../tests/rsa/public_rsa_key_pkcs8.pem").trim(), + // public_key_pkcs8.replace('\r', "").trim() + // ); + // } + // + // #[test] + // fn public_key_encoding() { + // let privkey_pem = decode_pem(include_str!("../tests/ec/private_ecdsa_key.pem")).unwrap(); + // let privkey = privkey_pem.as_key().unwrap(); + // let alg = &signature::ECDSA_P256_SHA256_FIXED_SIGNING; + // let ring_key = signature::EcdsaKeyPair::from_pkcs8( + // alg, + // match privkey { + // Key::Pkcs8(bytes) => bytes, + // _ => panic!("Unexpected"), + // }, + // ) + // .unwrap(); + // + // let public_key_pem = encode_ec_public_pem(ring_key.public_key().as_ref()).unwrap(); + // assert_eq!( + // include_str!("../tests/ec/public_ecdsa_key.pem").trim(), + // public_key_pem.replace('\r', "").trim() + // ); + // + // let public_key_der = encode_ec_public_der(ring_key.public_key().as_ref()).unwrap(); + // // The stored ".pk8" key is just the x coordinate of the EC key + // // It's not truly a pkcs8 formatted DER + // // To get around that, a prepended binary specifies the EC key, EC name, + // // and X coordinate length. The length is unlikely to change.. in the + // // event that it does, look at the pem file (convert base64 to hex) and find + // // where 0x03, 0x42 don't match up. 0x42 is the length. + // let mut stored_pk8_der = vec![ + // 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, + // 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, + // ]; + // stored_pk8_der.extend(include_bytes!("../tests/ec/public_ecdsa_key.pk8").to_vec()); + // assert_eq!(stored_pk8_der, public_key_der); + // } } diff --git a/src/serialization.rs b/src/serialization.rs index d1aafeb..6c6df1f 100644 --- a/src/serialization.rs +++ b/src/serialization.rs @@ -22,7 +22,8 @@ pub fn encode_part(input: &T) -> Result { Ok(base64::encode_config(json.as_bytes(), base64::URL_SAFE_NO_PAD)) } -/// Decodes from base64 and deserializes from JSON to a struct AND a hashmap +/// Decodes from base64 and deserializes from JSON to a struct AND a hashmap of Value so we can +/// run validation on it pub fn from_jwt_part_claims, T: DeserializeOwned>( encoded: B, ) -> Result<(T, Map)> { diff --git a/tests/ec/mod.rs b/tests/ec/mod.rs index cc3321e..b02721c 100644 --- a/tests/ec/mod.rs +++ b/tests/ec/mod.rs @@ -1,5 +1,5 @@ use chrono::Utc; -use jsonwebtoken::{decode, decode_pem, encode, sign, verify, Algorithm, Header, Key, Validation}; +use jsonwebtoken::{decode, encode, sign, verify, Algorithm, Header, Validation}; use serde::{Deserialize, Serialize}; #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] @@ -9,22 +9,21 @@ pub struct Claims { exp: i64, } -#[test] -fn round_trip_sign_verification_pk8() { - let privkey = include_bytes!("private_ecdsa_key.pk8"); - let encrypted = sign("hello world", Key::Pkcs8(&privkey[..]), Algorithm::ES256).unwrap(); - let pubkey = include_bytes!("public_ecdsa_key.pk8"); - let is_valid = verify(&encrypted, "hello world", Key::Pkcs8(pubkey), Algorithm::ES256).unwrap(); - assert!(is_valid); -} +// TODO: remove completely? +//#[test] +//fn round_trip_sign_verification_pk8() { +// let privkey = include_bytes!("private_ecdsa_key.pk8"); +// let encrypted = sign("hello world", privkey, Algorithm::ES256).unwrap(); +// let pubkey = include_bytes!("public_ecdsa_key.pk8"); +// let is_valid = verify(&encrypted, "hello world", pubkey, Algorithm::ES256).unwrap(); +// assert!(is_valid); +//} #[test] fn round_trip_sign_verification_pem() { - let privkey_pem = decode_pem(include_str!("private_ecdsa_key.pem")).unwrap(); - let privkey = privkey_pem.as_key().unwrap(); + let privkey = include_bytes!("private_ecdsa_key.pem"); let encrypted = sign("hello world", privkey, Algorithm::ES256).unwrap(); - let pubkey_pem = decode_pem(include_str!("public_ecdsa_key.pem")).unwrap(); - let pubkey = pubkey_pem.as_key().unwrap(); + let pubkey = include_bytes!("public_ecdsa_key.pem"); let is_valid = verify(&encrypted, "hello world", pubkey, Algorithm::ES256).unwrap(); assert!(is_valid); } @@ -36,12 +35,10 @@ fn round_trip_claim() { company: "ACME".to_string(), exp: Utc::now().timestamp() + 10000, }; - let privkey = include_bytes!("private_ecdsa_key.pk8"); - let token = - encode(&Header::new(Algorithm::ES256), &my_claims, Key::Pkcs8(&privkey[..])).unwrap(); - let pubkey = include_bytes!("public_ecdsa_key.pk8"); - let token_data = - decode::(&token, Key::Pkcs8(pubkey), &Validation::new(Algorithm::ES256)).unwrap(); + let privkey = include_bytes!("private_ecdsa_key.pem"); + let token = encode(&Header::new(Algorithm::ES256), &my_claims, privkey).unwrap(); + let pubkey = include_bytes!("public_ecdsa_key.pem"); + let token_data = decode::(&token, pubkey, &Validation::new(Algorithm::ES256)).unwrap(); assert_eq!(my_claims, token_data.claims); assert!(token_data.header.kid.is_none()); } diff --git a/tests/hmac.rs b/tests/hmac.rs index 89cfaf7..0a245fc 100644 --- a/tests/hmac.rs +++ b/tests/hmac.rs @@ -1,6 +1,6 @@ use chrono::Utc; use jsonwebtoken::{ - dangerous_unsafe_decode, decode, decode_header, encode, sign, verify, Algorithm, Header, Key, + dangerous_unsafe_decode, decode, decode_header, encode, sign, verify, Algorithm, Header, Validation, }; use serde::{Deserialize, Serialize}; @@ -14,7 +14,7 @@ pub struct Claims { #[test] fn sign_hs256() { - let result = sign("hello world", Key::Hmac(b"secret"), Algorithm::HS256).unwrap(); + let result = sign("hello world", b"secret", Algorithm::HS256).unwrap(); let expected = "c0zGLzKEFWj0VxWuufTXiRMk5tlI5MbGDAYhzaxIYjo"; assert_eq!(result, expected); } @@ -22,7 +22,7 @@ fn sign_hs256() { #[test] fn verify_hs256() { let sig = "c0zGLzKEFWj0VxWuufTXiRMk5tlI5MbGDAYhzaxIYjo"; - let valid = verify(sig, "hello world", Key::Hmac(b"secret"), Algorithm::HS256).unwrap(); + let valid = verify(sig, "hello world", b"secret", Algorithm::HS256).unwrap(); assert!(valid); } @@ -35,9 +35,8 @@ fn encode_with_custom_header() { }; let mut header = Header::default(); header.kid = Some("kid".to_string()); - let token = encode(&header, &my_claims, Key::Hmac(b"secret")).unwrap(); - let token_data = - decode::(&token, Key::Hmac(b"secret"), &Validation::default()).unwrap(); + let token = encode(&header, &my_claims, b"secret").unwrap(); + let token_data = decode::(&token, b"secret", &Validation::default()).unwrap(); assert_eq!(my_claims, token_data.claims); assert_eq!("kid", token_data.header.kid.unwrap()); } @@ -49,9 +48,8 @@ fn round_trip_claim() { company: "ACME".to_string(), exp: Utc::now().timestamp() + 10000, }; - let token = encode(&Header::default(), &my_claims, Key::Hmac(b"secret")).unwrap(); - let token_data = - decode::(&token, Key::Hmac(b"secret"), &Validation::default()).unwrap(); + let token = encode(&Header::default(), &my_claims, b"secret").unwrap(); + let token_data = decode::(&token, b"secret", &Validation::default()).unwrap(); assert_eq!(my_claims, token_data.claims); assert!(token_data.header.kid.is_none()); } @@ -59,7 +57,7 @@ fn round_trip_claim() { #[test] fn decode_token() { let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUiLCJleHAiOjI1MzI1MjQ4OTF9.9r56oF7ZliOBlOAyiOFperTGxBtPykRQiWNFxhDCW98"; - let claims = decode::(token, Key::Hmac(b"secret"), &Validation::default()); + let claims = decode::(token, b"secret", &Validation::default()); println!("{:?}", claims); claims.unwrap(); } @@ -68,7 +66,7 @@ fn decode_token() { #[should_panic(expected = "InvalidToken")] fn decode_token_missing_parts() { let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"; - let claims = decode::(token, Key::Hmac(b"secret"), &Validation::default()); + let claims = decode::(token, b"secret", &Validation::default()); claims.unwrap(); } @@ -77,7 +75,7 @@ fn decode_token_missing_parts() { fn decode_token_invalid_signature() { let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.wrong"; - let claims = decode::(token, Key::Hmac(b"secret"), &Validation::default()); + let claims = decode::(token, b"secret", &Validation::default()); claims.unwrap(); } @@ -85,14 +83,14 @@ fn decode_token_invalid_signature() { #[should_panic(expected = "InvalidAlgorithm")] fn decode_token_wrong_algorithm() { let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUifQ.I1BvFoHe94AFf09O6tDbcSB8-jp8w6xZqmyHIwPeSdY"; - let claims = decode::(token, Key::Hmac(b"secret"), &Validation::new(Algorithm::RS512)); + let claims = decode::(token, b"secret", &Validation::new(Algorithm::RS512)); claims.unwrap(); } #[test] fn decode_token_with_bytes_secret() { let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUiLCJleHAiOjI1MzI1MjQ4OTF9.Hm0yvKH25TavFPz7J_coST9lZFYH1hQo0tvhvImmaks"; - let claims = decode::(token, Key::Hmac(b"\x01\x02\x03"), &Validation::default()); + let claims = decode::(token, b"\x01\x02\x03", &Validation::default()); assert!(claims.is_ok()); } diff --git a/tests/rsa/mod.rs b/tests/rsa/mod.rs index 8fde515..83c4fde 100644 --- a/tests/rsa/mod.rs +++ b/tests/rsa/mod.rs @@ -1,5 +1,5 @@ use chrono::Utc; -use jsonwebtoken::{decode, decode_pem, encode, sign, verify, Algorithm, Header, Key, Validation}; +use jsonwebtoken::{decode, encode, sign, verify, Algorithm, Header, Validation}; use serde::{Deserialize, Serialize}; const RSA_ALGORITHMS: &[Algorithm] = &[ @@ -18,42 +18,26 @@ pub struct Claims { exp: i64, } -#[test] -fn round_trip_sign_verification_der() { - let privkey = include_bytes!("private_rsa_key.der"); - for &alg in RSA_ALGORITHMS { - let encrypted = sign("hello world", Key::Der(&privkey[..]), alg).unwrap(); - let is_valid = - verify(&encrypted, "hello world", Key::Der(include_bytes!("public_rsa_key.der")), alg) - .unwrap(); - assert!(is_valid); - } -} - #[test] fn round_trip_sign_verification_pem_pkcs1() { - let privkey_pem = decode_pem(include_str!("private_rsa_key_pkcs1.pem")).unwrap(); - let pubkey_pem = decode_pem(include_str!("public_rsa_key_pkcs1.pem")).unwrap(); + let privkey_pem = include_bytes!("private_rsa_key_pkcs1.pem"); + let pubkey_pem = include_bytes!("public_rsa_key_pkcs1.pem"); for &alg in RSA_ALGORITHMS { - let privkey_key = privkey_pem.as_key().unwrap(); - let pubkey_key = pubkey_pem.as_key().unwrap(); - let encrypted = sign("hello world", privkey_key, alg).unwrap(); - let is_valid = verify(&encrypted, "hello world", pubkey_key, alg).unwrap(); + let encrypted = sign("hello world", privkey_pem, alg).unwrap(); + let is_valid = verify(&encrypted, "hello world", pubkey_pem, alg).unwrap(); assert!(is_valid); } } #[test] fn round_trip_sign_verification_pem_pkcs8() { - let privkey_pem = decode_pem(include_str!("private_rsa_key_pkcs8.pem")).unwrap(); - let pubkey_pem = decode_pem(include_str!("public_rsa_key_pkcs8.pem")).unwrap(); + let privkey_pem = include_bytes!("private_rsa_key_pkcs8.pem"); + let pubkey_pem = include_bytes!("public_rsa_key_pkcs8.pem"); for &alg in RSA_ALGORITHMS { - let privkey_key = privkey_pem.as_key().unwrap(); - let pubkey_key = pubkey_pem.as_key().unwrap(); - let encrypted = sign("hello world", privkey_key, alg).unwrap(); - let is_valid = verify(&encrypted, "hello world", pubkey_key, alg).unwrap(); + let encrypted = sign("hello world", privkey_pem, alg).unwrap(); + let is_valid = verify(&encrypted, "hello world", pubkey_pem, alg).unwrap(); assert!(is_valid); } } @@ -65,13 +49,13 @@ fn round_trip_claim() { company: "ACME".to_string(), exp: Utc::now().timestamp() + 10000, }; - let privkey = include_bytes!("private_rsa_key.der"); + let privkey = include_bytes!("private_rsa_key_pkcs1.pem"); for &alg in RSA_ALGORITHMS { - let token = encode(&Header::new(alg), &my_claims, Key::Der(&privkey[..])).unwrap(); + let token = encode(&Header::new(alg), &my_claims, privkey).unwrap(); let token_data = decode::( &token, - Key::Der(include_bytes!("public_rsa_key.der")), + include_bytes!("public_rsa_key_pkcs1.pem"), &Validation::new(alg), ) .unwrap(); @@ -80,52 +64,45 @@ fn round_trip_claim() { } } -#[test] -#[should_panic(expected = "InvalidRsaKey")] -fn fails_with_different_key_format() { - let privkey = include_bytes!("private_rsa_key.der"); - sign("hello world", Key::Pkcs8(&privkey[..]), Algorithm::RS256).unwrap(); -} - -#[test] -fn rsa_modulus_exponent() { - let modulus: Vec = vec![ - 0xc9, 0x11, 0x3a, 0xac, 0x7b, 0x8d, 0x47, 0x44, 0x1b, 0x1c, 0xed, 0xc7, 0xdc, 0xab, 0x76, - 0xa4, 0xe2, 0x86, 0x56, 0x14, 0x2a, 0x19, 0x95, 0xc8, 0x9c, 0xe7, 0x6e, 0x40, 0xdc, 0x57, - 0xce, 0xe2, 0xa5, 0xbd, 0x04, 0xcb, 0x51, 0x3b, 0xf8, 0x97, 0x8b, 0x20, 0x82, 0x1e, 0x7f, - 0x09, 0x86, 0x22, 0xfd, 0xcb, 0xc8, 0xf9, 0x25, 0xd5, 0x4f, 0xd9, 0x0f, 0x59, 0x22, 0x97, - 0xc4, 0x95, 0xc1, 0x5d, 0xdf, 0xf8, 0x2e, 0x4b, 0xdc, 0x3e, 0xe5, 0x1a, 0x90, 0x1a, 0x00, - 0x91, 0xf8, 0x7e, 0x7a, 0x21, 0x55, 0x32, 0x1d, 0x95, 0xad, 0x4c, 0x96, 0xca, 0x3d, 0xcc, - 0x16, 0x5d, 0x07, 0x4d, 0x51, 0x7d, 0x2b, 0x04, 0x57, 0x2c, 0x07, 0x30, 0x91, 0x11, 0x22, - 0x4b, 0x79, 0xe9, 0x4e, 0x11, 0xd1, 0xc8, 0x8c, 0x6e, 0xcb, 0x46, 0x4c, 0x79, 0x97, 0xf1, - 0x54, 0xbe, 0x5a, 0xac, 0xc8, 0x70, 0xd5, 0x24, 0x44, 0x2c, 0x1f, 0x07, 0xa0, 0x67, 0xc6, - 0xfc, 0x0b, 0x47, 0xf3, 0xd0, 0x48, 0x13, 0xd8, 0xc3, 0x04, 0x76, 0x7d, 0x74, 0xb7, 0xa5, - 0x2b, 0xd6, 0xb5, 0xf3, 0x8c, 0xc0, 0x7f, 0xc2, 0xf0, 0xa0, 0xf2, 0xf1, 0xbc, 0x96, 0xf7, - 0x22, 0x5e, 0x67, 0x9d, 0xca, 0x8f, 0x71, 0x27, 0xca, 0x0c, 0x3a, 0x1d, 0x30, 0x50, 0x48, - 0x31, 0xce, 0x25, 0x43, 0x30, 0xca, 0x2f, 0x98, 0x2f, 0x9a, 0x25, 0xcb, 0x5c, 0x1d, 0x40, - 0x18, 0xb9, 0xbc, 0x28, 0x18, 0xdf, 0x13, 0xcb, 0x37, 0x2f, 0x9c, 0x6a, 0x8b, 0xec, 0x94, - 0xa1, 0xdf, 0xa3, 0xf0, 0xcb, 0x6f, 0x22, 0x3f, 0x35, 0xd9, 0xd9, 0x12, 0xe1, 0x03, 0x22, - 0x45, 0x53, 0x7f, 0x6f, 0x2d, 0xa1, 0xdd, 0x96, 0x3c, 0x2d, 0x85, 0x46, 0xae, 0xa6, 0x57, - 0x65, 0x37, 0x20, 0x9f, 0x6b, 0xa3, 0x9f, 0xcb, 0x8a, 0x8d, 0x72, 0xd9, 0x54, 0x3e, 0x53, - 0x75, - ]; - let exponent: Vec = vec![0x01, 0x00, 0x01]; - let privkey = include_bytes!("private_rsa_key.der"); - - let encrypted = sign("hello world", Key::Der(&privkey[..]), Algorithm::RS256).unwrap(); - let is_valid = verify( - &encrypted, - "hello world", - Key::ModulusExponent(&modulus, &exponent), - Algorithm::RS256, - ) - .unwrap(); - assert!(is_valid); -} +//#[test] +//fn rsa_modulus_exponent() { +// let modulus: Vec = vec![ +// 0xc9, 0x11, 0x3a, 0xac, 0x7b, 0x8d, 0x47, 0x44, 0x1b, 0x1c, 0xed, 0xc7, 0xdc, 0xab, 0x76, +// 0xa4, 0xe2, 0x86, 0x56, 0x14, 0x2a, 0x19, 0x95, 0xc8, 0x9c, 0xe7, 0x6e, 0x40, 0xdc, 0x57, +// 0xce, 0xe2, 0xa5, 0xbd, 0x04, 0xcb, 0x51, 0x3b, 0xf8, 0x97, 0x8b, 0x20, 0x82, 0x1e, 0x7f, +// 0x09, 0x86, 0x22, 0xfd, 0xcb, 0xc8, 0xf9, 0x25, 0xd5, 0x4f, 0xd9, 0x0f, 0x59, 0x22, 0x97, +// 0xc4, 0x95, 0xc1, 0x5d, 0xdf, 0xf8, 0x2e, 0x4b, 0xdc, 0x3e, 0xe5, 0x1a, 0x90, 0x1a, 0x00, +// 0x91, 0xf8, 0x7e, 0x7a, 0x21, 0x55, 0x32, 0x1d, 0x95, 0xad, 0x4c, 0x96, 0xca, 0x3d, 0xcc, +// 0x16, 0x5d, 0x07, 0x4d, 0x51, 0x7d, 0x2b, 0x04, 0x57, 0x2c, 0x07, 0x30, 0x91, 0x11, 0x22, +// 0x4b, 0x79, 0xe9, 0x4e, 0x11, 0xd1, 0xc8, 0x8c, 0x6e, 0xcb, 0x46, 0x4c, 0x79, 0x97, 0xf1, +// 0x54, 0xbe, 0x5a, 0xac, 0xc8, 0x70, 0xd5, 0x24, 0x44, 0x2c, 0x1f, 0x07, 0xa0, 0x67, 0xc6, +// 0xfc, 0x0b, 0x47, 0xf3, 0xd0, 0x48, 0x13, 0xd8, 0xc3, 0x04, 0x76, 0x7d, 0x74, 0xb7, 0xa5, +// 0x2b, 0xd6, 0xb5, 0xf3, 0x8c, 0xc0, 0x7f, 0xc2, 0xf0, 0xa0, 0xf2, 0xf1, 0xbc, 0x96, 0xf7, +// 0x22, 0x5e, 0x67, 0x9d, 0xca, 0x8f, 0x71, 0x27, 0xca, 0x0c, 0x3a, 0x1d, 0x30, 0x50, 0x48, +// 0x31, 0xce, 0x25, 0x43, 0x30, 0xca, 0x2f, 0x98, 0x2f, 0x9a, 0x25, 0xcb, 0x5c, 0x1d, 0x40, +// 0x18, 0xb9, 0xbc, 0x28, 0x18, 0xdf, 0x13, 0xcb, 0x37, 0x2f, 0x9c, 0x6a, 0x8b, 0xec, 0x94, +// 0xa1, 0xdf, 0xa3, 0xf0, 0xcb, 0x6f, 0x22, 0x3f, 0x35, 0xd9, 0xd9, 0x12, 0xe1, 0x03, 0x22, +// 0x45, 0x53, 0x7f, 0x6f, 0x2d, 0xa1, 0xdd, 0x96, 0x3c, 0x2d, 0x85, 0x46, 0xae, 0xa6, 0x57, +// 0x65, 0x37, 0x20, 0x9f, 0x6b, 0xa3, 0x9f, 0xcb, 0x8a, 0x8d, 0x72, 0xd9, 0x54, 0x3e, 0x53, +// 0x75, +// ]; +// let exponent: Vec = vec![0x01, 0x00, 0x01]; +// let privkey = include_bytes!("private_rsa_key.der"); +// +// let encrypted = sign("hello world", Key::Der(&privkey[..]), Algorithm::RS256).unwrap(); +// let is_valid = verify( +// &encrypted, +// "hello world", +// Key::ModulusExponent(&modulus, &exponent), +// Algorithm::RS256, +// ) +// .unwrap(); +// assert!(is_valid); +//} #[test] #[should_panic(expected = "InvalidKeyFormat")] fn fails_with_non_pkcs8_key_format() { - let privkey = include_bytes!("private_rsa_key.der"); - let _encrypted = sign("hello world", Key::Der(&privkey[..]), Algorithm::ES256).unwrap(); + let _encrypted = + sign("hello world", include_bytes!("private_rsa_key_pkcs1.pem"), Algorithm::ES256).unwrap(); }