@@ -6,6 +6,7 @@ use crate::crypto::verify;
6
6
use crate :: errors:: { new_error, ErrorKind , Result } ;
7
7
use crate :: header:: Header ;
8
8
use crate :: jwk:: { AlgorithmParameters , Jwk } ;
9
+ use crate :: jws:: Jws ;
9
10
#[ cfg( feature = "use_pem" ) ]
10
11
use crate :: pem:: decoder:: PemEncodedKey ;
11
12
use crate :: serialization:: { b64_decode, DecodedJwtPartClaims } ;
@@ -286,3 +287,58 @@ pub fn decode_header(token: &str) -> Result<Header> {
286
287
let ( _, header) = expect_two ! ( message. rsplitn( 2 , '.' ) ) ;
287
288
Header :: from_encoded ( header)
288
289
}
290
+
291
+ /// Verify signature of a JWS, and return the header object
292
+ ///
293
+ /// If the token or its signature is invalid, it will return an error.
294
+ fn verify_jws_signature < T > (
295
+ jws : & Jws < T > ,
296
+ key : & DecodingKey ,
297
+ validation : & Validation ,
298
+ ) -> Result < Header > {
299
+ if validation. validate_signature && validation. algorithms . is_empty ( ) {
300
+ return Err ( new_error ( ErrorKind :: MissingAlgorithm ) ) ;
301
+ }
302
+
303
+ if validation. validate_signature {
304
+ for alg in & validation. algorithms {
305
+ if key. family != alg. family ( ) {
306
+ return Err ( new_error ( ErrorKind :: InvalidAlgorithm ) ) ;
307
+ }
308
+ }
309
+ }
310
+
311
+ let header = Header :: from_encoded ( & jws. protected ) ?;
312
+
313
+ if validation. validate_signature && !validation. algorithms . contains ( & header. alg ) {
314
+ return Err ( new_error ( ErrorKind :: InvalidAlgorithm ) ) ;
315
+ }
316
+
317
+ let message = [ jws. protected . as_str ( ) , jws. payload . as_str ( ) ] . join ( "." ) ;
318
+
319
+ if validation. validate_signature
320
+ && !verify ( & jws. signature , message. as_bytes ( ) , key, header. alg ) ?
321
+ {
322
+ return Err ( new_error ( ErrorKind :: InvalidSignature ) ) ;
323
+ }
324
+
325
+ Ok ( header)
326
+ }
327
+
328
+ /// Validate a received JWS and decode into the header and claims.
329
+ pub fn decode_jws < T : DeserializeOwned > (
330
+ jws : & Jws < T > ,
331
+ key : & DecodingKey ,
332
+ validation : & Validation ,
333
+ ) -> Result < TokenData < T > > {
334
+ match verify_jws_signature ( jws, key, validation) {
335
+ Err ( e) => Err ( e) ,
336
+ Ok ( header) => {
337
+ let decoded_claims = DecodedJwtPartClaims :: from_jwt_part_claims ( & jws. payload ) ?;
338
+ let claims = decoded_claims. deserialize ( ) ?;
339
+ validate ( decoded_claims. deserialize ( ) ?, validation) ?;
340
+
341
+ Ok ( TokenData { header, claims } )
342
+ }
343
+ }
344
+ }
0 commit comments