jsonwebtoken_botan/
lib.rs1#![deny(missing_docs)]
4
5use botan::{HashFunction, Privkey};
6use jsonwebtoken::{
7 Algorithm, DecodingKey, EncodingKey,
8 crypto::{CryptoProvider, JwkUtils, JwtSigner, JwtVerifier},
9 errors::{self, Error, ErrorKind},
10 jwk::{EllipticCurve, ThumbprintHash},
11};
12
13mod ecdsa;
14mod eddsa;
15mod hmac;
16mod rsa;
17
18fn new_signer(algorithm: &Algorithm, key: &EncodingKey) -> Result<Box<dyn JwtSigner>, Error> {
19 let jwt_signer = match algorithm {
20 Algorithm::HS256 => Box::new(hmac::Hs256Signer::new(key)?) as Box<dyn JwtSigner>,
21 Algorithm::HS384 => Box::new(hmac::Hs384Signer::new(key)?) as Box<dyn JwtSigner>,
22 Algorithm::HS512 => Box::new(hmac::Hs512Signer::new(key)?) as Box<dyn JwtSigner>,
23 Algorithm::ES256 => Box::new(ecdsa::Es256Signer::new(key)?) as Box<dyn JwtSigner>,
24 Algorithm::ES384 => Box::new(ecdsa::Es384Signer::new(key)?) as Box<dyn JwtSigner>,
25 Algorithm::RS256 => Box::new(rsa::Rsa256Signer::new(key)?) as Box<dyn JwtSigner>,
26 Algorithm::RS384 => Box::new(rsa::Rsa384Signer::new(key)?) as Box<dyn JwtSigner>,
27 Algorithm::RS512 => Box::new(rsa::Rsa512Signer::new(key)?) as Box<dyn JwtSigner>,
28 Algorithm::PS256 => Box::new(rsa::RsaPss256Signer::new(key)?) as Box<dyn JwtSigner>,
29 Algorithm::PS384 => Box::new(rsa::RsaPss384Signer::new(key)?) as Box<dyn JwtSigner>,
30 Algorithm::PS512 => Box::new(rsa::RsaPss512Signer::new(key)?) as Box<dyn JwtSigner>,
31 Algorithm::EdDSA => Box::new(eddsa::EdDSASigner::new(key)?) as Box<dyn JwtSigner>,
32 };
33
34 Ok(jwt_signer)
35}
36
37fn new_verifier(algorithm: &Algorithm, key: &DecodingKey) -> Result<Box<dyn JwtVerifier>, Error> {
38 let jwt_verifier = match algorithm {
39 Algorithm::HS256 => Box::new(hmac::Hs256Verifier::new(key)?) as Box<dyn JwtVerifier>,
40 Algorithm::HS384 => Box::new(hmac::Hs384Verifier::new(key)?) as Box<dyn JwtVerifier>,
41 Algorithm::HS512 => Box::new(hmac::Hs512Verifier::new(key)?) as Box<dyn JwtVerifier>,
42 Algorithm::ES256 => Box::new(ecdsa::Es256Verifier::new(key)?) as Box<dyn JwtVerifier>,
43 Algorithm::ES384 => Box::new(ecdsa::Es384Verifier::new(key)?) as Box<dyn JwtVerifier>,
44 Algorithm::RS256 => Box::new(rsa::Rsa256Verifier::new(key)?) as Box<dyn JwtVerifier>,
45 Algorithm::RS384 => Box::new(rsa::Rsa384Verifier::new(key)?) as Box<dyn JwtVerifier>,
46 Algorithm::RS512 => Box::new(rsa::Rsa512Verifier::new(key)?) as Box<dyn JwtVerifier>,
47 Algorithm::PS256 => Box::new(rsa::RsaPss256Verifier::new(key)?) as Box<dyn JwtVerifier>,
48 Algorithm::PS384 => Box::new(rsa::RsaPss384Verifier::new(key)?) as Box<dyn JwtVerifier>,
49 Algorithm::PS512 => Box::new(rsa::RsaPss512Verifier::new(key)?) as Box<dyn JwtVerifier>,
50 Algorithm::EdDSA => Box::new(eddsa::EdDSAVerifier::new(key)?) as Box<dyn JwtVerifier>,
51 };
52
53 Ok(jwt_verifier)
54}
55
56fn extract_rsa_public_key_components(key_content: &[u8]) -> errors::Result<(Vec<u8>, Vec<u8>)> {
57 let privkey =
58 Privkey::load_rsa_pkcs1(key_content).map_err(|e| ErrorKind::Provider(e.to_string()))?;
59 let n = privkey
60 .get_field("n")
61 .map_err(|e| ErrorKind::Provider(e.to_string()))?
62 .to_bin()
63 .map_err(|e| ErrorKind::Provider(e.to_string()))?;
64 let e = privkey
65 .get_field("e")
66 .map_err(|e| ErrorKind::Provider(e.to_string()))?
67 .to_bin()
68 .map_err(|e| ErrorKind::Provider(e.to_string()))?;
69 Ok((n, e))
70}
71
72fn extract_ec_public_key_coordinates(
73 key_content: &[u8],
74 alg: Algorithm,
75) -> errors::Result<(EllipticCurve, Vec<u8>, Vec<u8>)> {
76 let privkey = Privkey::load_der(key_content).map_err(|_| ErrorKind::InvalidEcdsaKey)?;
77 let x = privkey
78 .get_field("public_x")
79 .map_err(|e| ErrorKind::Provider(e.to_string()))?
80 .to_bin()
81 .map_err(|e| ErrorKind::Provider(e.to_string()))?;
82 let y = privkey
83 .get_field("public_y")
84 .map_err(|e| ErrorKind::Provider(e.to_string()))?
85 .to_bin()
86 .map_err(|e| ErrorKind::Provider(e.to_string()))?;
87
88 match alg {
89 Algorithm::ES256 => Ok((EllipticCurve::P256, x, y)),
90 Algorithm::ES384 => Ok((EllipticCurve::P384, x, y)),
91 _ => Err(ErrorKind::InvalidEcdsaKey.into()),
92 }
93}
94
95fn compute_digest(data: &[u8], hash_function: ThumbprintHash) -> Vec<u8> {
96 let algo = match hash_function {
97 ThumbprintHash::SHA256 => "SHA-256",
98 ThumbprintHash::SHA384 => "SHA-384",
99 ThumbprintHash::SHA512 => "SHA-512",
100 };
101
102 let mut hash_function =
103 HashFunction::new(algo).expect("Constructing botan hash function must work");
104 hash_function
105 .update(data)
106 .expect("Updating botan hash function must work");
107 hash_function
108 .finish()
109 .expect("Finishing botan hash function must work")
110}
111
112pub static DEFAULT_PROVIDER: CryptoProvider = CryptoProvider {
114 signer_factory: new_signer,
115 verifier_factory: new_verifier,
116 jwk_utils: JwkUtils {
117 extract_rsa_public_key_components,
118 extract_ec_public_key_coordinates,
119 compute_digest,
120 },
121};
122
123pub fn install_default() -> Result<(), &'static CryptoProvider> {
125 DEFAULT_PROVIDER.install_default()
126}