diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 406f3459..5b038183 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -80,7 +80,7 @@ jobs: run: cargo install wasm-pack - name: Run tests default features - run: wasm-pack test --node --features rust_crypto,getrandom/js + run: wasm-pack test --node --features rust_crypto,getrandom/wasm_js - name: Run tests no features - run: wasm-pack test --node --no-default-features --features rust_crypto,getrandom/js + run: wasm-pack test --node --no-default-features --features rust_crypto,getrandom/wasm_js diff --git a/Cargo.toml b/Cargo.toml index db809c05..7d3ee924 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ features = ["rust_crypto"] base64 = "0.22" serde = { version = "1.0.228", features = ["derive"] } serde_json = "1.0" -signature = { version = "2.2.0", features = ["std"] } +signature = { version = "3.0.0", features = ["alloc"] } # For PEM decoding pem = { version = "3", optional = true } @@ -36,26 +36,28 @@ simple_asn1 = { version = "0.6", optional = true } aws-lc-rs = { version = "1.15.0", optional = true } # "rust_crypto" feature -ed25519-dalek = { version = "2.1.1", optional = true, features = ["pkcs8"] } -hmac = { version = "0.12.1", optional = true, features = ["reset"] } -p256 = { version = "0.13.2", optional = true, features = ["ecdsa"] } -p384 = { version = "0.13.0", optional = true, features = ["ecdsa"] } -rand = { version = "0.8.5", optional = true, features = [ +ed25519-dalek = { version = "3.0.0", optional = true, features = ["pkcs8"] } +hmac = { version = "0.13.0", optional = true } +p256 = { version = "0.14", optional = true, features = ["ecdsa"] } +p384 = { version = "0.14", optional = true, features = ["ecdsa"] } +p521 = { version = "0.14", optional = true, features = ["ecdsa", "pkcs8"] } +rand = { version = "0.10.0", optional = true, features = [ "std", + "std_rng", + "thread_rng", ], default-features = false } -rsa = { version = "0.9.6", optional = true } -sha2 = { version = "0.10.7", optional = true, features = ["oid"] } +rsa = { version = "0.10.0-rc.18", optional = true } +sha2 = { version = "0.11", optional = true, features = ["oid"] } zeroize = { version = "1.8.2", features = ["derive"] } [target.'cfg(target_arch = "wasm32")'.dependencies] js-sys = "0.3" -getrandom = "0.2" +getrandom = { version = "0.4", features = ["wasm_js"] } [dev-dependencies] wasm-bindgen-test = "0.3.1" -ed25519-dalek = { version = "2.1.1", features = ["pkcs8", "rand_core"] } -rand = { version = "0.8.5", features = ["std"], default-features = false } -rand_core = "0.6.4" +ed25519-dalek = { version = "3.0.0", features = ["pkcs8", "rand_core", "alloc"] } +rand = { version = "0.10.0", features = ["std", "std_rng", "thread_rng"], default-features = false } [target.'cfg(not(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi")))))'.dev-dependencies] # For the custom time example time = "0.3" @@ -74,6 +76,7 @@ rust_crypto = [ "dep:hmac", "dep:p256", "dep:p384", + "dep:p521", "dep:rand", "dep:rsa", "dep:sha2", diff --git a/README.md b/README.md index 38c7b66a..3151d3c7 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ This library currently supports the following: - PS512 - ES256 - ES384 +- ES512 - EdDSA diff --git a/examples/ed25519.rs b/examples/ed25519.rs index 6a89d0f8..da87c68e 100644 --- a/examples/ed25519.rs +++ b/examples/ed25519.rs @@ -1,6 +1,5 @@ use ed25519_dalek::SigningKey; use ed25519_dalek::pkcs8::EncodePrivateKey; -use rand_core::OsRng; use serde::{Deserialize, Serialize}; use jsonwebtoken::{ @@ -14,12 +13,9 @@ pub struct Claims { } fn main() { - let signing_key = SigningKey::generate(&mut OsRng); + let signing_key = SigningKey::generate(&mut rand::rng()); let pkcs8 = signing_key.to_pkcs8_der().unwrap(); - let pkcs8 = pkcs8.as_bytes(); - // The `to_pkcs8_der` includes the public key, the first 48 bits are the private key. - let pkcs8 = &pkcs8[..48]; - let encoding_key = EncodingKey::from_ed_der(pkcs8); + let encoding_key = EncodingKey::from_ed_der(pkcs8.as_bytes()); let verifying_key = signing_key.verifying_key(); let public_key = verifying_key.as_bytes(); @@ -45,12 +41,9 @@ mod tests { impl Jot { fn new() -> Jot { - let signing_key = SigningKey::generate(&mut OsRng); + let signing_key = SigningKey::generate(&mut rand::rng()); let pkcs8 = signing_key.to_pkcs8_der().unwrap(); - let pkcs8 = pkcs8.as_bytes(); - // The `to_pkcs8_der` includes the public key, the first 48 bits are the private key. - let pkcs8 = &pkcs8[..48]; - let encoding_key = EncodingKey::from_ed_der(&pkcs8); + let encoding_key = EncodingKey::from_ed_der(pkcs8.as_bytes()); let verifying_key = signing_key.verifying_key(); let public_key = verifying_key.as_bytes(); diff --git a/src/algorithms.rs b/src/algorithms.rs index 906d9a63..11b0d4f1 100644 --- a/src/algorithms.rs +++ b/src/algorithms.rs @@ -30,7 +30,7 @@ impl AlgorithmFamily { Algorithm::PS384, Algorithm::PS512, ], - Self::Ec => &[Algorithm::ES256, Algorithm::ES384], + Self::Ec => &[Algorithm::ES256, Algorithm::ES384, Algorithm::ES512], Self::Ed => &[Algorithm::EdDSA], } } @@ -53,6 +53,8 @@ pub enum Algorithm { ES256, /// ECDSA using SHA-384 ES384, + /// ECDSA using SHA-512 + ES512, /// RSASSA-PKCS1-v1_5 using SHA-256 RS256, @@ -81,6 +83,7 @@ impl FromStr for Algorithm { "HS512" => Ok(Algorithm::HS512), "ES256" => Ok(Algorithm::ES256), "ES384" => Ok(Algorithm::ES384), + "ES512" => Ok(Algorithm::ES512), "RS256" => Ok(Algorithm::RS256), "RS384" => Ok(Algorithm::RS384), "PS256" => Ok(Algorithm::PS256), @@ -104,7 +107,7 @@ impl Algorithm { | Algorithm::PS256 | Algorithm::PS384 | Algorithm::PS512 => AlgorithmFamily::Rsa, - Algorithm::ES256 | Algorithm::ES384 => AlgorithmFamily::Ec, + Algorithm::ES256 | Algorithm::ES384 | Algorithm::ES512 => AlgorithmFamily::Ec, Algorithm::EdDSA => AlgorithmFamily::Ed, } } diff --git a/src/crypto/aws_lc/ecdsa.rs b/src/crypto/aws_lc/ecdsa.rs index daf967c9..dff9eb63 100644 --- a/src/crypto/aws_lc/ecdsa.rs +++ b/src/crypto/aws_lc/ecdsa.rs @@ -8,7 +8,8 @@ use crate::{Algorithm, DecodingKey, EncodingKey}; use aws_lc_rs::rand::SystemRandom; use aws_lc_rs::signature::{ ECDSA_P256_SHA256_FIXED, ECDSA_P256_SHA256_FIXED_SIGNING, ECDSA_P384_SHA384_FIXED, - ECDSA_P384_SHA384_FIXED_SIGNING, EcdsaKeyPair, VerificationAlgorithm, + ECDSA_P384_SHA384_FIXED_SIGNING, ECDSA_P521_SHA512_FIXED, ECDSA_P521_SHA512_FIXED_SIGNING, + EcdsaKeyPair, VerificationAlgorithm, }; use signature::{Error, Signer, Verifier}; @@ -85,3 +86,6 @@ define_ecdsa_verifier!(Es256Verifier, Algorithm::ES256, ECDSA_P256_SHA256_FIXED) define_ecdsa_signer!(Es384Signer, Algorithm::ES384, &ECDSA_P384_SHA384_FIXED_SIGNING); define_ecdsa_verifier!(Es384Verifier, Algorithm::ES384, ECDSA_P384_SHA384_FIXED); + +define_ecdsa_signer!(Es512Signer, Algorithm::ES512, &ECDSA_P521_SHA512_FIXED_SIGNING); +define_ecdsa_verifier!(Es512Verifier, Algorithm::ES512, ECDSA_P521_SHA512_FIXED); diff --git a/src/crypto/aws_lc/mod.rs b/src/crypto/aws_lc/mod.rs index 502d2a87..1fdc60a1 100644 --- a/src/crypto/aws_lc/mod.rs +++ b/src/crypto/aws_lc/mod.rs @@ -2,7 +2,7 @@ use aws_lc_rs::{ digest, signature::{ self as aws_sig, ECDSA_P256_SHA256_FIXED_SIGNING, ECDSA_P384_SHA384_FIXED_SIGNING, - EcdsaKeyPair, Ed25519KeyPair, KeyPair, + ECDSA_P521_SHA512_FIXED_SIGNING, EcdsaKeyPair, Ed25519KeyPair, KeyPair, }, }; @@ -41,6 +41,7 @@ fn ec_components_from_private_key( let (signing_alg, curve, pub_elem_bytes) = match alg { Algorithm::ES256 => (&ECDSA_P256_SHA256_FIXED_SIGNING, EllipticCurve::P256, 32), Algorithm::ES384 => (&ECDSA_P384_SHA384_FIXED_SIGNING, EllipticCurve::P384, 48), + Algorithm::ES512 => (&ECDSA_P521_SHA512_FIXED_SIGNING, EllipticCurve::P521, 66), _ => return Err(ErrorKind::InvalidEcdsaKey.into()), }; @@ -86,6 +87,7 @@ fn new_signer(algorithm: &Algorithm, key: &EncodingKey) -> Result Box::new(hmac::Hs512Signer::new(key)?) as Box, Algorithm::ES256 => Box::new(ecdsa::Es256Signer::new(key)?) as Box, Algorithm::ES384 => Box::new(ecdsa::Es384Signer::new(key)?) as Box, + Algorithm::ES512 => Box::new(ecdsa::Es512Signer::new(key)?) as Box, Algorithm::RS256 => Box::new(rsa::Rsa256Signer::new(key)?) as Box, Algorithm::RS384 => Box::new(rsa::Rsa384Signer::new(key)?) as Box, Algorithm::RS512 => Box::new(rsa::Rsa512Signer::new(key)?) as Box, @@ -108,6 +110,7 @@ fn new_verifier( Algorithm::HS512 => Box::new(hmac::Hs512Verifier::new(key)?) as Box, Algorithm::ES256 => Box::new(ecdsa::Es256Verifier::new(key)?) as Box, Algorithm::ES384 => Box::new(ecdsa::Es384Verifier::new(key)?) as Box, + Algorithm::ES512 => Box::new(ecdsa::Es512Verifier::new(key)?) as Box, Algorithm::RS256 => Box::new(rsa::Rsa256Verifier::new(key)?) as Box, Algorithm::RS384 => Box::new(rsa::Rsa384Verifier::new(key)?) as Box, Algorithm::RS512 => Box::new(rsa::Rsa512Verifier::new(key)?) as Box, diff --git a/src/crypto/rust_crypto/ecdsa.rs b/src/crypto/rust_crypto/ecdsa.rs index 1a20479f..6b472fb2 100644 --- a/src/crypto/rust_crypto/ecdsa.rs +++ b/src/crypto/rust_crypto/ecdsa.rs @@ -12,10 +12,13 @@ use p256::pkcs8::DecodePrivateKey; use p384::ecdsa::{ Signature as Signature384, SigningKey as SigningKey384, VerifyingKey as VerifyingKey384, }; +use p521::ecdsa::{ + Signature as Signature521, SigningKey as SigningKey521, VerifyingKey as VerifyingKey521, +}; use signature::{Error, Signer, Verifier}; macro_rules! define_ecdsa_signer { - ($name:ident, $alg:expr, $signing_key:ty) => { + ($name:ident, $alg:expr, $signing_key:ty, $signature:ty) => { pub struct $name($signing_key); impl $name { @@ -33,7 +36,7 @@ macro_rules! define_ecdsa_signer { impl Signer> for $name { fn try_sign(&self, msg: &[u8]) -> std::result::Result, Error> { - let signature = self.0.sign_recoverable(msg).map_err(Error::from_source)?.0; + let signature: $signature = self.0.sign(msg); Ok(signature.to_vec()) } } @@ -80,8 +83,10 @@ macro_rules! define_ecdsa_verifier { }; } -define_ecdsa_signer!(Es256Signer, Algorithm::ES256, SigningKey256); -define_ecdsa_signer!(Es384Signer, Algorithm::ES384, SigningKey384); +define_ecdsa_signer!(Es256Signer, Algorithm::ES256, SigningKey256, Signature256); +define_ecdsa_signer!(Es384Signer, Algorithm::ES384, SigningKey384, Signature384); +define_ecdsa_signer!(Es512Signer, Algorithm::ES512, SigningKey521, Signature521); define_ecdsa_verifier!(Es256Verifier, Algorithm::ES256, VerifyingKey256, Signature256); define_ecdsa_verifier!(Es384Verifier, Algorithm::ES384, VerifyingKey384, Signature384); +define_ecdsa_verifier!(Es512Verifier, Algorithm::ES512, VerifyingKey521, Signature521); diff --git a/src/crypto/rust_crypto/hmac.rs b/src/crypto/rust_crypto/hmac.rs index ead21d97..9e20973a 100644 --- a/src/crypto/rust_crypto/hmac.rs +++ b/src/crypto/rust_crypto/hmac.rs @@ -1,7 +1,7 @@ //! Implementations of the [`JwtSigner`] and [`JwtVerifier`] traits for the //! HMAC family of algorithms using `RustCrypto`'s [`hmac`]. -use hmac::{Hmac, Mac}; +use hmac::{HmacReset, KeyInit, Mac}; use sha2::{Sha256, Sha384, Sha512}; use signature::{Signer, Verifier}; @@ -9,9 +9,9 @@ use crate::crypto::{JwtSigner, JwtVerifier}; use crate::errors::{ErrorKind, Result, new_error}; use crate::{Algorithm, AlgorithmFamily, DecodingKey, EncodingKey}; -type HmacSha256 = Hmac; -type HmacSha384 = Hmac; -type HmacSha512 = Hmac; +type HmacSha256 = HmacReset; +type HmacSha384 = HmacReset; +type HmacSha512 = HmacReset; /// Macro to define an HMAC signer for a specific algorithm macro_rules! define_hmac_signer { diff --git a/src/crypto/rust_crypto/mod.rs b/src/crypto/rust_crypto/mod.rs index 1dd5bec4..b3885bad 100644 --- a/src/crypto/rust_crypto/mod.rs +++ b/src/crypto/rust_crypto/mod.rs @@ -6,6 +6,7 @@ use ::rsa::{ use ed25519_dalek::SigningKey as Ed25519SigningKey; use p256::{ecdsa::SigningKey as P256SigningKey, pkcs8::DecodePrivateKey}; use p384::ecdsa::SigningKey as P384SigningKey; +use p521::ecdsa::SigningKey as P521SigningKey; use sha2::{Digest, Sha256, Sha384, Sha512}; use crate::{ @@ -24,13 +25,19 @@ fn rsa_components_from_private_key(key_content: &[u8]) -> errors::Result<(Vec errors::Result<(Vec, Vec)> { let public_key = RsaPublicKey::from_pkcs1_der(key_content) .map_err(|e| ErrorKind::InvalidRsaKey(e.to_string()))?; - Ok((public_key.n().to_bytes_be(), public_key.e().to_bytes_be())) + Ok(( + public_key.n().to_be_bytes_trimmed_vartime().to_vec(), + public_key.e().to_be_bytes_trimmed_vartime().to_vec(), + )) } fn ec_components_from_private_key( @@ -42,7 +49,7 @@ fn ec_components_from_private_key( let signing_key = P256SigningKey::from_pkcs8_der(key_content) .map_err(|_| ErrorKind::InvalidEcdsaKey)?; let public_key = signing_key.verifying_key(); - let encoded = public_key.to_encoded_point(false); + let encoded = public_key.to_sec1_point(false); match encoded.coordinates() { p256::elliptic_curve::sec1::Coordinates::Uncompressed { x, y } => { Ok((EllipticCurve::P256, x.to_vec(), y.to_vec())) @@ -54,7 +61,7 @@ fn ec_components_from_private_key( let signing_key = P384SigningKey::from_pkcs8_der(key_content) .map_err(|_| ErrorKind::InvalidEcdsaKey)?; let public_key = signing_key.verifying_key(); - let encoded = public_key.to_encoded_point(false); + let encoded = public_key.to_sec1_point(false); match encoded.coordinates() { p384::elliptic_curve::sec1::Coordinates::Uncompressed { x, y } => { Ok((EllipticCurve::P384, x.to_vec(), y.to_vec())) @@ -62,6 +69,18 @@ fn ec_components_from_private_key( _ => Err(ErrorKind::InvalidEcdsaKey.into()), } } + Algorithm::ES512 => { + let signing_key = P521SigningKey::from_pkcs8_der(key_content) + .map_err(|_| ErrorKind::InvalidEcdsaKey)?; + let public_key = signing_key.verifying_key(); + let encoded = public_key.to_sec1_point(false); + match encoded.coordinates() { + p521::elliptic_curve::sec1::Coordinates::Uncompressed { x, y } => { + Ok((EllipticCurve::P521, x.to_vec(), y.to_vec())) + } + _ => Err(ErrorKind::InvalidEcdsaKey.into()), + } + } _ => Err(ErrorKind::InvalidEcdsaKey.into()), } } @@ -95,6 +114,7 @@ fn new_signer(algorithm: &Algorithm, key: &EncodingKey) -> Result Box::new(hmac::Hs512Signer::new(key)?) as Box, Algorithm::ES256 => Box::new(ecdsa::Es256Signer::new(key)?) as Box, Algorithm::ES384 => Box::new(ecdsa::Es384Signer::new(key)?) as Box, + Algorithm::ES512 => Box::new(ecdsa::Es512Signer::new(key)?) as Box, Algorithm::RS256 => Box::new(rsa::Rsa256Signer::new(key)?) as Box, Algorithm::RS384 => Box::new(rsa::Rsa384Signer::new(key)?) as Box, Algorithm::RS512 => Box::new(rsa::Rsa512Signer::new(key)?) as Box, @@ -117,6 +137,7 @@ fn new_verifier( Algorithm::HS512 => Box::new(hmac::Hs512Verifier::new(key)?) as Box, Algorithm::ES256 => Box::new(ecdsa::Es256Verifier::new(key)?) as Box, Algorithm::ES384 => Box::new(ecdsa::Es384Verifier::new(key)?) as Box, + Algorithm::ES512 => Box::new(ecdsa::Es512Verifier::new(key)?) as Box, Algorithm::RS256 => Box::new(rsa::Rsa256Verifier::new(key)?) as Box, Algorithm::RS384 => Box::new(rsa::Rsa384Verifier::new(key)?) as Box, Algorithm::RS512 => Box::new(rsa::Rsa512Verifier::new(key)?) as Box, diff --git a/src/crypto/rust_crypto/rsa.rs b/src/crypto/rust_crypto/rsa.rs index b5112eda..d6f9ab3c 100644 --- a/src/crypto/rust_crypto/rsa.rs +++ b/src/crypto/rust_crypto/rsa.rs @@ -2,7 +2,7 @@ //! RSA family of algorithms using RustCrypto. use rsa::{ - BigUint, Pkcs1v15Sign, Pss, RsaPublicKey, + BoxedUint, Pkcs1v15Sign, Pss, RsaPublicKey, pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}, pkcs1v15::SigningKey, pkcs8::AssociatedOid, @@ -29,7 +29,7 @@ fn try_sign_rsa( where H: Digest + AssociatedOid + FixedOutputReset, { - let mut rng = rand::thread_rng(); + let mut rng = rand::rng(); let private_key = rsa::RsaPrivateKey::from_pkcs1_der(encoding_key.as_bytes()) .map_err(signature::Error::from_source)?; if pss { @@ -57,9 +57,12 @@ fn verify_rsa( .map_err(signature::Error::from_source)?; } DecodingKeyKind::RsaModulusExponent { n, e } => { - RsaPublicKey::new(BigUint::from_bytes_be(n), BigUint::from_bytes_be(e))? - .verify(scheme, &digest, signature) - .map_err(signature::Error::from_source)?; + RsaPublicKey::new( + BoxedUint::from_be_slice_vartime(n), + BoxedUint::from_be_slice_vartime(e), + )? + .verify(scheme, &digest, signature) + .map_err(signature::Error::from_source)?; } }; @@ -115,7 +118,7 @@ macro_rules! define_rsa_verifier { signature: &Vec, ) -> std::result::Result<(), signature::Error> { if $pss { - verify_rsa::(Pss::new::<$hash>(), &self.0, msg, signature) + verify_rsa::, $hash>(Pss::<$hash>::new(), &self.0, msg, signature) } else { verify_rsa::<_, $hash>(Pkcs1v15Sign::new::<$hash>(), &self.0, msg, signature) } diff --git a/src/jwk.rs b/src/jwk.rs index c15d83a2..02eb4ce6 100644 --- a/src/jwk.rs +++ b/src/jwk.rs @@ -163,6 +163,8 @@ pub enum KeyAlgorithm { ES256, /// ECDSA using SHA-384 ES384, + /// ECDSA using SHA-512 + ES512, /// RSASSA-PKCS1-v1_5 using SHA-256 RS256, @@ -206,6 +208,7 @@ impl FromStr for KeyAlgorithm { "HS512" => Ok(KeyAlgorithm::HS512), "ES256" => Ok(KeyAlgorithm::ES256), "ES384" => Ok(KeyAlgorithm::ES384), + "ES512" => Ok(KeyAlgorithm::ES512), "RS256" => Ok(KeyAlgorithm::RS256), "RS384" => Ok(KeyAlgorithm::RS384), "PS256" => Ok(KeyAlgorithm::PS256), @@ -229,6 +232,7 @@ impl From for KeyAlgorithm { Algorithm::HS512 => KeyAlgorithm::HS512, Algorithm::ES256 => KeyAlgorithm::ES256, Algorithm::ES384 => KeyAlgorithm::ES384, + Algorithm::ES512 => KeyAlgorithm::ES512, Algorithm::RS256 => KeyAlgorithm::RS256, Algorithm::RS384 => KeyAlgorithm::RS384, Algorithm::RS512 => KeyAlgorithm::RS512, @@ -250,6 +254,7 @@ impl TryFrom for Algorithm { KeyAlgorithm::HS512 => Ok(Algorithm::HS512), KeyAlgorithm::ES256 => Ok(Algorithm::ES256), KeyAlgorithm::ES384 => Ok(Algorithm::ES384), + KeyAlgorithm::ES512 => Ok(Algorithm::ES512), KeyAlgorithm::RS256 => Ok(Algorithm::RS256), KeyAlgorithm::RS384 => Ok(Algorithm::RS384), KeyAlgorithm::RS512 => Ok(Algorithm::RS512), @@ -819,6 +824,7 @@ mod tests { (Algorithm::HS512, KeyAlgorithm::HS512), (Algorithm::ES256, KeyAlgorithm::ES256), (Algorithm::ES384, KeyAlgorithm::ES384), + (Algorithm::ES512, KeyAlgorithm::ES512), (Algorithm::RS256, KeyAlgorithm::RS256), (Algorithm::RS384, KeyAlgorithm::RS384), (Algorithm::RS512, KeyAlgorithm::RS512), diff --git a/tests/ecdsa/mod.rs b/tests/ecdsa/mod.rs index 25da1228..6f7981aa 100644 --- a/tests/ecdsa/mod.rs +++ b/tests/ecdsa/mod.rs @@ -191,3 +191,80 @@ fn ec_jwk_from_key() { .unwrap() ); } + +#[test] +#[wasm_bindgen_test] +fn es512_round_trip_sign_verification_pk8() { + let privkey = include_bytes!("private_es512_key.pk8"); + let pubkey = include_bytes!("public_es512_key.pk8"); + + let encrypted = + sign(b"hello world", &EncodingKey::from_ec_der(privkey), Algorithm::ES512).unwrap(); + let is_valid = + verify(&encrypted, b"hello world", &DecodingKey::from_ec_der(pubkey), Algorithm::ES512) + .unwrap(); + assert!(is_valid); +} + +#[cfg(feature = "use_pem")] +#[test] +#[wasm_bindgen_test] +fn es512_round_trip_sign_verification_pem() { + let privkey_pem = include_bytes!("private_es512_key.pem"); + let pubkey_pem = include_bytes!("public_es512_key.pem"); + + let encrypted = + sign(b"hello world", &EncodingKey::from_ec_pem(privkey_pem).unwrap(), Algorithm::ES512) + .unwrap(); + let is_valid = verify( + &encrypted, + b"hello world", + &DecodingKey::from_ec_pem(pubkey_pem).unwrap(), + Algorithm::ES512, + ) + .unwrap(); + assert!(is_valid); +} + +#[cfg(feature = "use_pem")] +#[test] +#[wasm_bindgen_test] +fn es512_round_trip_claim() { + let privkey_pem = include_bytes!("private_es512_key.pem"); + let pubkey_pem = include_bytes!("public_es512_key.pem"); + let my_claims = Claims { + sub: "es512@example.com".to_string(), + company: "ACME".to_string(), + exp: OffsetDateTime::now_utc().unix_timestamp() + 10000, + }; + let token = encode( + &Header::new(Algorithm::ES512), + &my_claims, + &EncodingKey::from_ec_pem(privkey_pem).unwrap(), + ) + .unwrap(); + let token_data = decode::( + &token, + &DecodingKey::from_ec_pem(pubkey_pem).unwrap(), + &Validation::new(Algorithm::ES512), + ) + .unwrap(); + assert_eq!(my_claims, token_data.claims); +} + +#[cfg(feature = "use_pem")] +#[test] +#[wasm_bindgen_test] +fn es512_jwk_from_key() { + use jsonwebtoken::jwk::Jwk; + + let privkey = include_str!("private_es512_key.pem"); + let encoding_key = EncodingKey::from_ec_pem(privkey.as_ref()).unwrap(); + let jwk = Jwk::from_encoding_key(&encoding_key, Algorithm::ES512).unwrap(); + match jwk.algorithm { + jsonwebtoken::jwk::AlgorithmParameters::EllipticCurve(params) => { + assert_eq!(params.curve, jsonwebtoken::jwk::EllipticCurve::P521); + } + _ => panic!("expected EC algorithm parameters"), + } +} diff --git a/tests/ecdsa/private_es512_key.pem b/tests/ecdsa/private_es512_key.pem new file mode 100644 index 00000000..42e76dd4 --- /dev/null +++ b/tests/ecdsa/private_es512_key.pem @@ -0,0 +1,8 @@ +-----BEGIN PRIVATE KEY----- +MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIASpHRYZx6l+CIFdI2 +9MO1GGnfy4eyWXApZLmQUm9nbZCX2MDY6VB63umkLii3h+ng899S2GNqpWpqK4oc +TOwlL16hgYkDgYYABABoIJ4A1xiM93QfTORva8sVTWyrqNFC8VaTA9wNbHTV+6U/ +SyG1IiQ/wjdmHNzZmXMNah/ICrJGcvrJkN8Ol3tEFgD346qAuxWQp5OF4Fvadluo +uN/z8IPoeGtWIcTeU2xiJMBohyAKBR4j7yCKVVrQ7FFZ6di4LikqgloUeaMeGLop +OA== +-----END PRIVATE KEY----- diff --git a/tests/ecdsa/private_es512_key.pk8 b/tests/ecdsa/private_es512_key.pk8 new file mode 100644 index 00000000..029c8dd4 Binary files /dev/null and b/tests/ecdsa/private_es512_key.pk8 differ diff --git a/tests/ecdsa/public_es512_key.pem b/tests/ecdsa/public_es512_key.pem new file mode 100644 index 00000000..4a23bbc9 --- /dev/null +++ b/tests/ecdsa/public_es512_key.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAaCCeANcYjPd0H0zkb2vLFU1sq6jR +QvFWkwPcDWx01fulP0shtSIkP8I3Zhzc2ZlzDWofyAqyRnL6yZDfDpd7RBYA9+Oq +gLsVkKeTheBb2nZbqLjf8/CD6HhrViHE3lNsYiTAaIcgCgUeI+8gilVa0OxRWenY +uC4pKoJaFHmjHhi6KTg= +-----END PUBLIC KEY----- diff --git a/tests/ecdsa/public_es512_key.pk8 b/tests/ecdsa/public_es512_key.pk8 new file mode 100644 index 00000000..62fdb9f2 Binary files /dev/null and b/tests/ecdsa/public_es512_key.pk8 differ