Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
33d2c21
support wasm
itanxiao Jun 19, 2023
b116e44
upgrade dependency
itanxiao Mar 13, 2024
e2a203f
remove ring
itanxiao Mar 15, 2024
5bb1d75
Merge branch 'master' into wasm_support
itanxiao Mar 15, 2024
d80832c
fix wasm test failed
itanxiao Mar 17, 2024
69cbfa3
fix cargo format
itanxiao Mar 17, 2024
a66864f
change ci branch
itanxiao Mar 17, 2024
485fb9f
fix ci
itanxiao Mar 17, 2024
490564c
fix ci
itanxiao Mar 17, 2024
a672130
fix ci
itanxiao Mar 17, 2024
73ea869
remove ci branch
itanxiao Mar 17, 2024
a41c817
fix examples ed25519 test failed
itanxiao Apr 6, 2024
6f9b553
Next version
Keats Aug 29, 2024
e061882
Remove downgrade steps
Keats Sep 2, 2024
e5ba5a1
Merge branch 'master' into new-backends
Keats Sep 2, 2024
502faa4
feat(encoder): Add encoder builder
sidrubs Sep 30, 2024
a701547
feat(encoder): Convert to dynamic dispatch
sidrubs Sep 30, 2024
6a41ba7
feat(decoder): Create decoder
sidrubs Sep 30, 2024
66d54be
test: Get HMAC tests passing
sidrubs Oct 3, 2024
0886064
docs: Neaten up docstrings
sidrubs Oct 3, 2024
337f9ed
feat(crypto): Implement JwtSigner and JwtVerifier for aws-lc-rs
sidrubs Oct 5, 2024
a0431d8
feat: Remove builder style implementation
sidrubs Oct 12, 2024
4225e1f
feat: Use original encoding and decoding key structs
sidrubs Oct 13, 2024
78e84c1
feat(crypto): Add RSA family
sidrubs Oct 14, 2024
2a50e0d
Add ECDSA via AWS-LC
sulami May 10, 2025
19ee8f3
Implement EdDSA through AWS-LC
sulami May 10, 2025
765c04c
Verify ES and ED keys are of the right type
sulami May 10, 2025
e1305ef
Implement RSA-PSS via AWS-LC
sulami May 10, 2025
e37ebee
Implement EdDSA via RustCrypto/Dalek
sulami May 10, 2025
25f84c3
Implement EcDSA through RustCrypto
sulami May 10, 2025
4b7fdfb
Implement RSA via RustCrypto
sulami May 10, 2025
1f49f43
Clean up optional dependencies
sulami May 10, 2025
6062c96
Fix all test-breaking issues with the RustCrypto versions
sulami May 10, 2025
492760f
Re-add the crypto::{sign, verify} convenience functions
sulami May 10, 2025
eed1c1c
Require at least one crypto backend to be enabled
sulami May 10, 2025
8f60acf
Merge remote-tracking branch 'upstream/master' into decoupled-crypto-…
sulami May 11, 2025
660d89e
Ensure tests pass without use_pem feature as well
sulami May 11, 2025
9adb7da
Fix dependency features & clippy lints
sulami May 11, 2025
01eca4c
Reduce code duplication in crypto impls through macros
sulami Jun 25, 2025
903ecff
Move try_get_hmac_secret directly into en-/decoding key impls
sulami Jun 25, 2025
b8d2906
Re-enable the HMAC sign & verify test cases
sulami Jun 25, 2025
d6151bd
Uncomment the algorithm matching in verify_signature again
sulami Jul 3, 2025
76b2fe3
Inline _encode and _decode
sulami Jul 3, 2025
09e8d42
Fix some docstring typos
sulami Aug 13, 2025
f35c3e8
Don't default to a crypto backend
sulami Aug 18, 2025
755d868
Explicitly annotate an implicit lifetime
sulami Aug 19, 2025
eca3603
Enable getrandom/js for WASM tests in CI
sulami Aug 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 72 additions & 69 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,83 +1,86 @@
name: ci
on:
push:
branches:
- master
pull_request:
push:
branches:
- master
pull_request:

jobs:
style:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Check format
run: cargo fmt --check
style:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Check format
run: cargo fmt --check

clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- run: cargo clippy --all-targets --all-features -- -D warnings
clippy:
name: Clippy
runs-on: ubuntu-latest
strategy:
matrix:
backend: [ aws_lc_rs, rust_crypto ]
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- run: cargo clippy --all-targets --features ${{ matrix.backend }} -- -D warnings

tests:
name: Tests
runs-on: ${{ matrix.os }}
strategy:
matrix:
build: [pinned, stable, nightly]
include:
- build: pinned
os: ubuntu-20.04
rust: 1.73.0
- build: stable
os: ubuntu-20.04
rust: stable
- build: nightly
os: ubuntu-20.04
rust: nightly
steps:
- uses: actions/checkout@v3
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
tests:
name: Tests
runs-on: ${{ matrix.os }}
strategy:
matrix:
build: [ pinned, stable, nightly ]
backend: [ aws_lc_rs, rust_crypto ]
include:
- build: pinned
os: ubuntu-20.04
rust: 1.73.0
- build: stable
os: ubuntu-20.04
rust: stable
- build: nightly
os: ubuntu-20.04
rust: nightly
steps:
- uses: actions/checkout@v3
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}

- name: Build System Info
run: rustc --version
- name: Build System Info
run: rustc --version

- name: Run tests default features
run: cargo test
- name: Run tests default features
run: cargo test --features ${{ matrix.backend }}

- name: Run tests no features
run: cargo test --no-default-features
- name: Run tests no features
run: cargo test --no-default-features --features ${{ matrix.backend }}

wasm:
name: Run tests in wasm
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
wasm:
name: Run tests in wasm
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown

- uses: actions/setup-node@v4
- uses: actions/setup-node@v4

- name: Install wasm-pack
run: cargo install wasm-pack
- name: Install wasm-pack
run: cargo install wasm-pack

- name: Run tests default features
run: wasm-pack test --node

- name: Run tests no features
run: wasm-pack test --node --no-default-features
- name: Run tests default features
run: wasm-pack test --node --features rust_crypto,getrandom/js

- name: Run tests no features
run: wasm-pack test --node --no-default-features --features rust_crypto,getrandom/js
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Changelog

## 10.0.0 (unreleased)

## 9.3.1 (2024-02-06)

- Update base64
Expand Down
27 changes: 21 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,36 @@ include = [
rust-version = "1.73.0"

[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
base64 = "0.22"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
signature = { version = "2.2.0", features = ["std"] }

# For PEM decoding
pem = { version = "3", optional = true }
simple_asn1 = { version = "0.6", optional = true }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
ring = { version = "0.17.4", features = ["std"] }
# "aws_lc_rs" feature
aws-lc-rs = { version = "1.10.0", optional = true }

# "rust_crypto" feature
ed25519-dalek = { version = "2.1.1", optional = true, features = ["pkcs8"] }
hmac = { version = "0.12.1", optional = true }
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 = ["std"], default-features = false }
rsa = { version = "0.9.6", optional = true }
sha2 = { version = "0.10.7", optional = true, features = ["oid"] }

[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = "0.3"
ring = { version = "0.17.4", features = ["std", "wasm32_unknown_unknown_js"] }
getrandom = "0.2"

[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"
[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"
Expand All @@ -50,6 +63,8 @@ criterion = { version = "0.4", default-features = false }
[features]
default = ["use_pem"]
use_pem = ["pem", "simple_asn1"]
rust_crypto = ["ed25519-dalek", "hmac", "p256", "p384", "rand", "rsa", "sha2"]
aws_lc_rs = ["aws-lc-rs"]

[[bench]]
name = "jwt"
Expand Down
11 changes: 7 additions & 4 deletions examples/custom_time.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};
use time::{Duration, OffsetDateTime};

use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation};

const SECRET: &str = "some-secret";

#[derive(Debug, PartialEq, Serialize, Deserialize)]
Expand Down Expand Up @@ -60,13 +61,15 @@ mod jwt_numeric_date {

#[cfg(test)]
mod tests {
const EXPECTED_TOKEN: &str = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJDdXN0b20gT2Zmc2V0RGF0ZVRpbWUgc2VyL2RlIiwiaWF0IjowLCJleHAiOjMyNTAzNjgwMDAwfQ.BcPipupP9oIV6uFRI6Acn7FMLws_wA3oo6CrfeFF3Gg";
use time::{Duration, OffsetDateTime};

use super::super::{Claims, SECRET};
use jsonwebtoken::{
decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation,
};
use time::{Duration, OffsetDateTime};

use super::super::{Claims, SECRET};

const EXPECTED_TOKEN: &str = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJDdXN0b20gT2Zmc2V0RGF0ZVRpbWUgc2VyL2RlIiwiaWF0IjowLCJleHAiOjMyNTAzNjgwMDAwfQ.BcPipupP9oIV6uFRI6Acn7FMLws_wA3oo6CrfeFF3Gg";

#[test]
fn round_trip() {
Expand Down
34 changes: 24 additions & 10 deletions examples/ed25519.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use ed25519_dalek::pkcs8::EncodePrivateKey;
use ed25519_dalek::SigningKey;
use rand_core::OsRng;
use serde::{Deserialize, Serialize};

use jsonwebtoken::{
decode, encode, get_current_timestamp, Algorithm, DecodingKey, EncodingKey, Validation,
};
use ring::signature::{Ed25519KeyPair, KeyPair};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
Expand All @@ -11,11 +14,16 @@ pub struct Claims {
}

fn main() {
let doc = Ed25519KeyPair::generate_pkcs8(&ring::rand::SystemRandom::new()).unwrap();
let encoding_key = EncodingKey::from_ed_der(doc.as_ref());
let signing_key = SigningKey::generate(&mut OsRng);
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 pair = Ed25519KeyPair::from_pkcs8(doc.as_ref()).unwrap();
let decoding_key = DecodingKey::from_ed_der(pair.public_key().as_ref());
let verifying_key = signing_key.verifying_key();
let public_key = verifying_key.as_bytes();
let decoding_key = DecodingKey::from_ed_der(public_key);

let claims = Claims { sub: "test".to_string(), exp: get_current_timestamp() };

Expand All @@ -37,11 +45,17 @@ mod tests {

impl Jot {
fn new() -> Jot {
let doc = Ed25519KeyPair::generate_pkcs8(&ring::rand::SystemRandom::new()).unwrap();
let encoding_key = EncodingKey::from_ed_der(doc.as_ref());
let signing_key = SigningKey::generate(&mut OsRng);
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 verifying_key = signing_key.verifying_key();
let public_key = verifying_key.as_bytes();
let decoding_key = DecodingKey::from_ed_der(public_key);

let pair = Ed25519KeyPair::from_pkcs8(doc.as_ref()).unwrap();
let decoding_key = DecodingKey::from_ed_der(pair.public_key().as_ref());
Jot { encoding_key, decoding_key }
}
}
Expand Down
3 changes: 2 additions & 1 deletion examples/validation.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use serde::{Deserialize, Serialize};

use jsonwebtoken::errors::ErrorKind;
use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
struct Claims {
Expand Down
6 changes: 4 additions & 2 deletions src/algorithms.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::errors::{Error, ErrorKind, Result};
use serde::{Deserialize, Serialize};
use std::str::FromStr;

use serde::{Deserialize, Serialize};

use crate::errors::{Error, ErrorKind, Result};

#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
pub(crate) enum AlgorithmFamily {
Hmac,
Expand Down
Loading