@@ -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 {
@@ -273,21 +274,40 @@ pub fn decode<T: DeserializeOwned + Clone>(
273274 token : impl AsRef < [ u8 ] > ,
274275 key : & DecodingKey ,
275276 validation : & Validation ,
276- ) -> Result < TokenData < T > > {
277+ ) -> Result < TokenData < Header , T > > {
278+ decode_with_custom_header ( token, key, validation)
279+ }
280+
281+ /// Decode and validate a JWT with a custom header
282+ ///
283+ /// If the token or its signature is invalid, or the claims fail validation, this will return an
284+ /// error.
285+ pub fn decode_with_custom_header < H , T > (
286+ token : impl AsRef < [ u8 ] > ,
287+ key : & DecodingKey ,
288+ validation : & Validation ,
289+ ) -> Result < TokenData < H , T > >
290+ where
291+ H : DeserializeOwned + Clone + FromEncoded + Alg ,
292+ T : DeserializeOwned + Clone ,
293+ {
277294 let token = token. as_ref ( ) ;
278- let header = decode_header ( token) ?;
279295
280- if validation. validate_signature && !validation. algorithms . contains ( & header. alg ) {
296+ let ( signature, message) = expect_two ! ( token. rsplitn( 2 , |b| * b == b'.' ) ) ;
297+ let ( payload, header) = expect_two ! ( message. rsplitn( 2 , |b| * b == b'.' ) ) ;
298+ let header = H :: from_encoded ( header) ?;
299+
300+ if validation. validate_signature && !validation. algorithms . contains ( header. alg ( ) ) {
281301 return Err ( new_error ( ErrorKind :: InvalidAlgorithm ) ) ;
282302 }
283303
284- let verifying_provider = jwt_verifier_factory ( & header. alg , key) ?;
304+ let verifying_provider = jwt_verifier_factory ( header. alg ( ) , key) ?;
305+ verify_signature_body ( message, signature, & header, validation, verifying_provider) ?;
285306
286- let ( header, claims) = verify_signature ( token, validation, verifying_provider) ?;
307+ let decoded_claims = DecodedJwtPartClaims :: from_jwt_part_claims ( payload) ?;
308+ validate ( decoded_claims. deserialize ( ) ?, validation) ?;
287309
288- let decoded_claims = DecodedJwtPartClaims :: from_jwt_part_claims ( claims) ?;
289310 let claims = decoded_claims. deserialize ( ) ?;
290- validate ( decoded_claims. deserialize ( ) ?, validation) ?;
291311
292312 Ok ( TokenData { header, claims } )
293313}
@@ -332,10 +352,21 @@ pub fn decode_header(token: impl AsRef<[u8]>) -> Result<Header> {
332352 Header :: from_encoded ( header)
333353}
334354
355+ /// Decode only the custom header of a JWT without decoding or validating the payload
356+ pub fn decode_custom_header < H > ( token : impl AsRef < [ u8 ] > ) -> Result < H >
357+ where
358+ H : DeserializeOwned + Clone + Alg + FromEncoded ,
359+ {
360+ let token = token. as_ref ( ) ;
361+ let ( _, message) = expect_two ! ( token. rsplitn( 2 , |b| * b == b'.' ) ) ;
362+ let ( _, header) = expect_two ! ( message. rsplitn( 2 , |b| * b == b'.' ) ) ;
363+ H :: from_encoded ( header)
364+ }
365+
335366pub ( crate ) fn verify_signature_body (
336367 message : & [ u8 ] ,
337368 signature : & [ u8 ] ,
338- header : & Header ,
369+ header : & impl Alg ,
339370 validation : & Validation ,
340371 verifying_provider : Box < dyn JwtVerifier > ,
341372) -> Result < ( ) > {
@@ -351,7 +382,7 @@ pub(crate) fn verify_signature_body(
351382 }
352383 }
353384
354- if validation. validate_signature && !validation. algorithms . contains ( & header. alg ) {
385+ if validation. validate_signature && !validation. algorithms . contains ( header. alg ( ) ) {
355386 return Err ( new_error ( ErrorKind :: InvalidAlgorithm ) ) ;
356387 }
357388
@@ -363,19 +394,3 @@ pub(crate) fn verify_signature_body(
363394
364395 Ok ( ( ) )
365396}
366-
367- /// Verify the signature of a JWT, and return a header object and raw payload.
368- ///
369- /// If the token or its signature is invalid, it will return an error.
370- fn verify_signature < ' a > (
371- token : & ' a [ u8 ] ,
372- validation : & Validation ,
373- verifying_provider : Box < dyn JwtVerifier > ,
374- ) -> Result < ( Header , & ' a [ u8 ] ) > {
375- let ( signature, message) = expect_two ! ( token. rsplitn( 2 , |b| * b == b'.' ) ) ;
376- let ( payload, header) = expect_two ! ( message. rsplitn( 2 , |b| * b == b'.' ) ) ;
377- let header = Header :: from_encoded ( header) ?;
378- verify_signature_body ( message, signature, & header, validation, verifying_provider) ?;
379-
380- Ok ( ( header, payload) )
381- }
0 commit comments