Skip to content
This repository was archived by the owner on Jun 12, 2021. It is now read-only.

Commit 87a110e

Browse files
committed
Special module for add-ons.
1 parent abaa13e commit 87a110e

3 files changed

Lines changed: 97 additions & 1 deletion

File tree

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def run_tests(self):
5151
url='https://github.com/IdentityPython/oicsrv',
5252
packages=["oidcendpoint", 'oidcendpoint/oidc', 'oidcendpoint/authz',
5353
'oidcendpoint/user_authn', 'oidcendpoint/user_info',
54-
'oidcendpoint/oauth2'],
54+
'oidcendpoint/oauth2', 'oidcendpoint/oidc/add_on'],
5555
package_dir={"": "src"},
5656
classifiers=[
5757
"Development Status :: 4 - Beta",

src/oidcendpoint/oidc/add_on/__init__.py

Whitespace-only changes.
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import hashlib
2+
import logging
3+
4+
from cryptojwt.utils import b64e
5+
6+
from oidcendpoint.exception import ProcessError
7+
8+
LOGGER = logging.getLogger(__name__)
9+
10+
CC_METHOD = {"S256": hashlib.sha256, "S384": hashlib.sha384, "S512": hashlib.sha512}
11+
12+
13+
def post_authn_parse(request, client_id, endpoint_context, **kwargs):
14+
"""
15+
16+
:param request:
17+
:param client_id:
18+
:param endpoint_context:
19+
:param kwargs:
20+
:return:
21+
"""
22+
if endpoint_context.args['pkce']['essential'] is True:
23+
if not "code_challenge" in request:
24+
raise ValueError('Missing required code_challenge')
25+
if not "code_challenge_method" in request:
26+
if 'plain' not in endpoint_context.args['pkce']['code_challenge_method']:
27+
raise ValueError("No support for code_challenge_method=plain")
28+
29+
request["code_challenge_method"] = "plain"
30+
else: # May or may not
31+
if "code_challenge" in request:
32+
if not "code_challenge_method" in request:
33+
if 'plain' not in endpoint_context.args['pkce']['code_challenge_method']:
34+
raise ValueError("No support for code_challenge_method=plain")
35+
36+
request["code_challenge_method"] = "plain"
37+
return request
38+
39+
40+
def verify_code_challenge(code_verifier, code_challenge, code_challenge_method="S256"):
41+
"""
42+
Verify a PKCE (RFC7636) code challenge.
43+
44+
45+
:param code_verifier: The origin
46+
:param code_challenge: The transformed verifier used as challenge
47+
:return:
48+
"""
49+
_h = CC_METHOD[code_challenge_method](code_verifier.encode("ascii")).digest()
50+
_cc = b64e(_h)
51+
if _cc.decode("ascii") != code_challenge:
52+
LOGGER.error("PCKE Code Challenge check failed")
53+
raise ProcessError("PCKE check failed")
54+
55+
56+
def post_token_parse(request, client_id, endpoint_context, **kwargs):
57+
"""
58+
To be used as a post_parse_request function.
59+
60+
:param token_request:
61+
:return:
62+
"""
63+
if "code_verifier" in request:
64+
try:
65+
_info = endpoint_context.sdb[request["code"]]
66+
except KeyError:
67+
raise ProcessError("Unknown access grant")
68+
69+
_authn_req = _info["authn_req"]
70+
if "code_challenge" in _authn_req:
71+
try:
72+
_method = _info["authn_req"]["code_challenge_method"]
73+
except KeyError:
74+
_method = "S256"
75+
76+
verify_code_challenge(request["code_verifier"],
77+
_info["authn_req"]["code_challenge"],
78+
_method)
79+
else:
80+
raise ProcessError('Missing code_challenge in authorization request')
81+
82+
return request
83+
84+
85+
def add_pkce_support(endpoint, **kwargs):
86+
endpoint['authorization'].post_parse_request.append(post_authn_parse)
87+
88+
# Set defaults
89+
if 'essential' not in kwargs:
90+
kwargs['essential'] = False
91+
if 'code_challenge' not in kwargs:
92+
kwargs['code_challenge'] = list(CC_METHOD.keys())
93+
94+
endpoint['authorization'].endpoint_context.args['pkce'] = kwargs
95+
96+
endpoint['token'].post_parse_request.append(post_token_parse)

0 commit comments

Comments
 (0)