def index(): public_file = (open(str(settings.ROOT) + "/public.pub", "r")) public_key = jwk.JWK.from_pem(public_file.read().encode()) ks = jwk.JWKSet() ks.add(public_key) return ks.export(as_dict=True) ks2 = jwk.JWKSet() ks2.import_keyset(ks.export(False)) kkk = ks2.get_key(public_key.key_id) return kkk.export_to_pem(True, None)
def decrypt_and_verify(self, content): # decrypt jwetoken = jwe.JWE() jwetoken.deserialize(content, key=encryption_private_key) if json.loads(jwetoken.objects['protected'])['alg'] != 'RSA-OAEP-256' or json.loads(jwetoken.objects['protected'])['enc'] != 'A256CBC-HS512': raise Exception('Unsupported encryption') # we have to check those, otherwise other encryptions can be used as an attack vector # verify jwstoken = jws.JWS() jwstoken.deserialize(jwetoken.payload) if signature_public_key is None: jku = json.loads(jwstoken.objects['protected'])['jku'] kid = json.loads(jwstoken.objects['protected'])['kid'] #NOTE: to be certain to use a valid public key, one would have to check the # domain name and SSL certificate's Common Name against a whitelisted list keys = requests.get(jku).content keyset = jwk.JWKSet() keyset.import_keyset(keys) verification_key = keyset.get_key(kid) else: verification_key = signature_public_key if json.loads(jwstoken.objects['protected'])['alg'] != 'RS512': raise Exception('Unsupported signature algorithm') # we have to check, otherwise other algorithms can be used as an attack vector jwstoken.verify(verification_key) # if there's no exception, the signature is valid return jwstoken.payload
def get_key_from_jwks_json(tenant, kid): fetcher = CacheFetcher() data = fetcher.fetch("https://" + tenant + "/oauth2/.well-known/jwks.json", 600) try: key = jwk.JWKSet().from_json(data).get_key(kid) return key except Exception: raise UnauthorizedAccess
def read_key_from_file(filename): with open(filename, 'r') as fn: full_key_json = json.load(fn) if full_key_json.get('keys', None): print("Input is keyset.") key_set = jwk.JWKSet() key_set.import_keyset(**full_key_json) full_key = key_set else: print("Input is not keyset.") full_key = jwk.JWK(**full_key_json) return full_key
def get_key_from_jwks_json(tenant, kid): fetcher = CacheFetcher() data = fetcher.fetch("https://" + tenant + "/oauth2/.well-known/jwks.json", 600) try: key = jwk.JWKSet().from_json(data).get_key(kid) return key except Exception: raise AxiomsError( { "error": "unauthorized_access", "error_description": "Invalid access token", }, 401, )
def client_config(self): redirect_uri = 'http://localhost:8000/complete/test/?state=1234' jwks = jwk.JWKSet() jwks['keys'].add( jwk.JWK.generate(kty='RSA', alg='RS256', size=2048, kid=secrets.token_urlsafe(32))) ret = OpenIDClient.objects.create( client_id='test', redirect_uris=redirect_uri, client_auth_type=OpenIDClient.CLIENT_AUTH_TYPE_BASIC, jwks=jwks.export(True)) ret.set_client_secret('b') ret.save() ret.parsed_jwks = jwks return ret
def load_keys(key_list_path: str): global keys # Load the RSA keys from the keys folder keys = jwk.JWKSet() with open(key_list_path, mode="r") as key_list_file: # Read the locations of the keys key_list = json.load(key_list_file) print(f"Keylist contains {len(key_list)} elements.") for key_list_item in key_list: # Read the PEM key file with open(key_list_item["path"], mode="rb") as key_file: # Create JWK from file k = jwk.JWK.from_pem(key_file.read()) k._params["kid"] = key_list_item["name"] keys.add(k) print("JWKSet has been loaded.", keys) load_key()
def handle(self, *args, **kwargs): """ Creates JWT keys at the location pointed by settings.OPENID_JWT_PRIVATE_KEY, settings.OPENID_JWT_PUBLIC_KEY """ jwks = jwk.JWKSet() jwks['keys'].add(jwk.JWK.generate(kty='RSA', alg='RS256', size=2048, kid=secrets.token_urlsafe(32))) jwks['keys'].add(jwk.JWK.generate(kty='RSA', alg='RS512', size=4096, kid=secrets.token_urlsafe(32))) jwks['keys'].add(jwk.JWK.generate(kty='EC', crv='P-256', alg='ES256', kid=secrets.token_urlsafe(32))) jwks['keys'].add(jwk.JWK.generate(kty='EC', crv='P-384', alg='ES384', kid=secrets.token_urlsafe(32))) jwks['keys'].add(jwk.JWK.generate(kty='EC', crv='P-521', alg='ES512', kid=secrets.token_urlsafe(32))) jwks['keys'].add(jwk.JWK.generate(kty='oct', alg='AES', size=16*8, kid=secrets.token_urlsafe(32))) client = OpenIDClient.objects.get_or_create(client_id=OpenIDClient.SELF_CLIENT_ID, defaults={ 'client_auth_type': OpenIDClient.CLIENT_AUTH_TYPE_INVALID, 'client_name': 'This server' })[0] client.jwks = json.dumps(json.loads(jwks.export(private_keys=True)), indent=True) client.save()
def create_JWK(key): return jwk.JWKSet()
def jwks(self, req, **query): keyset = jwk.JWKSet() keyset.add(self.__get_id_token_jwk(req)) return keyset.export(private_keys=False)
def generate_keyset(keys): keyset = jwk.JWKSet() for key in keys: keyset.add(key) return keyset
def post(self, request, success_url=None) : encoded = request.POST.get('JWT') if encoded is None: return self.launcherror('This URL is expecting a POST with a JWT to initiate a launch') try: header = jwt.get_unverified_header(encoded) except: return self.launcherror('Could not load header from JWT',encoded) try: kid = header.get('kid') except: return self.launcherror('The JWT is missing a key ID (kid)', encoded) # Check if we already have the kid public_key = TSUGI_JWK_LIST.get(kid, False) # Lets get the keyset, retrieve the key, and cache it if public_key == False : keyset_proxy = False try : if settings.TSUGI_PROXY is not False: keyset_proxy = {'http' : settings.TSUGI_PROXY} except: pass try : keyset_url = settings.TSUGI_KEYSET except : print("Please set TSUGI_KEYSET in your settings.py, using dev1.tsugicloud.org as default") keyset_url = "https://dev1.tsugicloud.org/tsugi/lti/keyset-ext" status_code = False try: if keyset_proxy : print(keyset_proxy) response = requests.get(keyset_url, proxies=keyset_proxy, timeout=10) status_code = response.status_code dat = response.text except Exception as e: print('Keyset load failure', keyset_url, e) return self.launcherror('Could not retrieve keyset from '+keyset_url+' ('+str(e)+')') if len(dat) < 1 : print('Keyset load error', keyset_url, status_code) return self.launcherror('Could not load keyset from '+keyset_url+' ('+str(status_code)+')') # https://github.com/latchset/jwcrypto/blob/master/jwcrypto/tests.py # https://jwcrypto.readthedocs.io/en/latest/jwk.html#classes try: ks = jwk.JWKSet() ks.import_keyset(dat) except Exception as e: print('Keyset parse error', keyset_url, e) print(dat[:1000]) return self.launcherror('Could not parse keyset from '+keyset_url,encoded) try: k1 = ks.get_key(kid) public_key = jwk.JWK.export_to_pem(k1) except: print('Keyset extract error', keyset_url) print(dat[:1000]) return self.launcherror('Could not extract kid='+kid+' from '+keyset_url,encoded) if len(TSUGI_JWK_LIST) > 10 : TSUGI_JWK_LIST.clear() TSUGI_JWK_LIST[kid] = public_key try: lti_launch = jwt.decode(encoded, public_key, algorithms=['RS256']) print('Forwarding valid launch') print(lti_launch) except Exception as e: return self.launcherror('Could not decode JSON Web Token: '+str(e),encoded) # Check to see how they want us to launch... debug = request.GET.get('debug') force_cookie = request.GET.get('force_cookie') if success_url : destination = success_url print('from successurl',destination) else: destination = request.GET.get('destination', None) print('from GET',destination) if destination is None: return self.launcherror('Must have a success_url or a destination parameter') lti_launch['launch_destination'] = destination lti_launch['launch_force_cookie'] = force_cookie lti_launch['launch_debug'] = debug request.session['lti_launch'] = lti_launch redirect_url = reverse(destination) request.session['lti_destination'] = redirect_url if debug == "true" or force_cookie == "true" : redirect_url = reverse('django_tsugi:start') # Copy GET parameters params = request.GET.copy() params['destination'] = destination redirect_url = redirect_url + "?" + urllib.parse.urlencode(params) return redirect(redirect_url)
def __init__(self, jwk_file): keys_json = open(jwk_file, 'r').read() self.key_set = jwk.JWKSet().from_json(keys_json) self.logger = logging.getLogger(__name__) self.header_key = 'TOKEN'
def jwks_view(req): keyset = jwk.JWKSet() keyset.add(decryption_key) keyset.add(signing_key) return sanic.response.json(json.loads(keyset.export(False)))
def get(self): keyset = jwk.JWKSet() keyset.add(get_id_token_jwk()) return keyset.export(private_keys=False)