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