1use crate::validation::validate_header;
2use crate::{
3 pem::PemEncodedKey, validation::validate, Algorithm, Error, Header, SecretKey,
4 ValidationOptions, VerifyingKey,
5};
6use base64::Engine;
7use ecdsa::der::Signature as EcdsaDerSignature;
8use hmac::{Hmac, Mac};
9use k256::ecdsa::VerifyingKey as K256VerifyingKey;
10use p256::ecdsa::VerifyingKey as P256VerifyingKey;
11use p384::ecdsa::VerifyingKey as P384VerifyingKey;
12use p521::ecdsa::VerifyingKey as P521VerifyingKey;
13use rsa::signature::Verifier as RsaVerifier;
14use rsa::{
15 pkcs1v15::Signature as Pkcs1v15Signature, pkcs1v15::VerifyingKey as Pkcs1v15VerifyingKey,
16 pss::VerifyingKey as PssVerifyingKey,
17};
18use serde_json::Value as JsonValue;
19use sha2::{Sha256, Sha384, Sha512};
20use simple_asn1::{to_der, ASN1Block, BigUint};
21
22#[derive(Debug, Clone)]
23pub struct DecodedJwt {
24 pub header: Header,
25 pub payload: JsonValue,
26}
27
28pub fn decode(
41 token: &str,
42 verifying_key: &VerifyingKey,
43 validation_options: &ValidationOptions,
44) -> Result<DecodedJwt, Error> {
45 let (header, payload, signature) = split_jwt(token)?;
46
47 validate_header(&header, validation_options)?;
48
49 let signing_input = format!(
50 "{}.{}",
51 token.split('.').collect::<Vec<&str>>()[0],
52 token.split('.').collect::<Vec<&str>>()[1]
53 );
54 verify_signature(&signing_input, &signature, &header.alg, verifying_key)
55 .map_err(|_| Error::InvalidSignature)?;
56 validate(
57 payload.as_object().ok_or(Error::InvalidKeyFormat)?,
58 validation_options,
59 )?;
60
61 Ok(DecodedJwt { header, payload })
62}
63
64pub fn decode_only(token: &str) -> Result<DecodedJwt, Error> {
76 let (header, payload, _) = split_jwt(token)?;
77 Ok(DecodedJwt { header, payload })
78}
79
80fn split_jwt(token: &str) -> Result<(Header, JsonValue, Vec<u8>), Error> {
81 let parts: Vec<&str> = token.split('.').collect();
82 if parts.len() != 3 {
83 return Err(Error::InvalidKeyFormat);
84 }
85
86 let header_data = base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(parts[0])?;
87 let payload_data = base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(parts[1])?;
88 let signature = base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(parts[2])?;
89
90 let header: Header = serde_json::from_slice(&header_data)?;
91 let payload: JsonValue = serde_json::from_slice(&payload_data)?;
92
93 Ok((header, payload, signature))
94}
95
96fn verify_signature(
109 signing_input: &str,
110 signature: &[u8],
111 alg: &Algorithm,
112 verifying_key: &VerifyingKey,
113) -> Result<(), Error> {
114 match verifying_key {
115 VerifyingKey::Secret(secret) => match alg {
116 Algorithm::HS256 | Algorithm::HS384 | Algorithm::HS512 => {
117 verify_hmac(signing_input, signature, secret, alg)
118 }
119 _ => Err(Error::UnsupportedAlgorithm),
120 },
121 VerifyingKey::RsaKey(rsa_key) => match alg {
122 Algorithm::RS256 | Algorithm::RS384 | Algorithm::RS512 => {
123 verify_rsa(signing_input, signature, rsa_key, alg)
124 }
125 Algorithm::PS256 | Algorithm::PS384 | Algorithm::PS512 => {
126 verify_pss(signing_input, signature, rsa_key, alg)
127 }
128 _ => Err(Error::UnsupportedAlgorithm),
129 },
130 VerifyingKey::EcKey(ec_key) => match alg {
131 Algorithm::ES256 | Algorithm::ES256K | Algorithm::ES384 | Algorithm::ES512 => {
132 verify_ecdsa(signing_input, signature, ec_key, alg)
133 }
134 _ => Err(Error::UnsupportedAlgorithm),
135 },
136 _ => Err(Error::UnsupportedAlgorithm),
137 }
138}
139
140fn verify_rsa(
142 signing_input: &str,
143 signature: &[u8],
144 rsa_key: &PemEncodedKey,
145 alg: &Algorithm,
146) -> Result<(), Error> {
147 let rsa_public_key = rsa_key.as_rsa_public_key()?;
148 let pkcs1_signature = Pkcs1v15Signature::try_from(signature)?;
149 match alg {
150 Algorithm::RS256 => {
151 let verifying_key = Pkcs1v15VerifyingKey::<sha2::Sha256>::new(rsa_public_key);
152 verifying_key.verify(signing_input.as_bytes(), &pkcs1_signature)?;
153 }
154 Algorithm::RS384 => {
155 let verifying_key = Pkcs1v15VerifyingKey::<sha2::Sha384>::new(rsa_public_key);
156 verifying_key.verify(signing_input.as_bytes(), &pkcs1_signature)?;
157 }
158 Algorithm::RS512 => {
159 let verifying_key = Pkcs1v15VerifyingKey::<sha2::Sha512>::new(rsa_public_key);
160 verifying_key.verify(signing_input.as_bytes(), &pkcs1_signature)?;
161 }
162 _ => return Err(Error::UnsupportedAlgorithm),
163 };
164
165 Ok(())
166}
167
168fn verify_pss(
170 signing_input: &str,
171 signature: &[u8],
172 rsa_key: &PemEncodedKey,
173 alg: &Algorithm,
174) -> Result<(), Error> {
175 let rsa_public_key = rsa_key.as_rsa_public_key()?;
176 let pss_signature = rsa::pss::Signature::try_from(signature)?;
177
178 match alg {
179 Algorithm::PS256 => {
180 let verifying_key = PssVerifyingKey::<sha2::Sha256>::new(rsa_public_key);
181 verifying_key.verify(signing_input.as_bytes(), &pss_signature)?
182 }
183 Algorithm::PS384 => {
184 let verifying_key = PssVerifyingKey::<sha2::Sha384>::new(rsa_public_key);
185 verifying_key.verify(signing_input.as_bytes(), &pss_signature)?
186 }
187 Algorithm::PS512 => {
188 let veryfing_key = PssVerifyingKey::<sha2::Sha512>::new(rsa_public_key);
189 veryfing_key.verify(signing_input.as_bytes(), &pss_signature)?
190 }
191 _ => {
192 return Err(Error::UnsupportedAlgorithm);
193 }
194 };
195
196 Ok(())
197}
198
199fn verify_hmac(
201 signing_input: &str,
202 signature: &[u8],
203 secret: &SecretKey,
204 alg: &Algorithm,
205) -> Result<(), Error> {
206 let key = secret.inner();
207 let computed_signature = match alg {
208 Algorithm::HS256 => {
209 let mut hmac = Hmac::<Sha256>::new_from_slice(key)?;
210 hmac.update(signing_input.as_bytes());
211 hmac.finalize().into_bytes().to_vec()
212 }
213 Algorithm::HS384 => {
214 let mut hmac = Hmac::<Sha384>::new_from_slice(key)?;
215 hmac.update(signing_input.as_bytes());
216 hmac.finalize().into_bytes().to_vec()
217 }
218 Algorithm::HS512 => {
219 let mut hmac = Hmac::<Sha512>::new_from_slice(key)?;
220 hmac.update(signing_input.as_bytes());
221 hmac.finalize().into_bytes().to_vec()
222 }
223 _ => return Err(Error::UnsupportedAlgorithm),
224 };
225
226 if computed_signature == signature {
227 Ok(())
228 } else {
229 Err(Error::InvalidSignature)
230 }
231}
232
233fn verify_ecdsa(
235 signing_input: &str,
236 signature: &[u8],
237 ec_key: &PemEncodedKey,
238 alg: &Algorithm,
239) -> Result<(), Error> {
240 let public_key_bytes = ec_key.as_ec_public_key()?;
241
242 match alg {
243 Algorithm::ES256 => {
244 let verifying_key = P256VerifyingKey::from_sec1_bytes(public_key_bytes)
245 .map_err(|_| Error::InvalidEcdsaKey)?;
246 let ecdsa_signature_vec = determine_signature_type(signature, 64);
247 let ecdsa_signature = EcdsaDerSignature::from_bytes(&ecdsa_signature_vec)?;
248 verifying_key
249 .verify(signing_input.as_bytes(), &ecdsa_signature)
250 .map_err(|_| Error::InvalidSignature)
251 }
252 Algorithm::ES256K => {
253 let verifying_key = K256VerifyingKey::from_sec1_bytes(public_key_bytes)
254 .map_err(|_| Error::InvalidEcdsaKey)?;
255 let ecdsa_signature_vec = determine_signature_type(signature, 64);
256 let ecdsa_signature = EcdsaDerSignature::from_bytes(&ecdsa_signature_vec)?;
257 verifying_key
258 .verify(signing_input.as_bytes(), &ecdsa_signature)
259 .map_err(|_| Error::InvalidSignature)
260 }
261 Algorithm::ES384 => {
262 let verifying_key = P384VerifyingKey::from_sec1_bytes(public_key_bytes)
263 .map_err(|_| Error::InvalidEcdsaKey)?;
264 let ecdsa_signature_vec = determine_signature_type(signature, 96);
265 let ecdsa_signature = EcdsaDerSignature::from_bytes(&ecdsa_signature_vec)?;
266 verifying_key
267 .verify(signing_input.as_bytes(), &ecdsa_signature)
268 .map_err(|_| Error::InvalidSignature)
269 }
270 Algorithm::ES512 => {
271 let verifying_key = P521VerifyingKey::from_sec1_bytes(public_key_bytes)
272 .map_err(|_| Error::InvalidEcdsaKey)?;
273 let ecdsa_signature_vec = determine_signature_type(signature, 132);
274 let ecdsa_signature = EcdsaDerSignature::from_bytes(&ecdsa_signature_vec)?;
275 verifying_key
276 .verify(signing_input.as_bytes(), &ecdsa_signature.try_into()?)
277 .map_err(|_| Error::InvalidSignature)
278 }
279 _ => Err(Error::UnsupportedAlgorithm),
280 }
281}
282
283fn determine_signature_type(signature: &[u8], signature_len: usize) -> Vec<u8> {
284 if signature.len() == signature_len {
286 let r = &signature[..signature_len / 2];
287 let s = &signature[signature_len / 2..];
288
289 let asn1_signature = ASN1Block::Sequence(
290 0,
291 vec![
292 ASN1Block::Integer(0, BigUint::from_bytes_be(r).into()),
293 ASN1Block::Integer(0, BigUint::from_bytes_be(s).into()),
294 ],
295 );
296
297 to_der(&asn1_signature).unwrap()
298 } else {
299 signature.to_vec()
300 }
301}