def test_sign_encrypt_id_token(): client_info = RegistrationResponse(id_token_signed_response_alg='RS512', client_id='client_1') session_info = { 'authn_req': AREQN, 'sub': 'sub', 'authn_event': { "authn_info": 'loa2', "authn_time": time.time() } } ENDPOINT_CONTEXT.jwx_def["signing_alg"] = {'id_token': 'RS384'} ENDPOINT_CONTEXT.cdb['client_1'] = client_info.to_dict() _token = sign_encrypt_id_token(ENDPOINT_CONTEXT, session_info, 'client_1', sign=True) assert _token _jws = jws.factory(_token) assert _jws.jwt.headers['alg'] == 'RS512' client_keyjar = KeyJar() _jwks = KEYJAR.export_jwks() client_keyjar.import_jwks(_jwks, ENDPOINT_CONTEXT.issuer) _jwt = JWT(keyjar=client_keyjar, iss='client_1') res = _jwt.unpack(_token) assert isinstance(res, JsonWebToken) assert res['aud'] == ['client_1']
def test_update_metadata_statement(): make_signing_sequence(['https://op.sunet.se', 'https://sunet.se', 'https://swamid.sunet.se'], ENTITY) op = ENTITY['https://op.sunet.se'] metadata_statement = MetadataStatement(foo='bar') metadata_statement = op.update_metadata_statement(metadata_statement) assert metadata_statement assert set(metadata_statement.keys()) == {'foo', 'metadata_statements'} swamid = ENTITY['https://swamid.sunet.se'] # on the RP side rp = FederationEntityOOB(None, 'https://rp.sunet.se') # Need the FO bundle, which in this case only needs Swamid's key jb = JWKSBundle('https://rp.sunet.se') _kj = KeyJar() _kj.import_jwks(swamid.self_signer.public_keys(), swamid.iss) jb['https://swamid.sunet.se'] = _kj rp.jwks_bundle = jb l = rp.get_metadata_statement(metadata_statement, MetadataStatement, 'discovery') assert l[0].iss == 'https://op.sunet.se' assert l[0].fo == 'https://swamid.sunet.se' assert l[0].le == {'foo':'bar'}
def __init__(self, state_db, ca_certs=None, client_authn_factory=None, keyjar=None, verify_ssl=True, config=None, client_cert=None, httplib=None, services=None, service_factory=None, jwks_uri=''): """ :param ca_certs: Certificates used to verify HTTPS certificates :param client_authn_factory: Factory that this client can use to initiate a client authentication class. :param keyjar: A py:class:`oidcmsg.key_jar.KeyJar` instance :param verify_ssl: Whether the SSL certificate should be verified. :param config: Configuration information passed on to the :py:class:`oidcservice.service_context.ServiceContext` initialization :param client_cert: Certificate used by the HTTP client :param httplib: A HTTP client to use :param services: A list of service definitions :param service_factory: A factory to use when building the :py:class:`oidcservice.service.Service` instances :param jwks_uri: A jwks_uri :return: Client instance """ self.state_db = state_db self.http = httplib or HTTPLib(ca_certs=ca_certs, verify_ssl=verify_ssl, client_cert=client_cert, keyjar=keyjar) if not keyjar: keyjar = KeyJar() keyjar.verify_ssl = verify_ssl self.events = None self.service_context = ServiceContext(keyjar, config=config, jwks_uri=jwks_uri) if self.service_context.client_id: self.client_id = self.service_context.client_id _cam = client_authn_factory or ca_factory self.service_factory = service_factory or service.factory _srvs = services or DEFAULT_SERVICES self.service = build_services(_srvs, self.service_factory, self.service_context, state_db, _cam) self.service_context.service = self.service self.verify_ssl = verify_ssl
def public_jwks_bundle(eids): jb_copy = JWKSBundle('') for eid in eids: jwks = ENTITY[eid].signing_keys_as_jwks() kj_copy = KeyJar() kj_copy.import_jwks(jwks, eid) jb_copy.bundle[eid] = kj_copy return jb_copy
def test_self_signed_jwks(): kj = KeyJar() kj.issuer_keys['abc'] = KEYJAR.issuer_keys[''] ssj = self_sign_jwks(kj, 'abc', kid='', lifetime=3600) assert ssj res = verify_self_signed_jwks(ssj) _kj = jwks_to_keyjar(res['jwks'], res['iss']) assert list(_kj.owners()) == ['abc'] assert len(_kj.get_signing_key('RSA',owner='abc')) == 2 assert len(_kj.get_signing_key('EC',owner='abc')) == 1
def test_request_signed_by_signing_keys(): kj = KeyJar() kj.issuer_keys['abc'] = KEYJAR.issuer_keys[''] msreq = MetadataStatement(signing_keys=json.dumps(JWKS)) smsreq = request_signed_by_signing_keys(kj, msreq, 'abc', 3600) assert smsreq res = verify_request_signed_by_signing_keys(smsreq) assert set(res.keys()) == {'ms', 'iss'} assert res['iss'] == 'abc'
def test_create_verify(): sign_keyjar = build_keyjar(KEYDEFS)[1] jb = make_jwks_bundle('https://example.com', ['fo0', 'fo1', 'fo2', 'fo3'], sign_keyjar, KEYDEFS) _jws = jb.create_signed_bundle() _jwks = sign_keyjar.export_jwks() kj = KeyJar() kj.import_jwks(_jwks, 'https://example.com') bundle = verify_signed_bundle(_jws, kj) assert bundle
def test_client_secret_jwt(): client_keyjar = KeyJar() client_keyjar[conf['issuer']] = KEYJAR.issuer_keys[''] # The only own key the client has a this point client_keyjar.add_symmetric('', client_secret, ['sig']) _jwt = JWT(client_keyjar, iss=client_id, sign_alg='HS256') _assertion = _jwt.pack({'aud': [conf['issuer']]}) request = {'client_assertion': _assertion, 'client_assertion_type': JWT_BEARER} authn_info = ClientSecretJWT(endpoint_context).verify(request) assert authn_info['client_id'] == client_id assert 'jwt' in authn_info
def public_jwks_bundle(jwks_bundle): jb_copy = JWKSBundle('') for fo, kj in jwks_bundle.bundle.items(): kj_copy = KeyJar() for owner in kj.owners(): public_keys_keyjar(kj, owner, kj_copy, owner) jb_copy.bundle[fo] = kj_copy return jb_copy
def test_web_signing_service(): _kj = KJ['https://swamid.sunet.se'] iss = InternalSigningService('https://swamid.sunet.se', _kj) _sms = iss.create( RegistrationRequest(redirect_uris=['https://example.com/rp/cb']), 'https://example.com/rp') _jwks = _kj.export_jwks() _vkj = KeyJar() _vkj.import_jwks(_jwks, 'https://swamid.sunet.se') wss = WebSigningServiceClient('https://swamid.sunet.se', 'https://swamid.sunet.se/mdss', 'https://example.com/rp', _vkj) response = Response(200, _sms, {'Location': 'https://swamid.sunet.se/mdss/abcdefg'}) _res = wss.parse_response(response) assert set(_res.keys()) == {'sms', 'loc'}
def __init__(self, ca_certs=None, verify_ssl=True, keyjar=None, client_cert=None): """ A base class for OAuth2 clients and servers :param ca_certs: the path to a CA_BUNDLE file or directory with certificates of trusted CAs :param verify_ssl: If True then the server SSL certificate is not verfied :param keyjar: A place to keep keys for signing/encrypting messages :param client_cert: local cert to use as client side certificate, as a single file (containing the private key and the certificate) or as a tuple of both file's path """ self.keyjar = keyjar or KeyJar(verify_ssl=verify_ssl) self.request_args = {"allow_redirects": False} self.cookiejar = FileCookieJar() self.ca_certs = ca_certs if ca_certs: if verify_ssl is False: raise ValueError( 'conflict: ca_certs defined, but verify_ssl is False') # Instruct requests to verify certificate against the CA cert # bundle located at the path given by `ca_certs`. self.request_args["verify"] = ca_certs elif verify_ssl: # Instruct requests to verify server certificates against the # default CA bundle provided by 'certifi'. See # http://docs.python-requests.org/en/master/user/advanced/#ca # -certificates self.request_args["verify"] = True else: # Instruct requests to not perform server cert verification. self.request_args["verify"] = False self.events = None self.req_callback = None if client_cert: self.request_args['cert'] = client_cert
def test_pack_and_unpack_ms_lev0(): cms = ClientMetadataStatement(signing_keys=FOP.signing_keys_as_jwks_json(), contacts=['*****@*****.**'], scope=['openid']) _jwt = FOP.pack_metadata_statement(cms, sign_alg='RS256') assert _jwt json_ms = unfurl(_jwt) # print(json_ms.keys()) assert set(json_ms.keys()) == { 'signing_keys', 'iss', 'iat', 'exp', 'kid', 'scope', 'contacts', 'aud' } # Unpack what you have packed _kj = KeyJar().import_jwks(FOP.signing_keys_as_jwks(), '') op = Operator(_kj, jwks_bundle=public_jwks_bundle(FOP.jwks_bundle)) pr = op.unpack_metadata_statement(jwt_ms=_jwt) assert pr.result
def get_jwks(private_path, keydefs, public_path): if os.path.isfile(private_path): _jwks = open(private_path, 'r').read() _kj = KeyJar() _kj.import_jwks(json.loads(_jwks), '') else: _kj = build_keyjar(keydefs)[1] jwks = _kj.export_jwks(private=True) head, tail = os.path.split(private_path) if not os.path.isdir(head): os.makedirs(head) fp = open(private_path, 'w') fp.write(json.dumps(jwks)) fp.close() jwks = _kj.export_jwks() # public part fp = open(public_path, 'w') fp.write(json.dumps(jwks)) fp.close() return _kj
#!/usr/bin/env python3 import sys import json from oidcmsg.key_jar import KeyJar keyjar = KeyJar() keyjar.import_jwks_as_json(open(sys.argv[1]).read(), '') print(keyjar.export_jwks_as_json(issuer=''))
'88aNu59aBn0elksaVznzoVKkdbT5B4euhOIEqJoFvFbEocw9mC4k-yozIAQSV5FEakoSPOl8lrymCoM3Q1fVHfaM9Rbb9RCRlsV1JOeVVZOE05HUdz8zOIqLBDEGM_oQqDwF_kp-4nDTZ1-dtnGdTo4Cf7QRuApzE_dwVabUCTc', 'q': '6LOHuM7H_0kDrMTwUEX7Aubzr792GoJ6EgTKIQY25SAFTZpYwuC3NnqlAdy8foIa3d7eGU2yICRbBG0S_ITcooDFrOa7nZ6enMUclMTxW8FwwvBXeIHo9cIsrKYtOThGplz43Cvl73MK5M58ZRmuhaNYa6Mk4PL4UokARfEiDus', 'use': 'sig' }, { 'crv': 'P-256', 'd': 'N2dg0-DAROBF8owQA4-uY5s0Ab-Fep_42kEFQG4BNVQ', 'kid': 'UnpYbi0tWC1HaEtyRFMtSmkyZDVHUHZVNDF0d21KTVk1dzEwYmhpNlVtQQ', 'kty': 'EC', 'use': 'sig', 'x': 'Ls8SqX8Ti5QAKtw3rdGr5K537-tqQCIbhyebeE_2C38', 'y': 'S-BrbPQkh8HVFLWg5Wid_5OAk4ewn5skHlHtG08ShaA' }] } OP_KEYJAR = KeyJar() OP_KEYJAR.import_jwks(JWKS_OP, '') OP_PUBLIC_JWKS = OP_KEYJAR.export_jwks() OP_BASEURL = "https://example.org/op" RP_JWKS = { "keys": [{ "kty": "RSA", "use": "sig", "kid": "Mk0yN2w0N3BZLWtyOEpQWGFmNDZvQi1hbDl2azR3ai1WNElGdGZQSFd6MA", "e": "AQAB", "n":
import requests from oidcmsg.jwt import JWT from oidcmsg.key_jar import KeyJar from oidcmsg.oidc import JsonWebToken EDIR = 'entities' EM = 'entity_metadata' for _dir in [EM]: if not os.path.isdir(_dir): os.makedirs(_dir) for _name in os.listdir(EDIR): fname = os.path.join(EDIR, _name) einfo = json.loads(open(fname).read()) keyjar = KeyJar() keyjar.import_jwks_as_json(einfo['signing_keys'], einfo['entity_id']) try: resp = requests.request('GET', einfo['metadata_endpoint'], verify=False) except Exception as err: continue if resp.status_code == 200: _jwt = JWT(keyjar) metadata_statement = _jwt.unpack(resp.text) # Remove the JWT attributes for attr in JsonWebToken.c_param.keys(): try:
# make sure the necessary directories are there for _dir in ['public', 'private', 'fo_bundle']: if not os.path.isdir(_dir): os.mkdir(_dir) # The kind of keys the federation entities has FED_KEYDEF = [{"type": "EC", "crv": "P-256", "use": ["sig"]}] # Identifiers for all the entities ALL = ['https://edugain.org', 'https://swamid.sunet.se'] _path = os.path.realpath(__file__) root_dir, _fname = os.path.split(_path) # Create the federation entities FEDENT = create_federation_entities(ALL, FED_KEYDEF, root_dir=root_dir) # create and load the key bundle bundle = FSJWKSBundle(iss='jra3t3', fdir='fo_bundle', key_conv={ 'to': quote_plus, 'from': unquote_plus }) for iss in ALL: kj = KeyJar() kj.import_jwks(FEDENT[iss].signing_keys_as_jwks(), iss) bundle[iss] = kj