def test_import_export_eckey(): _key = ECKey(**ECKEY) _key.deserialize() _key.serialize() exp_key = _key.to_dict() assert _eq(exp_key.keys(), ["y", "x", "crv", "kty", "d"])
def generate_jwks(self, mode): if "rotenc" in self.behavior_type: # Rollover encryption keys rsa_key = RSAKey(kid="rotated_rsa_{}".format(time.time()), use="enc").load_key(RSA.generate(2048)) ec_key = ECKey(kid="rotated_ec_{}".format(time.time()), use="enc").load_key(P256) keys = [rsa_key.serialize(private=True), ec_key.serialize(private=True)] new_keys = {"keys": keys} #self.do_key_rollover(new_keys, "%d") signing_keys = [k.to_dict() for k in self.keyjar.get_signing_key()] new_keys["keys"].extend(signing_keys) return json.dumps(new_keys) elif "nokid1jwk" in self.behavior_type: alg = mode["sign_alg"] if not alg: alg = "RS256" keys = [k.to_dict() for kb in self.keyjar[""] for k in list(kb.keys())] for key in keys: if key["use"] == "sig" and key["kty"].startswith(alg[:2]): key.pop("kid", None) jwk = dict(keys=[key]) return json.dumps(jwk) raise Exception( "Did not find sig {} key for nokid1jwk test ".format(alg)) else: # Return all keys keys = [k.to_dict() for kb in self.keyjar[""] for k in list(kb.keys())] jwks = dict(keys=keys) return json.dumps(jwks)
def ec_init(spec): """ :param spec: Key specifics of the form {"type": "EC", "crv": "P-256", "use": ["sig"]}, :return: A KeyBundle instance """ _key = NISTEllipticCurve.by_name(spec["crv"]) kb = KeyBundle(keytype="EC", keyusage=spec["use"]) for use in spec["use"]: priv, pub = _key.key_pair() ec = ECKey(x=pub[0], y=pub[1], d=priv, crv=spec["crv"]) ec.serialize() ec.use = use kb.append(ec) return kb
def test_verify_protected_headers(): payload = "Please take a moment to register today" _key = ECKey().load_key(P256) keys = [_key] _jws = JWS(payload, alg="ES256") protected = dict(header1=u"header1 is protected", header2="header2 is protected too", a=1) _jwt = _jws.sign_compact(keys, protected=protected) protectedHeader, enc_payload, sig = _jwt.split(".") data = dict( payload=enc_payload, signatures=[dict(header=dict(alg=u"ES256", jwk=_key.serialize()), protected=protectedHeader, signature=sig)], ) fobj = io.BytesIO(JSONEncoder().encode(data).encode("utf-8")) _jws = JWS() reader = codecs.getreader("utf-8") assert _jws.verify_json(reader(fobj)) == payload
def test_verify_protected_headers(): payload = "Please take a moment to register today" _key = ECKey().load_key(P256) keys = [_key] _jws = JWS(payload, alg="ES256") protected = dict(header1=u"header1 is protected", header2="header2 is protected too", a=1) _jwt = _jws.sign_compact(keys, protected=protected) protectedHeader, enc_payload, sig = _jwt.split(".") data = dict(payload=enc_payload, signatures=[ dict( header=dict(alg=u"ES256", jwk=_key.serialize()), protected=protectedHeader, signature=sig, ) ]) _jws = JWS() assert _jws.verify_json(json.dumps(data)) == payload
def test_verify_protected_headers(): payload = "Please take a moment to register today" _key = ECKey().load_key(P256) keys = [_key] _jws = JWS(payload, alg="ES256") protected = dict(header1=u"header1 is protected", header2="header2 is protected too", a=1) _jwt = _jws.sign_compact(keys, protected=protected) protectedHeader, enc_payload, sig = _jwt.split(".") data = dict(payload=enc_payload, signatures=[ dict( header=dict(alg=u"ES256", jwk=_key.serialize()), protected=protectedHeader, signature=sig, ) ]) fobj = io.BytesIO(JSONEncoder().encode(data).encode("utf-8")) _jws = JWS() reader = codecs.getreader("utf-8") assert _jws.verify_json(reader(fobj)) == payload
def generate_jwks(self, mode): if "rotenc" in self.behavior_type: # Rollover encryption keys rsa_key = RSAKey(kid="rotated_rsa_{}".format(time.time()), use="enc").load_key(RSA.generate(2048)) ec_key = ECKey(kid="rotated_ec_{}".format(time.time()), use="enc").load_key(P256) keys = [ rsa_key.serialize(private=True), ec_key.serialize(private=True) ] new_keys = {"keys": keys} #self.do_key_rollover(new_keys, "%d") signing_keys = [k.to_dict() for k in self.keyjar.get_signing_key()] new_keys["keys"].extend(signing_keys) return json.dumps(new_keys) elif "nokid1jwk" in self.behavior_type: alg = mode["sign_alg"] if not alg: alg = "RS256" keys = [ k.to_dict() for kb in self.keyjar[""] for k in list(kb.keys()) ] for key in keys: if key["use"] == "sig" and key["kty"].startswith(alg[:2]): key.pop("kid", None) jwk = dict(keys=[key]) return json.dumps(jwk) raise Exception( "Did not find sig {} key for nokid1jwk test ".format(alg)) else: # Return all keys keys = [ k.to_dict() for kb in self.keyjar[""] for k in list(kb.keys()) ] jwks = dict(keys=keys) return json.dumps(jwks)
def test_create_eckey(): priv, pub = P256.key_pair() ec = ECKey(x=pub[0], y=pub[1], d=priv, crv="P-256") exp_key = ec.serialize() assert _eq(list(exp_key.keys()), ["y", "x", "crv", "kty"])
def authorization_endpoint(self, request="", cookie=None, **kwargs): _req = parse_qs(request) #self.events.store(EV_REQUEST, _req) try: _scope = _req["scope"] except KeyError: return self._error(error="incorrect_behavior", descr="No scope parameter") else: # verify that openid is among the scopes _scopes = _scope[0].split(" ") if "openid" not in _scopes: return self._error(error="incorrect_behavior", descr="Scope does not contain 'openid'") client_id = _req["client_id"][0] try: f = response_type_cmp(kwargs['test_cnf']['response_type'], _req['response_type']) except KeyError: pass else: if f is False: self.events.store( EV_FAULT, 'Wrong response type: {}'.format(_req['response_type'])) return self._error_response(error="incorrect_behavior", descr="Wrong response_type") _rtypes = [] for rt in _req['response_type']: _rtypes.extend(rt.split(' ')) if 'id_token' in _rtypes: try: self._update_client_keys(client_id) except TestError: return self._error(error="incorrect_behavior", descr="No change in client keys") _response = provider.Provider.authorization_endpoint( self, request, cookie, **kwargs) if "rotenc" in self.behavior_type: # Rollover encryption keys rsa_key = RSAKey(kid="rotated_rsa_{}".format(time.time()), use="enc").load_key(RSA.generate(2048)) ec_key = ECKey(kid="rotated_ec_{}".format(time.time()), use="enc").load_key(P256) keys = [ rsa_key.serialize(private=True), ec_key.serialize(private=True) ] new_keys = {"keys": keys} self.events.store("New encryption keys", new_keys) self.do_key_rollover(new_keys, "%d") self.events.store("Rotated encryption keys", '') logger.info('Rotated OP enc keys, new set: {}'.format( key_summary(self.keyjar, ''))) # This is just for logging purposes try: _resp = self.server.http_request(_req["request_uri"][0]) except KeyError: pass else: if _resp.status_code == 200: self.events.store( EV_REQUEST, "Request from request_uri: {}".format(_resp.text)) return _response
def authorization_endpoint(self, request="", cookie=None, **kwargs): if isinstance(request, dict): _req = request else: _req = {} for key, val in parse_qs(request).items(): if len(val) == 1: _req[key] = val[0] else: _req[key] = val # self.events.store(EV_REQUEST, _req) try: _scope = _req["scope"] except KeyError: return error_response( error="incorrect_behavior", descr="No scope parameter" ) else: # verify that openid is among the scopes _scopes = _scope.split(" ") if "openid" not in _scopes: return error_response( error="incorrect_behavior", descr="Scope does not contain 'openid'" ) client_id = _req["client_id"] try: f = response_type_cmp(self.capabilities['response_types_supported'], _req['response_type']) except KeyError: pass else: if f is False: self.events.store( EV_FAULT, 'Wrong response type: {}'.format(_req['response_type'])) return error_response(error="incorrect_behavior", descr="Not supported response_type") _rtypes = _req['response_type'].split(' ') if 'id_token' in _rtypes: try: self._update_client_keys(client_id) except TestError: return error_response(error="incorrect_behavior", descr="No change in client keys") if isinstance(request, dict): request = urlencode(request) if "max_age" in _req and _req["max_age"] == "0" and "prompt" in _req and _req["prompt"] == "none": aresp = { "error": "login_required", } if "state" in _req: aresp['state'] = _req["state"] return self.response_mode(_req, False, aresp=aresp, redirect_uri=_req['redirect_uri'], headers={}) else: _response = provider.Provider.authorization_endpoint(self, request, cookie, **kwargs) if "rotenc" in self.behavior_type: # Rollover encryption keys rsa_key = RSAKey(kid="rotated_rsa_{}".format(time.time()), use="enc").load_key(RSA.generate(2048)) ec_key = ECKey(kid="rotated_ec_{}".format(time.time()), use="enc").load_key(P256) keys = [rsa_key.serialize(private=True), ec_key.serialize(private=True)] new_keys = {"keys": keys} self.events.store("New encryption keys", new_keys) self.do_key_rollover(new_keys, "%d") self.events.store("Rotated encryption keys", '') logger.info( 'Rotated OP enc keys, new set: {}'.format( key_summary(self.keyjar, ''))) # This is just for logging purposes try: _resp = self.server.http_request(_req["request_uri"]) except KeyError: pass except requests.ConnectionError as err: self.events.store(EV_EXCEPTION, err) err = unwrap_exception(err) return error_response(error="server_error", descr=err) else: if _resp.status_code == 200: self.events.store(EV_REQUEST, "Request from request_uri: {}".format( _resp.text)) return _response
def authorization_endpoint(self, request="", cookie=None, **kwargs): _req = parse_qs(request) #self.events.store(EV_REQUEST, _req) try: _scope = _req["scope"] except KeyError: return self._error( error="incorrect_behavior", descr="No scope parameter" ) else: # verify that openid is among the scopes _scopes = _scope[0].split(" ") if "openid" not in _scopes: return self._error( error="incorrect_behavior", descr="Scope does not contain 'openid'" ) client_id = _req["client_id"][0] try: f = response_type_cmp(kwargs['test_cnf']['response_type'], _req['response_type']) except KeyError: pass else: if f is False: self.events.store( EV_FAULT, 'Wrong response type: {}'.format(_req['response_type'])) return self._error_response(error="incorrect_behavior", descr="Wrong response_type") _rtypes = [] for rt in _req['response_type']: _rtypes.extend(rt.split(' ')) if 'id_token' in _rtypes: try: self._update_client_keys(client_id) except TestError: return self._error(error="incorrect_behavior", descr="No change in client keys") _response = provider.Provider.authorization_endpoint(self, request, cookie, **kwargs) if "rotenc" in self.behavior_type: # Rollover encryption keys rsa_key = RSAKey(kid="rotated_rsa_{}".format(time.time()), use="enc").load_key(RSA.generate(2048)) ec_key = ECKey(kid="rotated_ec_{}".format(time.time()), use="enc").load_key(P256) keys = [rsa_key.serialize(private=True), ec_key.serialize(private=True)] new_keys = {"keys": keys} self.events.store("New encryption keys", new_keys) self.do_key_rollover(new_keys, "%d") self.events.store("Rotated encryption keys", '') logger.info( 'Rotated OP enc keys, new set: {}'.format( key_summary(self.keyjar, ''))) # This is just for logging purposes try: _resp = self.server.http_request(_req["request_uri"][0]) except KeyError: pass else: if _resp.status_code == 200: self.events.store(EV_REQUEST, "Request from request_uri: {}".format(_resp.text)) return _response
from jwkest.jwk import ECKey from Cryptodome.PublicKey import ECC ecc_key = ECC.generate(curve='P-256') jwk = ECKey(key=ecc_key) jwk.serialize(private=True)
def authorization_endpoint(self, request="", cookie=None, **kwargs): if isinstance(request, dict): _req = request else: _req = {} for key, val in parse_qs(request).items(): if len(val) == 1: _req[key] = val[0] else: _req[key] = val # self.events.store(EV_REQUEST, _req) try: _scope = _req["scope"] except KeyError: return error( error="incorrect_behavior", descr="No scope parameter" ) else: # verify that openid is among the scopes _scopes = _scope.split(" ") if "openid" not in _scopes: return error( error="incorrect_behavior", descr="Scope does not contain 'openid'" ) client_id = _req["client_id"] try: f = response_type_cmp(self.capabilities['response_types_supported'], _req['response_type']) except KeyError: pass else: if f is False: self.events.store( EV_FAULT, 'Wrong response type: {}'.format(_req['response_type'])) return error_response(error="incorrect_behavior", descr="Not supported response_type") _rtypes = _req['response_type'].split(' ') if 'id_token' in _rtypes: try: self._update_client_keys(client_id) except TestError: return error(error="incorrect_behavior", descr="No change in client keys") if isinstance(request, dict): request = urlencode(request) _response = provider.Provider.authorization_endpoint(self, request, cookie, **kwargs) if "rotenc" in self.behavior_type: # Rollover encryption keys rsa_key = RSAKey(kid="rotated_rsa_{}".format(time.time()), use="enc").load_key(RSA.generate(2048)) ec_key = ECKey(kid="rotated_ec_{}".format(time.time()), use="enc").load_key(P256) keys = [rsa_key.serialize(private=True), ec_key.serialize(private=True)] new_keys = {"keys": keys} self.events.store("New encryption keys", new_keys) self.do_key_rollover(new_keys, "%d") self.events.store("Rotated encryption keys", '') logger.info( 'Rotated OP enc keys, new set: {}'.format( key_summary(self.keyjar, ''))) # This is just for logging purposes try: _resp = self.server.http_request(_req["request_uri"]) except KeyError: pass except requests.ConnectionError as err: self.events.store(EV_EXCEPTION, err) err = unwrap_exception(err) return error_response(error="server_error", descr=err) else: if _resp.status_code == 200: self.events.store(EV_REQUEST, "Request from request_uri: {}".format( _resp.text)) return _response
def enc_setup(self, msg, auth_data, key=None, **kwargs): encrypted_key = "" self.msg = msg self.auth_data = auth_data # Generate the input parameters try: apu = b64d(kwargs["apu"]) except KeyError: apu = Random.get_random_bytes(16) try: apv = b64d(kwargs["apv"]) except KeyError: apv = Random.get_random_bytes(16) # Handle Local Key and Ephemeral Public Key if not key: raise Exception("EC Key Required for ECDH-ES JWE Encrpytion Setup") # Generate an ephemeral key pair if none is given curve = NISTEllipticCurve.by_name(key.crv) if "epk" in kwargs: epk = kwargs["epk"] if isinstance(kwargs["epk"], ECKey) else ECKey( kwargs["epk"]) else: epk = ECKey().load_key(key=NISTEllipticCurve.by_name(key.crv)) params = { "apu": b64e(apu), "apv": b64e(apv), "epk": epk.serialize(False) } cek = iv = None if 'cek' in kwargs and kwargs['cek']: cek = kwargs['cek'] if 'iv' in kwargs and kwargs['iv']: iv = kwargs['iv'] cek, iv = self._generate_key_and_iv(self.enc, cek=cek, iv=iv) if self.alg == "ECDH-ES": try: dk_len = KEYLEN[self.enc] except KeyError: raise Exception("Unknown key length for algorithm %s" % self.enc) cek = ecdh_derive_key(curve, epk.d, (key.x, key.y), apu, apv, str(self.enc).encode(), dk_len) elif self.alg in [ "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW" ]: _pre, _post = self.alg.split("+") klen = int(_post[1:4]) kek = ecdh_derive_key(curve, epk.d, (key.x, key.y), apu, apv, str(_post).encode(), klen) encrypted_key = aes_wrap_key(kek, cek) else: raise Exception("Unsupported algorithm %s" % self.alg) return cek, encrypted_key, iv, params, epk