Skip to content

Exception in evaluating iat in PAR requests #498

@peppelinux

Description

@peppelinux

Sometimes the exception above happen when all the tests are executed (pytest -vvv -x). It doesn't seem to happen when that single test is executed (pytest -vvv -x -k test_valid_request)

par_handler = <pyeudiw.satosa.frontends.openid4vci.endpoints.pushed_authorization_request_endpoint.ParHandler object at 0x79bd685fcb50>
context = <satosa.context.Context object at 0x79bd685fe080>

    def test_valid_request(par_handler, context):
>       _assert_valid_request(par_handler, context)

pyeudiw/tests/satosa/frontends/openid4vci/endpoints/test_pushed_authorization_request_endpoint.py:249: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

par_handler = <pyeudiw.satosa.frontends.openid4vci.endpoints.pushed_authorization_request_endpoint.ParHandler object at 0x79bd685fcb50>
context = <satosa.context.Context object at 0x79bd685fe080>

    def _assert_valid_request(par_handler: ParHandler, context: Context):
        with (patch(JWS_HELPER_VERIFY_MODULE, return_value = _mock_request_deserialized()),
              patch(_PAR_VALIDATE_OAUTH_CLIENT_ATTESTATION_TARGET, return_value = {
                  "thumbprint": _MOCK_VALID_THUMBPRINT
              })):
            context.request = _MOCK_PAR_REQUEST
            par_handler.db_engine = MagicMock()
            result = par_handler.endpoint(context)
    
>           assert result.status == '201 Created'
E           AssertionError: assert '400' == '201 Created'
E             - 201 Created
E             + 400

pyeudiw/tests/satosa/frontends/openid4vci/endpoints/test_pushed_authorization_request_endpoint.py:260: AssertionError
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

See also that SignedParRequest requires the copy of the original signed JWT and that without a signature, the iat parameter should se to None, as made evident during this debug shwon below

149         if not is_valid_unix_timestamp(self.iat):                                                                                                                        
 150           logger.error(f"invalid iat {self.iat} in request `{endpoint}` endpoint")                                                                                       
 151           breakpoint()                                                                                                                                                   
 152  ->       raise InvalidRequestException("invalid `iat` parameter")                                                                                                       
 153                                                                                                                                                                          
 154         if int(self.exp) - int(self.iat) > 300:                                                                                                                          
 155           logger.error(f"expired request token in `{endpoint}` endpoint")                                                                                                
 156           raise InvalidRequestException("expired token")                                                                                                                 
 157                                                                                                                                                                          
 158         self.validate_response_type(config.response_types_supported, endpoint)                                                                                           
 159         self.validate_response_mode(config.response_modes_supported, endpoint)                                                                                           
 160         self.validate_code_challenge(endpoint)                                                                                                                           
 161         self.validate_code_challenge_method(config.code_challenge_methods_supported, endpoint)                                                                           
 162         self.validate_scope(config.scopes_supported, endpoint)                                                                                                           
 163         self.validate_authorization_details(endpoint)                                                                                                                    
 164         if not self.scope and (not self.authorization_details or len(self.authorization_details) == 0):                                                                  
 165           raise InvalidRequestException("Missing `scope` and `authorization_details` in `par` endpoint")                                                                 
 166                                                                                                                                                                          
 167         self.validate_redirect_uri(endpoint)                                                                                                                             
 168         self.validate_jti(endpoint)                                                                                                                                      
 169         return self                                                                                                                                                      
(Pdb++) self.iat
(Pdb++) self
SignedParRequest(iss="b'i5blIsZsKuQAl93ygTPpa_PrZCQZ47Bw9MGPIK-RNnM'", aud='example.com/openid4vcimock', exp=1758535114, iat=None, response_type='code', response_mode='query', client_id="b'i5blIsZsKuQAl93ygTPpa_PrZCQZ47Bw9MGPIK-RNnM'", state='a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6', code_challenge='Xz1T-ZG_i_zMEZtEXAMPLE5pYssH', code_challenge_method='S256', scope='openid', authorization_details=[AuthorizationDetail(type='openid_credential', credential_configuration_id='dc_sd_jwt_EuropeanDisabilityCard', credential_identifiers=None)], redirect_uri='https://wallet.example.org/callback', jti="b'i5blIsZsKuQAl93ygTPpa_PrZCQZ47Bw9MGPIK-RNnM':9a3be9c2-0d2c-4670-a413-fd6b86a59a32", issuer_state='b5d6b6c1-98ec-4af2-a2b4-23484d9f1e1d')

self requires a .jwt attribute, brining the original signed request.

the checks on the iat parameter should therefore be properly evaluated.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions