Skip to main content

jsonwebtoken/crypto/aws_lc/
mod.rs

1use aws_lc_rs::{
2    digest,
3    signature::{
4        self as aws_sig, ECDSA_P256_SHA256_FIXED_SIGNING, ECDSA_P384_SHA384_FIXED_SIGNING,
5        EcdsaKeyPair, KeyPair,
6    },
7};
8
9use crate::{
10    Algorithm, DecodingKey, EncodingKey,
11    crypto::{CryptoProvider, JwkUtils, JwtSigner, JwtVerifier},
12    errors::{self, Error, ErrorKind},
13    jwk::{EllipticCurve, ThumbprintHash},
14};
15
16mod ecdsa;
17mod eddsa;
18mod hmac;
19mod rsa;
20
21fn extract_rsa_public_key_components(key_content: &[u8]) -> errors::Result<(Vec<u8>, Vec<u8>)> {
22    let key_pair = aws_sig::RsaKeyPair::from_der(key_content)
23        .map_err(|e| ErrorKind::InvalidRsaKey(e.to_string()))?;
24    let public = key_pair.public_key();
25    let components = aws_sig::RsaPublicKeyComponents::<Vec<u8>>::from(public);
26    Ok((components.n, components.e))
27}
28
29fn extract_ec_public_key_coordinates(
30    key_content: &[u8],
31    alg: Algorithm,
32) -> errors::Result<(EllipticCurve, Vec<u8>, Vec<u8>)> {
33    let (signing_alg, curve, pub_elem_bytes) = match alg {
34        Algorithm::ES256 => (&ECDSA_P256_SHA256_FIXED_SIGNING, EllipticCurve::P256, 32),
35        Algorithm::ES384 => (&ECDSA_P384_SHA384_FIXED_SIGNING, EllipticCurve::P384, 48),
36        _ => return Err(ErrorKind::InvalidEcdsaKey.into()),
37    };
38
39    let key_pair = EcdsaKeyPair::from_pkcs8(signing_alg, key_content)
40        .map_err(|_| ErrorKind::InvalidEcdsaKey)?;
41
42    let pub_bytes = key_pair.public_key().as_ref();
43    if pub_bytes[0] != 4 {
44        return Err(ErrorKind::InvalidEcdsaKey.into());
45    }
46
47    let (x, y) = pub_bytes[1..].split_at(pub_elem_bytes);
48    Ok((curve, x.to_vec(), y.to_vec()))
49}
50
51fn compute_digest(data: &[u8], hash_function: ThumbprintHash) -> Vec<u8> {
52    let algorithm = match hash_function {
53        ThumbprintHash::SHA256 => &digest::SHA256,
54        ThumbprintHash::SHA384 => &digest::SHA384,
55        ThumbprintHash::SHA512 => &digest::SHA512,
56    };
57    digest::digest(algorithm, data).as_ref().to_vec()
58}
59
60fn new_signer(algorithm: &Algorithm, key: &EncodingKey) -> Result<Box<dyn JwtSigner>, Error> {
61    let jwt_signer = match algorithm {
62        Algorithm::HS256 => Box::new(hmac::Hs256Signer::new(key)?) as Box<dyn JwtSigner>,
63        Algorithm::HS384 => Box::new(hmac::Hs384Signer::new(key)?) as Box<dyn JwtSigner>,
64        Algorithm::HS512 => Box::new(hmac::Hs512Signer::new(key)?) as Box<dyn JwtSigner>,
65        Algorithm::ES256 => Box::new(ecdsa::Es256Signer::new(key)?) as Box<dyn JwtSigner>,
66        Algorithm::ES384 => Box::new(ecdsa::Es384Signer::new(key)?) as Box<dyn JwtSigner>,
67        Algorithm::RS256 => Box::new(rsa::Rsa256Signer::new(key)?) as Box<dyn JwtSigner>,
68        Algorithm::RS384 => Box::new(rsa::Rsa384Signer::new(key)?) as Box<dyn JwtSigner>,
69        Algorithm::RS512 => Box::new(rsa::Rsa512Signer::new(key)?) as Box<dyn JwtSigner>,
70        Algorithm::PS256 => Box::new(rsa::RsaPss256Signer::new(key)?) as Box<dyn JwtSigner>,
71        Algorithm::PS384 => Box::new(rsa::RsaPss384Signer::new(key)?) as Box<dyn JwtSigner>,
72        Algorithm::PS512 => Box::new(rsa::RsaPss512Signer::new(key)?) as Box<dyn JwtSigner>,
73        Algorithm::EdDSA => Box::new(eddsa::EdDSASigner::new(key)?) as Box<dyn JwtSigner>,
74    };
75
76    Ok(jwt_signer)
77}
78
79fn new_verifier(
80    algorithm: &Algorithm,
81    key: &DecodingKey,
82) -> Result<Box<dyn super::JwtVerifier>, Error> {
83    let jwt_verifier = match algorithm {
84        Algorithm::HS256 => Box::new(hmac::Hs256Verifier::new(key)?) as Box<dyn JwtVerifier>,
85        Algorithm::HS384 => Box::new(hmac::Hs384Verifier::new(key)?) as Box<dyn JwtVerifier>,
86        Algorithm::HS512 => Box::new(hmac::Hs512Verifier::new(key)?) as Box<dyn JwtVerifier>,
87        Algorithm::ES256 => Box::new(ecdsa::Es256Verifier::new(key)?) as Box<dyn JwtVerifier>,
88        Algorithm::ES384 => Box::new(ecdsa::Es384Verifier::new(key)?) as Box<dyn JwtVerifier>,
89        Algorithm::RS256 => Box::new(rsa::Rsa256Verifier::new(key)?) as Box<dyn JwtVerifier>,
90        Algorithm::RS384 => Box::new(rsa::Rsa384Verifier::new(key)?) as Box<dyn JwtVerifier>,
91        Algorithm::RS512 => Box::new(rsa::Rsa512Verifier::new(key)?) as Box<dyn JwtVerifier>,
92        Algorithm::PS256 => Box::new(rsa::RsaPss256Verifier::new(key)?) as Box<dyn JwtVerifier>,
93        Algorithm::PS384 => Box::new(rsa::RsaPss384Verifier::new(key)?) as Box<dyn JwtVerifier>,
94        Algorithm::PS512 => Box::new(rsa::RsaPss512Verifier::new(key)?) as Box<dyn JwtVerifier>,
95        Algorithm::EdDSA => Box::new(eddsa::EdDSAVerifier::new(key)?) as Box<dyn JwtVerifier>,
96    };
97
98    Ok(jwt_verifier)
99}
100
101/// The default [`CryptoProvider`] backed by [`aws_lc_rs`].
102pub static DEFAULT_PROVIDER: CryptoProvider = CryptoProvider {
103    signer_factory: new_signer,
104    verifier_factory: new_verifier,
105    jwk_utils: JwkUtils {
106        extract_rsa_public_key_components,
107        extract_ec_public_key_coordinates,
108        compute_digest,
109    },
110};