@@ -7,7 +7,7 @@ use crate::Algorithm;
77use crate :: algorithms:: AlgorithmFamily ;
88use crate :: crypto:: JwtVerifier ;
99use crate :: errors:: { ErrorKind , Result , new_error} ;
10- use crate :: header:: Header ;
10+ use crate :: header:: { Alg , FromEncoded , Header } ;
1111use crate :: jwk:: { AlgorithmParameters , Jwk } ;
1212#[ cfg( feature = "use_pem" ) ]
1313use crate :: pem:: decoder:: PemEncodedKey ;
@@ -37,15 +37,16 @@ use crate::crypto::rust_crypto::{
3737
3838/// The return type of a successful call to [decode](fn.decode.html).
3939#[ derive( Debug ) ]
40- pub struct TokenData < T > {
40+ pub struct TokenData < H , T > {
4141 /// The decoded JWT header
42- pub header : Header ,
42+ pub header : H ,
4343 /// The decoded JWT claims
4444 pub claims : T ,
4545}
4646
47- impl < T > Clone for TokenData < T >
47+ impl < H , T > Clone for TokenData < H , T >
4848where
49+ H : Clone ,
4950 T : Clone ,
5051{
5152 fn clone ( & self ) -> Self {
@@ -281,21 +282,40 @@ pub fn decode<T: DeserializeOwned + Clone>(
281282 token : impl AsRef < [ u8 ] > ,
282283 key : & DecodingKey ,
283284 validation : & Validation ,
284- ) -> Result < TokenData < T > > {
285+ ) -> Result < TokenData < Header , T > > {
286+ decode_with_custom_header ( token, key, validation)
287+ }
288+
289+ /// Decode and validate a JWT with a custom header
290+ ///
291+ /// If the token or its signature is invalid, or the claims fail validation, this will return an
292+ /// error.
293+ pub fn decode_with_custom_header < H , T > (
294+ token : impl AsRef < [ u8 ] > ,
295+ key : & DecodingKey ,
296+ validation : & Validation ,
297+ ) -> Result < TokenData < H , T > >
298+ where
299+ H : DeserializeOwned + Clone + FromEncoded + Alg ,
300+ T : DeserializeOwned + Clone ,
301+ {
285302 let token = token. as_ref ( ) ;
286- let header = decode_header ( token) ?;
287303
288- if validation. validate_signature && !validation. algorithms . contains ( & header. alg ) {
304+ let ( signature, message) = expect_two ! ( token. rsplitn( 2 , |b| * b == b'.' ) ) ;
305+ let ( payload, header) = expect_two ! ( message. rsplitn( 2 , |b| * b == b'.' ) ) ;
306+ let header = H :: from_encoded ( header) ?;
307+
308+ if validation. validate_signature && !validation. algorithms . contains ( header. alg ( ) ) {
289309 return Err ( new_error ( ErrorKind :: InvalidAlgorithm ) ) ;
290310 }
291311
292- let verifying_provider = jwt_verifier_factory ( & header. alg , key) ?;
312+ let verifying_provider = jwt_verifier_factory ( header. alg ( ) , key) ?;
313+ verify_signature_body ( message, signature, & header, validation, verifying_provider) ?;
293314
294- let ( header, claims) = verify_signature ( token, validation, verifying_provider) ?;
315+ let decoded_claims = DecodedJwtPartClaims :: from_jwt_part_claims ( payload) ?;
316+ validate ( decoded_claims. deserialize ( ) ?, validation) ?;
295317
296- let decoded_claims = DecodedJwtPartClaims :: from_jwt_part_claims ( claims) ?;
297318 let claims = decoded_claims. deserialize ( ) ?;
298- validate ( decoded_claims. deserialize ( ) ?, validation) ?;
299319
300320 Ok ( TokenData { header, claims } )
301321}
@@ -357,10 +377,21 @@ pub fn decode_header(token: impl AsRef<[u8]>) -> Result<Header> {
357377 Header :: from_encoded ( header)
358378}
359379
380+ /// Decode only the custom header of a JWT without decoding or validating the payload
381+ pub fn decode_custom_header < H > ( token : impl AsRef < [ u8 ] > ) -> Result < H >
382+ where
383+ H : DeserializeOwned + Clone + Alg + FromEncoded ,
384+ {
385+ let token = token. as_ref ( ) ;
386+ let ( _, message) = expect_two ! ( token. rsplitn( 2 , |b| * b == b'.' ) ) ;
387+ let ( _, header) = expect_two ! ( message. rsplitn( 2 , |b| * b == b'.' ) ) ;
388+ H :: from_encoded ( header)
389+ }
390+
360391pub ( crate ) fn verify_signature_body (
361392 message : & [ u8 ] ,
362393 signature : & [ u8 ] ,
363- header : & Header ,
394+ header : & impl Alg ,
364395 validation : & Validation ,
365396 verifying_provider : Box < dyn JwtVerifier > ,
366397) -> Result < ( ) > {
@@ -376,7 +407,7 @@ pub(crate) fn verify_signature_body(
376407 }
377408 }
378409
379- if validation. validate_signature && !validation. algorithms . contains ( & header. alg ) {
410+ if validation. validate_signature && !validation. algorithms . contains ( header. alg ( ) ) {
380411 return Err ( new_error ( ErrorKind :: InvalidAlgorithm ) ) ;
381412 }
382413
@@ -388,19 +419,3 @@ pub(crate) fn verify_signature_body(
388419
389420 Ok ( ( ) )
390421}
391-
392- /// Verify the signature of a JWT, and return a header object and raw payload.
393- ///
394- /// If the token or its signature is invalid, it will return an error.
395- fn verify_signature < ' a > (
396- token : & ' a [ u8 ] ,
397- validation : & Validation ,
398- verifying_provider : Box < dyn JwtVerifier > ,
399- ) -> Result < ( Header , & ' a [ u8 ] ) > {
400- let ( signature, message) = expect_two ! ( token. rsplitn( 2 , |b| * b == b'.' ) ) ;
401- let ( payload, header) = expect_two ! ( message. rsplitn( 2 , |b| * b == b'.' ) ) ;
402- let header = Header :: from_encoded ( header) ?;
403- verify_signature_body ( message, signature, & header, validation, verifying_provider) ?;
404-
405- Ok ( ( header, payload) )
406- }
0 commit comments