Skip to content

Commit 38698b3

Browse files
committed
remove custom-provider feature, make jwk utility functions private
1 parent 370f904 commit 38698b3

File tree

17 files changed

+101
-146
lines changed

17 files changed

+101
-146
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ wasm-bindgen-test = "0.3.1"
5353
ed25519-dalek = { version = "2.1.1", features = ["pkcs8", "rand_core"] }
5454
rand = { version = "0.8.5", features = ["std"], default-features = false }
5555
rand_core = "0.6.4"
56+
# for the custom provider example
57+
botan = { version = "0.12.0", features = ["vendored"] }
5658
[target.'cfg(not(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi")))))'.dev-dependencies]
5759
# For the custom time example
5860
time = "0.3"
@@ -68,7 +70,6 @@ default = ["use_pem"]
6870
use_pem = ["pem", "simple_asn1"]
6971
rust_crypto = ["ed25519-dalek", "hmac", "p256", "p384", "rand", "rsa", "sha2"]
7072
aws_lc_rs = ["aws-lc-rs"]
71-
custom-provider = []
7273

7374
[[bench]]
7475
name = "jwt"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jsonwebtoken = { version = "10", features = ["aws_lc_rs"] }
1515
serde = {version = "1.0", features = ["derive"] }
1616
```
1717

18-
Two crypto backends are available via features, `aws_lc_rs` and `rust_crypto`, at most one of which must be enabled. If you wish to use a custom crypto provider, enable the `custom-provider` feature instead.
18+
Two crypto backends are available via features, `aws_lc_rs` and `rust_crypto`, at most one of which must be enabled. If you select neither feature, you need to provide your own `CryptoProvider`.
1919

2020
The minimum required Rust version (MSRV) is specified in the `rust-version` field in this project's [Cargo.toml](Cargo.toml).
2121

examples/custom_provider.rs

Lines changed: 60 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
use jsonwebtoken::{
2-
Algorithm, DecodingKey, EncodingKey, Header, Validation,
2+
Algorithm, AlgorithmFamily, DecodingKey, EncodingKey, Error as SigError, Header, Signer,
3+
Validation, Verifier,
34
crypto::{CryptoProvider, JwkUtils, JwtSigner, JwtVerifier},
45
decode, encode,
5-
errors::Error,
6+
errors::{Error, ErrorKind},
67
};
78
use serde::{Deserialize, Serialize};
8-
use signature::{Signer, Verifier};
99

1010
fn new_signer(algorithm: &Algorithm, key: &EncodingKey) -> Result<Box<dyn JwtSigner>, Error> {
1111
let jwt_signer = match algorithm {
12-
Algorithm::EdDSA => Box::new(CustomEdDSASigner::new(key)?) as Box<dyn JwtSigner>,
12+
Algorithm::EdDSA => Box::new(EdDSASigner::new(key)?) as Box<dyn JwtSigner>,
1313
_ => unimplemented!(),
1414
};
1515

@@ -18,49 +18,71 @@ fn new_signer(algorithm: &Algorithm, key: &EncodingKey) -> Result<Box<dyn JwtSig
1818

1919
fn new_verifier(algorithm: &Algorithm, key: &DecodingKey) -> Result<Box<dyn JwtVerifier>, Error> {
2020
let jwt_verifier = match algorithm {
21-
Algorithm::EdDSA => Box::new(CustomEdDSAVerifier::new(key)?) as Box<dyn JwtVerifier>,
21+
Algorithm::EdDSA => Box::new(EdDSAVerifier::new(key)?) as Box<dyn JwtVerifier>,
2222
_ => unimplemented!(),
2323
};
2424

2525
Ok(jwt_verifier)
2626
}
2727

28-
pub struct CustomEdDSASigner;
28+
struct EdDSASigner(botan::Privkey);
2929

30-
impl CustomEdDSASigner {
31-
fn new(_: &EncodingKey) -> Result<Self, Error> {
32-
Ok(CustomEdDSASigner)
30+
impl EdDSASigner {
31+
fn new(encoding_key: &EncodingKey) -> Result<Self, Error> {
32+
if encoding_key.family() != AlgorithmFamily::Ed {
33+
return Err(ErrorKind::InvalidKeyFormat.into());
34+
}
35+
36+
Ok(Self(
37+
botan::Privkey::load_der(encoding_key.inner())
38+
.map_err(|_| ErrorKind::InvalidEddsaKey)?,
39+
))
3340
}
3441
}
3542

36-
// WARNING: This is obviously not secure at all and should NEVER be done in practice!
37-
impl Signer<Vec<u8>> for CustomEdDSASigner {
38-
fn try_sign(&self, _: &[u8]) -> Result<Vec<u8>, signature::Error> {
39-
Ok(vec![0; 16])
43+
impl Signer<Vec<u8>> for EdDSASigner {
44+
fn try_sign(&self, msg: &[u8]) -> std::result::Result<Vec<u8>, SigError> {
45+
let mut rng = botan::RandomNumberGenerator::new_system().map_err(SigError::from_source)?;
46+
let mut signer = botan::Signer::new(&self.0, "Pure").map_err(SigError::from_source)?;
47+
signer.update(msg).map_err(SigError::from_source)?;
48+
signer.finish(&mut rng).map_err(SigError::from_source)
4049
}
4150
}
4251

43-
impl JwtSigner for CustomEdDSASigner {
52+
impl JwtSigner for EdDSASigner {
4453
fn algorithm(&self) -> Algorithm {
4554
Algorithm::EdDSA
4655
}
4756
}
4857

49-
pub struct CustomEdDSAVerifier;
58+
struct EdDSAVerifier(botan::Pubkey);
59+
60+
impl EdDSAVerifier {
61+
fn new(decoding_key: &DecodingKey) -> Result<Self, Error> {
62+
if decoding_key.family() != AlgorithmFamily::Ed {
63+
return Err(ErrorKind::InvalidKeyFormat.into());
64+
}
5065

51-
impl CustomEdDSAVerifier {
52-
fn new(_: &DecodingKey) -> Result<Self, Error> {
53-
Ok(CustomEdDSAVerifier)
66+
Ok(Self(
67+
botan::Pubkey::load_ed25519(decoding_key.as_bytes())
68+
.map_err(|_| ErrorKind::InvalidEddsaKey)?,
69+
))
5470
}
5571
}
5672

57-
impl Verifier<Vec<u8>> for CustomEdDSAVerifier {
58-
fn verify(&self, _: &[u8], signature: &Vec<u8>) -> Result<(), signature::Error> {
59-
if signature == &vec![0; 16] { Ok(()) } else { Err(signature::Error::new()) }
73+
impl Verifier<Vec<u8>> for EdDSAVerifier {
74+
fn verify(&self, msg: &[u8], signature: &Vec<u8>) -> std::result::Result<(), SigError> {
75+
let mut verifier = botan::Verifier::new(&self.0, "Pure").map_err(SigError::from_source)?;
76+
verifier.update(msg).map_err(SigError::from_source)?;
77+
verifier
78+
.finish(signature)
79+
.map_err(SigError::from_source)?
80+
.then_some(())
81+
.ok_or(SigError::new())
6082
}
6183
}
6284

63-
impl JwtVerifier for CustomEdDSAVerifier {
85+
impl JwtVerifier for EdDSAVerifier {
6486
fn algorithm(&self) -> Algorithm {
6587
Algorithm::EdDSA
6688
}
@@ -82,21 +104,30 @@ fn main() {
82104
};
83105
my_crypto_provider.install_default().unwrap();
84106

85-
// for an actual EdDSA implementation, this would be some private key
86-
let key = b"secret";
107+
// generate a new key
108+
let (privkey, pubkey) = {
109+
let key = botan::Privkey::create(
110+
"Ed25519",
111+
"",
112+
&mut botan::RandomNumberGenerator::new_system().unwrap(),
113+
)
114+
.unwrap();
115+
(key.pem_encode().unwrap(), key.pubkey().unwrap().pem_encode().unwrap())
116+
};
87117
let my_claims = Claims { sub: "me".to_owned(), exp: 10000000000 };
88118

89119
// our crypto provider only supports EdDSA
90120
let header = Header::new(Algorithm::EdDSA);
91121

92-
let token = match encode(&header, &my_claims, &EncodingKey::from_ed_der(key)) {
93-
Ok(t) => t,
94-
Err(_) => panic!(), // in practice you would return an error
95-
};
122+
let token =
123+
match encode(&header, &my_claims, &EncodingKey::from_ed_pem(privkey.as_bytes()).unwrap()) {
124+
Ok(t) => t,
125+
Err(_) => panic!(), // in practice you would return an error
126+
};
96127

97128
let claims = match decode::<Claims>(
98129
token,
99-
&DecodingKey::from_ed_der(key),
130+
&DecodingKey::from_ed_pem(pubkey.as_bytes()).unwrap(),
100131
&Validation::new(Algorithm::EdDSA),
101132
) {
102133
Ok(c) => c.claims,

src/crypto/aws_lc/ecdsa.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ macro_rules! define_ecdsa_signer {
1818

1919
impl $name {
2020
pub(crate) fn new(encoding_key: &EncodingKey) -> Result<Self> {
21-
if encoding_key.family != AlgorithmFamily::Ec {
21+
if encoding_key.family() != AlgorithmFamily::Ec {
2222
return Err(new_error(ErrorKind::InvalidKeyFormat));
2323
}
2424

@@ -51,7 +51,7 @@ macro_rules! define_ecdsa_verifier {
5151

5252
impl $name {
5353
pub(crate) fn new(decoding_key: &DecodingKey) -> Result<Self> {
54-
if decoding_key.family != AlgorithmFamily::Ec {
54+
if decoding_key.family() != AlgorithmFamily::Ec {
5555
return Err(new_error(ErrorKind::InvalidKeyFormat));
5656
}
5757

src/crypto/aws_lc/eddsa.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub struct EdDSASigner(Ed25519KeyPair);
1111

1212
impl EdDSASigner {
1313
pub(crate) fn new(encoding_key: &EncodingKey) -> Result<Self> {
14-
if encoding_key.family != AlgorithmFamily::Ed {
14+
if encoding_key.family() != AlgorithmFamily::Ed {
1515
return Err(new_error(ErrorKind::InvalidKeyFormat));
1616
}
1717

@@ -38,7 +38,7 @@ pub struct EdDSAVerifier(DecodingKey);
3838

3939
impl EdDSAVerifier {
4040
pub(crate) fn new(decoding_key: &DecodingKey) -> Result<Self> {
41-
if decoding_key.family != AlgorithmFamily::Ed {
41+
if decoding_key.family() != AlgorithmFamily::Ed {
4242
return Err(new_error(ErrorKind::InvalidKeyFormat));
4343
}
4444

src/crypto/aws_lc/mod.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,15 @@ mod eddsa;
1515
mod hmac;
1616
mod rsa;
1717

18-
/// Given a DER encoded private key, extract the RSA public key components (n, e)
19-
pub fn extract_rsa_public_key_components(key_content: &[u8]) -> errors::Result<(Vec<u8>, Vec<u8>)> {
18+
fn extract_rsa_public_key_components(key_content: &[u8]) -> errors::Result<(Vec<u8>, Vec<u8>)> {
2019
let key_pair = aws_sig::RsaKeyPair::from_der(key_content)
2120
.map_err(|e| ErrorKind::InvalidRsaKey(e.to_string()))?;
2221
let public = key_pair.public_key();
2322
let components = aws_sig::RsaPublicKeyComponents::<Vec<u8>>::from(public);
2423
Ok((components.n, components.e))
2524
}
2625

27-
/// Given a DER encoded private key and an algorithm, extract the associated curve
28-
/// and the EC public key components (x, y)
29-
pub fn extract_ec_public_key_coordinates(
26+
fn extract_ec_public_key_coordinates(
3027
key_content: &[u8],
3128
alg: Algorithm,
3229
) -> errors::Result<(EllipticCurve, Vec<u8>, Vec<u8>)> {
@@ -52,8 +49,7 @@ pub fn extract_ec_public_key_coordinates(
5249
Ok((curve, x.to_vec(), y.to_vec()))
5350
}
5451

55-
/// Given some data and a name of a hash function, compute hash_function(data)
56-
pub fn compute_digest(data: &[u8], hash_function: ThumbprintHash) -> Vec<u8> {
52+
fn compute_digest(data: &[u8], hash_function: ThumbprintHash) -> Vec<u8> {
5753
let algorithm = match hash_function {
5854
ThumbprintHash::SHA256 => &digest::SHA256,
5955
ThumbprintHash::SHA384 => &digest::SHA384,

src/crypto/aws_lc/rsa.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn verify_rsa(
3737
msg: &[u8],
3838
signature: &[u8],
3939
) -> std::result::Result<(), signature::Error> {
40-
match &decoding_key.kind {
40+
match decoding_key.kind() {
4141
DecodingKeyKind::SecretOrDer(bytes) => {
4242
let public_key = crypto_sig::UnparsedPublicKey::new(algorithm, bytes);
4343
public_key.verify(msg, signature).map_err(signature::Error::from_source)?;
@@ -57,7 +57,7 @@ macro_rules! define_rsa_signer {
5757

5858
impl $name {
5959
pub(crate) fn new(encoding_key: &EncodingKey) -> Result<Self> {
60-
if encoding_key.family != AlgorithmFamily::Rsa {
60+
if encoding_key.family() != AlgorithmFamily::Rsa {
6161
return Err(new_error(ErrorKind::InvalidKeyFormat));
6262
}
6363

@@ -85,7 +85,7 @@ macro_rules! define_rsa_verifier {
8585

8686
impl $name {
8787
pub(crate) fn new(decoding_key: &DecodingKey) -> Result<Self> {
88-
if decoding_key.family != AlgorithmFamily::Rsa {
88+
if decoding_key.family() != AlgorithmFamily::Rsa {
8989
return Err(new_error(ErrorKind::InvalidKeyFormat));
9090
}
9191

src/crypto/mod.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,20 +132,12 @@ See the documentation of the CryptoProvider type for more information.
132132

133133
/// Determine a `CryptoProvider` based on crate features.
134134
pub fn from_crate_features() -> Option<Self> {
135-
#[cfg(all(
136-
feature = "rust_crypto",
137-
not(feature = "aws_lc_rs"),
138-
not(feature = "custom-provider")
139-
))]
135+
#[cfg(all(feature = "rust_crypto", not(feature = "aws_lc_rs")))]
140136
{
141137
return Some(rust_crypto::DEFAULT_PROVIDER);
142138
}
143139

144-
#[cfg(all(
145-
feature = "aws_lc_rs",
146-
not(feature = "rust_crypto"),
147-
not(feature = "custom-provider")
148-
))]
140+
#[cfg(all(feature = "aws_lc_rs", not(feature = "rust_crypto")))]
149141
{
150142
return Some(aws_lc::DEFAULT_PROVIDER);
151143
}

src/crypto/rust_crypto/ecdsa.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ macro_rules! define_ecdsa_signer {
2020

2121
impl $name {
2222
pub(crate) fn new(encoding_key: &EncodingKey) -> Result<Self> {
23-
if encoding_key.family != AlgorithmFamily::Ec {
23+
if encoding_key.family() != AlgorithmFamily::Ec {
2424
return Err(new_error(ErrorKind::InvalidKeyFormat));
2525
}
2626

@@ -52,7 +52,7 @@ macro_rules! define_ecdsa_verifier {
5252

5353
impl $name {
5454
pub(crate) fn new(decoding_key: &DecodingKey) -> Result<Self> {
55-
if decoding_key.family != AlgorithmFamily::Ec {
55+
if decoding_key.family() != AlgorithmFamily::Ec {
5656
return Err(new_error(ErrorKind::InvalidKeyFormat));
5757
}
5858

src/crypto/rust_crypto/eddsa.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub struct EdDSASigner(SigningKey);
1212

1313
impl EdDSASigner {
1414
pub(crate) fn new(encoding_key: &EncodingKey) -> Result<Self> {
15-
if encoding_key.family != AlgorithmFamily::Ed {
15+
if encoding_key.family() != AlgorithmFamily::Ed {
1616
return Err(new_error(ErrorKind::InvalidKeyFormat));
1717
}
1818

@@ -39,7 +39,7 @@ pub struct EdDSAVerifier(VerifyingKey);
3939

4040
impl EdDSAVerifier {
4141
pub(crate) fn new(decoding_key: &DecodingKey) -> Result<Self> {
42-
if decoding_key.family != AlgorithmFamily::Ed {
42+
if decoding_key.family() != AlgorithmFamily::Ed {
4343
return Err(new_error(ErrorKind::InvalidKeyFormat));
4444
}
4545

0 commit comments

Comments
 (0)