Skip to content

Commit

Permalink
remove custom implementation of code challenge computation, reuse oic…
Browse files Browse the repository at this point in the history
… function instead. Remove nacl dependency
  • Loading branch information
maxxiefjv committed Aug 9, 2021
1 parent 173d3af commit 1c642b8
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 40 deletions.
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
description='OpenID Connect Provider (OP) library in Python.',
install_requires=[
'oic >= 1.2.1',
'pynacl',
'pymongo'
]
)
30 changes: 5 additions & 25 deletions src/pyop/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
from urllib.parse import parse_qsl
from urllib.parse import urlparse

import nacl.hash
from nacl.encoding import URLSafeBase64Encoder
from jwkest import jws
from oic import rndstr
from oic.exception import MessageException
Expand All @@ -23,6 +21,7 @@
from oic.oic.message import RefreshAccessTokenRequest
from oic.oic.message import RegistrationRequest
from oic.oic.message import RegistrationResponse
from oic.extension.provider import Provider as OICProviderExtensions

from .message import AuthorizationRequest
from .message import AccessTokenRequest
Expand Down Expand Up @@ -330,23 +329,6 @@ def handle_token_request(self, request_body, # type: str
raise InvalidTokenRequest('grant_type \'{}\' unknown'.format(token_request['grant_type']), token_request,
oauth_error='unsupported_grant_type')

def _compute_code_challenge(self,
code_verifier # type: str
):
# type: (...) -> str
"""
Given a code verifier compute the code_challenge. This code_challenge is computed as defined (https://datatracker.ietf.org/doc/html/rfc7636#section-4.2):
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))).
This shows that the SHA256 of the ascii encoded code_verifier is URLSafe base64 encoded. We have adjusted the encoding to the ISO_8859_1 encoding,
conform to the AppAuth SDK for Android and IOS. Moreover, we remove the base64 padding (=).
:param code_verifier: the code verifier to transform to the Code Challenge
"""
verifier_hash = nacl.hash.sha256(code_verifier.encode('ISO_8859_1'), encoder=URLSafeBase64Encoder)
return verifier_hash.decode().replace('=', '')

def _PKCE_verify(self,
token_request, # type: AccessTokenRequest
authentication_request # type: AuthorizationRequest
Expand All @@ -368,12 +350,10 @@ def _PKCE_verify(self,
raise InvalidTokenRequest("A code_challenge and code_verifier have been supplied"
"but missing code_challenge_method in authentication_request", token_request)

code_challenge_method = authentication_request['code_challenge_method']
if code_challenge_method == 'plain':
return authentication_request['code_challenge'] == token_request['code_verifier']

code_challenge = self._compute_code_challenge(token_request['code_verifier'])
return code_challenge == authentication_request['code_challenge']
# OIC Provider extension returns either a boolean or Response object containing an error. To support
# stricter typing guidelines, return if True. Error handling support should be in encapsulating function.
return OICProviderExtensions.verify_code_challenge(token_request['code_verifier'],
authentication_request['code_challenge'], authentication_request['code_challenge_method']) == True

def _verify_code_exchange_req(self,
token_request, # type: AccessTokenRequest
Expand Down
14 changes: 0 additions & 14 deletions tests/pyop/test_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,20 +333,6 @@ def test_pkce_code_exchange_request(self):
assert_id_token_base_claims(response['id_token'], self.provider.signing_key, self.provider,
self.authn_request_args)

@patch('time.time', MOCK_TIME)
def test_pkce_code_exchange_request_plaintext(self):
self.authorization_code_exchange_request_args['code'] = self.create_authz_code(
{
"code_challenge": "SoOEDN-mZKNhw7Mc52VXxyiqTvFB3mod36MwPru253c",
"code_challenge_method": "plain"
}
)
self.authorization_code_exchange_request_args['code_verifier'] = "SoOEDN-mZKNhw7Mc52VXxyiqTvFB3mod36MwPru253c"
response = self.provider._do_code_exchange(self.authorization_code_exchange_request_args, None)
assert response['access_token'] in self.provider.authz_state.access_tokens
assert_id_token_base_claims(response['id_token'], self.provider.signing_key, self.provider,
self.authn_request_args)

@patch('time.time', MOCK_TIME)
def test_code_exchange_request_with_claims_requested_in_id_token(self):
claims_req = {'claims': ClaimsRequest(id_token=Claims(email=None))}
Expand Down

0 comments on commit 1c642b8

Please sign in to comment.