def test_jws_rsa_signer_and_verifier(): algs = ['RS256', 'RS384', 'RS512', 'PS256', 'PS384', 'PS512'] for alg in algs: calgs = algs[:] calgs.remove(alg) json_priv_key = json.loads(test_vector.json_rsa_priv_key) json_priv_key['alg'] = alg json_priv_key = json.dumps(json_priv_key) json_pub_key = json.loads(test_vector.json_rsa_pub_key) json_pub_key['alg'] = alg json_pub_key = json.dumps(json_pub_key) json_header_rsa = json.loads(test_vector.test_header_rsa) json_header_rsa['alg'] = alg # Sign priv_key = key_from_jwk_dict(json.loads(json_priv_key)) jws = JWS(msg=test_vector.test_payload, **json_header_rsa) signed_token = jws.sign_compact([priv_key]) # Verify pub_key = key_from_jwk_dict(json.loads(json_pub_key)) verifier = JWS(alg=[alg]) assert verifier.verify_compact(signed_token, [pub_key]) for modified_token in modify_token(signed_token, calgs): with pytest.raises(JWKESTException): verifier.verify_compact(modified_token, [pub_key])
def test_jws_ecdsa_signer_verifier_es256(): # Sign priv_key = key_from_jwk_dict(json.loads(test_vector.es256_ecdsa_priv_key)) signer = JWS(msg=test_vector.test_payload, **json.loads(test_vector.test_header_ecdsa)) signed_token = signer.sign_compact([priv_key]) # Verify pub_key = key_from_jwk_dict(json.loads(test_vector.es256_ecdsa_pub_key)) verifier = JWS(alg='ES256') assert verifier.verify_compact(signed_token, [pub_key]) for modified_token in modify_token(signed_token, ['ES384', 'ES512']): with pytest.raises(JWKESTException): verifier.verify_compact(modified_token, [pub_key])
def test_jws_mac_authenticator_and_verifier(): algs = ['HS256', 'HS384', 'HS512'] for alg in algs: calgs = algs[:] calgs.remove(alg) json_hmac_key = json.loads(test_vector.json_hmac_key) json_hmac_key['alg'] = alg json_hmac_key = json.dumps(json_hmac_key) json_header_hmac = json.loads(test_vector.test_header_hmac) json_header_hmac['alg'] = alg json_header_hmac = json.dumps(json_header_hmac) # Authenticator mac_key = key_from_jwk_dict(json.loads(json_hmac_key)) authenticator = JWS(test_vector.test_payload, **json.loads(json_header_hmac)) signed_token = authenticator.sign_compact([mac_key]) # Verify verifier = JWS(alg=alg) assert verifier.verify_compact(signed_token, [mac_key]) for modified_token in modify_token(signed_token, calgs): with pytest.raises(JWKESTException): assert verifier.verify_compact(modified_token, [mac_key])
def test_key_from_jwk_dict_ec(): key = ECKey().load(full_path("570-ec-sect571r1-keypair.pem")) assert key.has_private_key() jwk = key.serialize(private=True) _key = key_from_jwk_dict(jwk) assert isinstance(_key, ECKey) assert _key.has_private_key()
def test_private_rsa_key_from_jwk(): keys = [] kspec = json.loads(open(full_path("jwk_private_key.json")).read()) keys.append(key_from_jwk_dict(kspec)) key = keys[0] assert isinstance(key.n, (bytes, str)) assert isinstance(key.e, (bytes, str)) assert isinstance(key.d, (bytes, str)) assert isinstance(key.p, (bytes, str)) assert isinstance(key.q, (bytes, str)) assert isinstance(key.dp, (bytes, str)) assert isinstance(key.dq, (bytes, str)) assert isinstance(key.qi, (bytes, str)) _d = key.to_dict() assert _eq( list(_d.keys()), [ "n", "alg", "dq", "e", "q", "p", "dp", "d", "ext", "key_ops", "kty", "qi" ], ) assert _eq(list(_d.keys()), kspec.keys())
def post_parse_request(request, client_id, endpoint_context, **kwargs): """ Expect http_info attribute in kwargs. http_info should be a dictionary containing HTTP information. :param request: :param client_id: :param endpoint_context: :param kwargs: :return: """ _http_info = kwargs.get("http_info") if not _http_info: return request _dpop = DPoPProof().verify_header(_http_info["headers"]["dpop"]) # The signature of the JWS is verified, now for checking the # content if _dpop["htu"] != _http_info["url"]: raise ValueError("htu in DPoP does not match the HTTP URI") if _dpop["htm"] != _http_info["method"]: raise ValueError("htm in DPoP does not match the HTTP method") if not _dpop.key: _dpop.key = key_from_jwk_dict(_dpop["jwk"]) # Need something I can add as a reference when minting tokens request["dpop_jkt"] = as_unicode(_dpop.key.thumbprint("SHA-256")) return request
def main(): parser = argparse.ArgumentParser() parser.add_argument("-r", dest="rsa_file", help="File containing a RSA key") parser.add_argument("-k", dest="hmac_key", help="If using a HMAC algorithm this is the key") parser.add_argument("-i", dest="kid", help="key id") parser.add_argument("-j", dest="jwk", help="JSON Web Key") parser.add_argument("-J", dest="jwks", help="JSON Web Keys") parser.add_argument("-u", dest="jwks_url", help="JSON Web Keys URL") parser.add_argument("-f", dest="msg", help="The message") parser.add_argument( "-q", dest="quiet", help="Quiet mode -- only show the RAW but prettified JSON", action="store_true", ) args = parser.parse_args() if args.kid: _kid = args.kid else: _kid = "" keys = [] if args.rsa_file: keys.append(RSAKey(key=import_rsa_key(args.rsa_file), kid=_kid)) if args.hmac_key: keys.append(SYMKey(key=args.hmac_key, kid=_kid)) if args.jwk: _key = key_from_jwk_dict(open(args.jwk).read()) keys.append(_key) if args.jwks: _iss = KeyIssuer() _iss.import_jwks(open(args.jwks).read()) keys.extend(_iss.all_keys()) if args.jwks_url: _kb = KeyBundle(source=args.jwks_url) keys.extend(_kb.get()) if not args.msg: # If nothing specified assume stdin message = sys.stdin.read() elif args.msg == "-": message = sys.stdin.read() else: if os.path.isfile(args.msg): message = open(args.msg).read().strip("\n") else: message = args.msg message = message.strip() message = message.strip('"') process(message, keys, args.quiet)
def get_jwks_from_jwks_uri(self, jwks_uri: str, verify: bool = True) -> tuple: """ builds jwks objects, importable in a Key Jar """ jwks_dict = requests.get(jwks_uri, verify=verify).json() return jwks_dict, [key_from_jwk_dict(i) for i in jwks_dict["keys"]]
def from_dict(self, dictionary, **kwargs): Message.from_dict(self, dictionary, **kwargs) if "jwk" in self: self.key = key_from_jwk_dict(self["jwk"]) self.key.deserialize() return self
def test_key_from_jwk_dict_rsa(): rsa_key = new_rsa_key() jwk = rsa_key.serialize(private=True) _key = key_from_jwk_dict(jwk) assert isinstance(_key, RSAKey) assert _key.has_private_key() _key2 = RSAKey(**jwk) assert isinstance(_key2, RSAKey) assert _key2.has_private_key()
def test_thumbprint_ec(): jwk = key_from_jwk_dict({ "kty": "EC", "crv": "P-256", "x": "MJ05vpfkWoIce1MwUpZYAyotenxp4yYVHJuc6lN_J0o", "y": "Kfzs5wbqnEWUlFElN8ErWEL5YL2WQ1yowxzHejlzlZ0", }) thumbprint = "RCWR9g8NPt9iZeq-lh-qXbiFxXcU0_o1YLitDj3kpg0" assert (jwk.thumbprint("SHA-256").decode()) == thumbprint
def __init__(self, set_defaults=True, **kwargs): self.key = None Message.__init__(self, set_defaults=set_defaults, **kwargs) if self.key: pass elif "jwk" in self: self.key = key_from_jwk_dict(self["jwk"]) self.key.deserialize()
def test_jws_mac_verifier_with_rfc(): # Set up phase: parse the key and initialize the JwsMacVerify key = key_from_jwk_dict(json.loads(test_vector.json_hmac_key)) verifier = JWS(alg='HS256') # Use phase assert verifier.verify_compact(test_vector.hmac_token, [key]) for modified_token in modify_token(test_vector.hmac_token, ['HS384', 'HS512']): with pytest.raises(JWKESTException): assert verifier.verify_compact(modified_token, [key])
def test_jws_ecdsa_verifier_with_rfc_es512(): # Set up phase: parse the key and initialize the verifier. key = key_from_jwk_dict(json.loads(test_vector.es512_ecdsa_pub_key)) verifier = JWS(alg='ES512') # Use phase assert verifier.verify_compact(test_vector.es512_ecdsa_token, [key]) for modified_token in modify_token(test_vector.es512_ecdsa_token, ['ES256', 'ES512']): with pytest.raises(JWKESTException): verifier.verify_compact(modified_token, [key])
def test_jws_rsa_verifier_with_rfc(): # Set up phase: parse the key and initialize the verifier. key = key_from_jwk_dict(json.loads(test_vector.json_rsa_pub_key)) jws = JWS() assert jws.verify_compact(test_vector.rsa_token, [key]) # mess with the JWS for _token in modify_token(test_vector.rsa_token, ['RS384', 'RS512', 'PS256', 'PS384', 'PS512']): with pytest.raises(JWKESTException): jws.verify_compact(_token, [key])
def test_thumbprint_rsa(): jwk = key_from_jwk_dict({ "kty": "RSA", "e": "AQAB", "n": "3xIyjRLL1LYi2FULhN6koVwtsaixgXa5TBOMcq2EMsk_Fq" "-tSXmxA8ATYcUnuSGX3PGJ5pHwIF42eesIzQV5ypYklF0sLAkmkXow_TMDX0qoc4rdfc2prq" "-mzPWwGcYoRsjDKiSUFOUSKB41zQ6sMY2k4BWZVo1bEL0CVpVct1DDhqSME6uUKex9T2AbwWNvwFacrwJaWyKixBhiPSwVBn7dUWDnJiM39_4Lnw6JnriXcli-aJlPuXm5F_qspXL4Pfn9nR5Z9j9Qf7NFif7nVRyg8cx7OYTbbsoIbMYYG-boVPLL7ebEBZVIUysqH_WkNJlkl5m7gAs5DB_KfMx18Q", }) thumbprint = "Q1wZMrouq_iCnG7mr2y03Zxf7iE9mie-y_Mfh9-Cgk0" assert (jwk.thumbprint("SHA-256").decode()) == thumbprint
def test_public_key_from_jwk(): keys = [] kspec = json.loads(open(full_path("jwk_private_key.json")).read()) keys.append(key_from_jwk_dict(kspec, private=False)) key = keys[0] assert isinstance(key.n, (bytes, str)) assert isinstance(key.e, (bytes, str)) _d = key.to_dict() assert _eq(list(_d.keys()), ['n', 'alg', 'e', 'ext', 'key_ops', 'kty'])
def test_ec_public_key_from_jwk(): keys = [] kspec = json.loads(open(full_path("jwk_private_ec_key.json")).read()) keys.append(key_from_jwk_dict(kspec, private=False)) key = keys[0] assert isinstance(key.x, (bytes, str)) assert isinstance(key.y, (bytes, str)) _d = key.to_dict() assert _eq(list(_d.keys()), ["x", "y", "alg", "crv", "kty"])
def test_jws_verifier_with_kid(): # Sign priv_key = key_from_jwk_dict( json.loads(test_vector.test_json_ecdsa_priv_key_kid1)) signer = JWS(test_vector.test_payload, **json.loads(test_vector.test_header_ecdsa_kid1)) signed_token_kid1 = signer.sign_compact([priv_key]) priv_key = key_from_jwk_dict( json.loads(test_vector.test_json_ecdsa_priv_key_kid2)) signer = JWS(test_vector.test_payload, **json.loads(test_vector.test_header_ecdsa_kid2)) signed_token_kid2 = signer.sign_compact([priv_key]) # Verify pub_key = key_from_jwk_dict( json.loads(test_vector.test_json_ecdsa_pub_key_kid1)) verifier = JWS(alg='ES256') assert verifier.verify_compact(signed_token_kid1, [pub_key]) # The signature is valid but the kids don't match. with pytest.raises(NoSuitableSigningKeys): verifier.verify_compact(signed_token_kid2, [pub_key])
def test_ec_private_key_from_jwk(): keys = [] kspec = json.loads(open(full_path("jwk_private_ec_key.json")).read()) keys.append(key_from_jwk_dict(kspec)) key = keys[0] assert isinstance(key.x, (bytes, str)) assert isinstance(key.y, (bytes, str)) assert isinstance(key.d, (bytes, str)) _d = key.to_dict() assert _eq(list(_d.keys()), ['alg', 'kty', 'crv', 'x', 'y', 'd']) assert _eq(list(_d.keys()), kspec.keys())
def verify_header(self, dpop_header) -> Optional["DPoPProof"]: _jws = factory(dpop_header) if _jws: _jwt = _jws.jwt if "jwk" in _jwt.headers: _pub_key = key_from_jwk_dict(_jwt.headers["jwk"]) _pub_key.deserialize() _info = _jws.verify_compact(keys=[_pub_key], sigalg=_jwt.headers["alg"]) for k, v in _jwt.headers.items(): self[k] = v for k, v in _info.items(): self[k] = v else: raise Exception() return self else: return None
def test_private_rsa_key_from_jwk(): keys = [] kspec = json.loads(open(full_path("jwk_private_key.json")).read()) keys.append(key_from_jwk_dict(kspec)) key = keys[0] assert isinstance(key.n, (bytes, str)) assert isinstance(key.e, (bytes, str)) assert isinstance(key.d, (bytes, str)) assert isinstance(key.p, (bytes, str)) assert isinstance(key.q, (bytes, str)) assert isinstance(key.dp, (bytes, str)) assert isinstance(key.dq, (bytes, str)) assert isinstance(key.qi, (bytes, str)) _d = key.to_dict() assert _eq(list(_d.keys()), [ 'n', 'alg', 'dq', 'e', 'q', 'p', 'dp', 'd', 'ext', 'key_ops', 'kty', 'qi' ]) assert _eq(list(_d.keys()), kspec.keys())
def test_key_from_jwk_dict_sym(): jwk = {"kty": "oct", "key": "abcdefghijklmnopq"} _key = key_from_jwk_dict(jwk) assert isinstance(_key, SYMKey) jwk = _key.serialize() assert jwk == {"kty": "oct", "k": "YWJjZGVmZ2hpamtsbW5vcHE"}
args = parser.parse_args() if args.kid: _kid = args.kid else: _kid = '' keys = [] if args.rsa_file: keys.append(RSAKey(key=import_rsa_key(args.rsa_file), kid=_kid)) if args.hmac_key: keys.append(SYMKey(key=args.hmac_key, kid=_kid)) if args.jwk: _key = key_from_jwk_dict(open(args.jwk).read()) keys.append(_key) if args.jwks: _k = KeyJar() _k.import_jwks(open(args.jwks).read(), "") keys.extend(_k.issuer_keys("")) if args.jwks_url: _kb = KeyBundle(source=args.jwks_url) keys.extend(_kb.get()) if not args.msg: # If nothing specified assume stdin message = sys.stdin.read() elif args.msg == "-": message = sys.stdin.read()
def deserialize(jwk: dict) -> JWK: k = key_from_jwk_dict(jwk) inactive = jwk.get("inactive_since", 0) if inactive: k.inactive_since = inactive return k
def test_key_from_jwk_dict_sym(): jwk = {'kty': 'oct', 'key': 'abcdefghijklmnopq'} _key = key_from_jwk_dict(jwk) assert isinstance(_key, SYMKey) jwk = _key.serialize() assert jwk == {'kty': 'oct', 'k': 'YWJjZGVmZ2hpamtsbW5vcHE'}
from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind=engine) session = Session() thing = Thing(owner='peppe', data=json.dumps(rsa_key.serialize(private=True))) # store in the alchemy_db, commit means we have in a transation session.add(thing) session.commit() # get an entry session.query(Thing).filter_by(owner='peppe').all() # get a key _key = key_from_jwk_dict( json.loads(session.query(Thing).filter_by(owner='peppe').all()[0].data)) # ====================================================================== # Storage Abstraction Layer class AbstractStorageSQLAlchemy: def __init__(self, conf_dict): self.engine = alchemy_db.create_engine(conf_dict['url']) self.connection = self.sengine.connect() self.metadata = alchemy_db.MetaData() self.table = alchemy_db.Table(conf_dict['params']['table'], self.metadata, autoload=True,
def import_jwk(filename): with open(filename) as jwk_file: jwk_dict = json.loads(jwk_file.read()) return key_from_jwk_dict(jwk_dict)