@@ -6,6 +6,7 @@ use crate::crypto::verify;
66use crate :: errors:: { new_error, ErrorKind , Result } ;
77use crate :: header:: Header ;
88use crate :: jwk:: { AlgorithmParameters , Jwk } ;
9+ use crate :: jws:: Jws ;
910#[ cfg( feature = "use_pem" ) ]
1011use crate :: pem:: decoder:: PemEncodedKey ;
1112use crate :: serialization:: { b64_decode, DecodedJwtPartClaims } ;
@@ -286,3 +287,58 @@ pub fn decode_header(token: &str) -> Result<Header> {
286287 let ( _, header) = expect_two ! ( message. rsplitn( 2 , '.' ) ) ;
287288 Header :: from_encoded ( header)
288289}
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