1 use ring::constant_time::verify_slices_are_equal;
2 use ring::{hmac, signature};
3 
4 use crate::algorithms::Algorithm;
5 use crate::decoding::{DecodingKey, DecodingKeyKind};
6 use crate::encoding::EncodingKey;
7 use crate::errors::Result;
8 use crate::serialization::{b64_decode, b64_encode};
9 
10 pub(crate) mod ecdsa;
11 pub(crate) mod rsa;
12 
13 /// The actual HS signing + encoding
14 /// Could be in its own file to match RSA/EC but it's 2 lines...
sign_hmac(alg: hmac::Algorithm, key: &[u8], message: &str) -> Result<String>15 pub(crate) fn sign_hmac(alg: hmac::Algorithm, key: &[u8], message: &str) -> Result<String> {
16     let digest = hmac::sign(&hmac::Key::new(alg, key), message.as_bytes());
17     Ok(b64_encode(digest.as_ref()))
18 }
19 
20 /// Take the payload of a JWT, sign it using the algorithm given and return
21 /// the base64 url safe encoded of the result.
22 ///
23 /// If you just want to encode a JWT, use `encode` instead.
sign(message: &str, key: &EncodingKey, algorithm: Algorithm) -> Result<String>24 pub fn sign(message: &str, key: &EncodingKey, algorithm: Algorithm) -> Result<String> {
25     match algorithm {
26         Algorithm::HS256 => sign_hmac(hmac::HMAC_SHA256, key.inner(), message),
27         Algorithm::HS384 => sign_hmac(hmac::HMAC_SHA384, key.inner(), message),
28         Algorithm::HS512 => sign_hmac(hmac::HMAC_SHA512, key.inner(), message),
29 
30         Algorithm::ES256 | Algorithm::ES384 => {
31             ecdsa::sign(ecdsa::alg_to_ec_signing(algorithm), key.inner(), message)
32         }
33 
34         Algorithm::RS256
35         | Algorithm::RS384
36         | Algorithm::RS512
37         | Algorithm::PS256
38         | Algorithm::PS384
39         | Algorithm::PS512 => rsa::sign(rsa::alg_to_rsa_signing(algorithm), key.inner(), message),
40     }
41 }
42 
43 /// See Ring docs for more details
verify_ring( alg: &'static dyn signature::VerificationAlgorithm, signature: &str, message: &str, key: &[u8], ) -> Result<bool>44 fn verify_ring(
45     alg: &'static dyn signature::VerificationAlgorithm,
46     signature: &str,
47     message: &str,
48     key: &[u8],
49 ) -> Result<bool> {
50     let signature_bytes = b64_decode(signature)?;
51     let public_key = signature::UnparsedPublicKey::new(alg, key);
52     let res = public_key.verify(message.as_bytes(), &signature_bytes);
53 
54     Ok(res.is_ok())
55 }
56 
57 /// Compares the signature given with a re-computed signature for HMAC or using the public key
58 /// for RSA/EC.
59 ///
60 /// If you just want to decode a JWT, use `decode` instead.
61 ///
62 /// `signature` is the signature part of a jwt (text after the second '.')
63 ///
64 /// `message` is base64(header) + "." + base64(claims)
verify( signature: &str, message: &str, key: &DecodingKey, algorithm: Algorithm, ) -> Result<bool>65 pub fn verify(
66     signature: &str,
67     message: &str,
68     key: &DecodingKey,
69     algorithm: Algorithm,
70 ) -> Result<bool> {
71     match algorithm {
72         Algorithm::HS256 | Algorithm::HS384 | Algorithm::HS512 => {
73             // we just re-sign the message with the key and compare if they are equal
74             let signed = sign(message, &EncodingKey::from_secret(key.as_bytes()), algorithm)?;
75             Ok(verify_slices_are_equal(signature.as_ref(), signed.as_ref()).is_ok())
76         }
77         Algorithm::ES256 | Algorithm::ES384 => verify_ring(
78             ecdsa::alg_to_ec_verification(algorithm),
79             signature,
80             message,
81             key.as_bytes(),
82         ),
83         Algorithm::RS256
84         | Algorithm::RS384
85         | Algorithm::RS512
86         | Algorithm::PS256
87         | Algorithm::PS384
88         | Algorithm::PS512 => {
89             let alg = rsa::alg_to_rsa_parameters(algorithm);
90             match &key.kind {
91                 DecodingKeyKind::SecretOrDer(bytes) => verify_ring(alg, signature, message, bytes),
92                 DecodingKeyKind::RsaModulusExponent { n, e } => {
93                     rsa::verify_from_components(alg, signature, message, (n, e))
94                 }
95             }
96         }
97     }
98 }
99