jsonwebtoken_rustcrypto/crypto/
mod.rs1use hmac::{Hmac, Mac};
2
3use crate::algorithms::Algorithm;
4use crate::decoding::DecodingKey;
5use crate::encoding::EncodingKey;
6use crate::errors::{new_error, ErrorKind, Result};
7use crate::serialization::{b64_decode, b64_encode};
8
9use sha2::{Sha256, Sha384, Sha512};
10pub(crate) mod rsa;
12
13type HmacSha256 = Hmac<Sha256>;
14type HmacSha384 = Hmac<Sha384>;
15type HmacSha512 = Hmac<Sha512>;
16pub(crate) fn sign_hmac(alg: Algorithm, key: &[u8], message: &str) -> Result<String> {
19 let digest = match alg {
23 Algorithm::HS256 => {
24 let mut mac = HmacSha256::new_from_slice(key).unwrap();
25 mac.update(message.as_bytes());
26 b64_encode(mac.finalize().into_bytes().as_slice())
27 }
28 Algorithm::HS384 => {
29 let mut mac = HmacSha384::new_from_slice(key).unwrap();
30 mac.update(message.as_bytes());
31 b64_encode(mac.finalize().into_bytes().as_slice())
32 }
33 Algorithm::HS512 => {
34 let mut mac = HmacSha512::new_from_slice(key).unwrap();
35 mac.update(message.as_bytes());
36 b64_encode(mac.finalize().into_bytes().as_slice())
37 }
38 _ => unreachable!(),
39 };
40 Ok(digest)
41}
42
43pub fn validate_matching_key(key: &EncodingKey, algorithm: Algorithm) -> Result<()> {
45 match key {
46 EncodingKey::Hmac(_) => match algorithm {
47 Algorithm::HS256 => Ok(()),
48 Algorithm::HS384 => Ok(()),
49 Algorithm::HS512 => Ok(()),
50 _ => Err(ErrorKind::InvalidAlgorithm.into()),
51 },
52 EncodingKey::Rsa(_) => match algorithm {
53 Algorithm::RS256
54 | Algorithm::PS256
55 | Algorithm::PS384
56 | Algorithm::PS512
57 | Algorithm::RS384
58 | Algorithm::RS512 => Ok(()),
59 _ => Err(ErrorKind::InvalidAlgorithm.into()),
60 },
61 }
67}
68
69pub fn sign(message: &str, key: &EncodingKey, algorithm: Algorithm) -> Result<String> {
74 match key {
75 EncodingKey::Hmac(s) => match algorithm {
76 Algorithm::HS256 => sign_hmac(Algorithm::HS256, s, message),
77 Algorithm::HS384 => sign_hmac(Algorithm::HS384, s, message),
78 Algorithm::HS512 => sign_hmac(Algorithm::HS512, s, message),
79 _ => Err(ErrorKind::InvalidAlgorithm.into()),
80 },
81
82 EncodingKey::Rsa(k) => match algorithm {
83 Algorithm::RS256
84 | Algorithm::RS384
85 | Algorithm::RS512
86 | Algorithm::PS256
87 | Algorithm::PS384
88 | Algorithm::PS512 => rsa::sign(algorithm, k, message),
89 _ => Err(ErrorKind::InvalidAlgorithm.into()),
90 },
91 }
99}
100
101pub fn verify(
110 signature: &str,
111 message: &str,
112 key: &DecodingKey,
113 algorithm: Algorithm,
114) -> Result<bool> {
115 match key {
116 DecodingKey::Hmac(s) => match algorithm {
117 Algorithm::HS256 => {
118 let mut mac = HmacSha256::new_from_slice(s).unwrap();
119 mac.update(message.as_bytes());
120 Ok(mac.finalize().into_bytes().as_slice()
121 == b64_decode(signature)
122 .map_err(|_e| new_error(ErrorKind::InvalidSignature))?)
123 }
124 Algorithm::HS384 => {
125 let mut mac = HmacSha384::new_from_slice(s).unwrap();
126 mac.update(message.as_bytes());
127 Ok(mac.finalize().into_bytes().as_slice()
128 == b64_decode(signature)
129 .map_err(|_e| new_error(ErrorKind::InvalidSignature))?)
130 }
131 Algorithm::HS512 => {
132 let mut mac = HmacSha512::new_from_slice(s).unwrap();
133 mac.update(message.as_bytes());
134 Ok(mac.finalize().into_bytes().as_slice()
135 == b64_decode(signature)
136 .map_err(|_e| new_error(ErrorKind::InvalidSignature))?)
137 }
138 _ => Err(ErrorKind::InvalidAlgorithm.into()),
139 },
140 DecodingKey::Rsa(k) => match algorithm {
141 Algorithm::RS256
142 | Algorithm::RS384
143 | Algorithm::RS512
144 | Algorithm::PS256
145 | Algorithm::PS384
146 | Algorithm::PS512 => rsa::verify(algorithm, signature, message, k),
147 _ => Err(ErrorKind::InvalidAlgorithm.into()),
148 },
149 }
150}