示例#1
0
def test_remove_after():
    # initial keyjar
    keyjar = build_keyjar(KEYDEFS)[1]
    _old = [k.kid for k in keyjar.get_issuer_keys('') if k.kid]
    assert len(_old) == 2

    # rotate_keys = create new keys + make the old as inactive
    keyjar = build_keyjar(KEYDEFS, keyjar=keyjar)[1]

    keyjar.remove_after = 1
    # None are remove since none are marked as inactive yet
    keyjar.remove_outdated()

    _interm = [k.kid for k in keyjar.get_issuer_keys('') if k.kid]
    assert len(_interm) == 4

    # Now mark the keys to be inactivated
    _now = time.time()
    for k in keyjar.get_issuer_keys(''):
        if k.kid in _old:
            if not k.inactive_since:
                k.inactive_since = _now

    keyjar.remove_outdated(_now + 5)

    # The remainder are the new keys
    _new = [k.kid for k in keyjar.get_issuer_keys('') if k.kid]
    assert len(_new) == 2

    # should not be any overlap between old and new
    assert set(_new).intersection(set(_old)) == set()
示例#2
0
def make_fs_jwks_bundle(iss, fo_liss, sign_keyjar, keydefs, base_path=''):
    """
    Given a list of Federation identifiers creates a FSJWKBundle containing all
    the signing keys.

    :param iss: The issuer ID of the entity owning the JWKSBundle
    :param fo_liss: List with federation identifiers as keys
    :param sign_keyjar: Keys that the JWKSBundle owner can use to sign
        an export version of the JWKS bundle.
    :param keydefs: What type of keys that should be created for each
        federation. The same for all of them.
    :param base_path: Where the pem versions of the keys are stored as files
    :return: A FSJWKSBundle instance.
    """
    jb = FSJWKSBundle(iss, sign_keyjar, 'fo_jwks',
                      key_conv={'to': quote_plus, 'from': unquote_plus})

    jb.clear()  # start from scratch

    # Need to save the private parts on disc
    jb.bundle.value_conv['to'] = keyjar_to_jwks_private

    for entity in fo_liss:
        _name = entity.replace('/', '_')
        try:
            _ = jb[entity]
        except KeyError:
            fname = os.path.join(base_path, 'keys', "{}.key".format(_name))
            _keydef = copy.deepcopy(keydefs)
            _keydef[0]['key'] = fname

            _keyjar = build_keyjar(_keydef)[1]
            jb[entity] = _keyjar

    return jb
示例#3
0
def create_federation_entity(iss, jwks_dir, sup='', fo_jwks=None, ms_dir='',
                             entity=None, sig_keys=None, sig_def_keys=None):
    fname = os.path.join(ms_dir, quote_plus(sup))

    if fo_jwks:
        _keybundle = FSJWKSBundle('', fdir=fo_jwks,
                                  key_conv={'to': quote_plus,
                                            'from': unquote_plus})

        # Organisation information
        _kj = _keybundle[sup]
        signer = Signer(InternalSigningService(sup, _kj), ms_dir=fname)
    else:
        signer = Signer(ms_dir=fname)

    # And then the FOs public keys
    _public_keybundle = FSJWKSBundle('', fdir=jwks_dir,
                                     key_conv={'to': quote_plus,
                                               'from': unquote_plus})

    # The OPs own signing keys
    if sig_keys is None:
        sig_keys = build_keyjar(sig_def_keys)[1]

    return FederationEntity(entity, iss=iss, keyjar=sig_keys, signer=signer,
                            fo_bundle=_public_keybundle)
示例#4
0
    def rotate_keys(self, keyconf=None):
        _old = [k.kid for k in self.keyjar.get_issuer_keys('') if k.kid]

        if keyconf:
            self.keyjar = build_keyjar(keyconf, keyjar=self.keyjar)[1]
        else:
            self.keyjar = build_keyjar(self.keyconf, keyjar=self.keyjar)[1]

        self.keyjar.remove_after = self.remove_after
        self.keyjar.remove_outdated()

        _now = time.time()
        for k in self.keyjar.get_issuer_keys(''):
            if k.kid in _old:
                if not k.inactive_since:
                    k.inactive_since = _now
示例#5
0
def test_key_rotation():
    _keyjar = build_keyjar(KEYDEFS)[1]
    fo = FederationOperator(iss='https://example.com/op',
                            keyjar=_keyjar,
                            keyconf=KEYDEFS,
                            remove_after=1)
    fo.rotate_keys()
    assert len(fo.keyjar.get_issuer_keys('')) == 4
    time.sleep(1)
    fo.rotate_keys()
    assert len(fo.keyjar.get_issuer_keys('')) == 4
示例#6
0
def own_sign_keys(sigkey_name, issuer, sig_def_keys):
    try:
        jwks = json.loads(open(sigkey_name, 'r').read())
        sign_kj = KeyJar()
        sign_kj.import_jwks(jwks, issuer)
    except FileNotFoundError:
        jwks, sign_kj, _ = build_keyjar(sig_def_keys)
        sign_kj.issuer_keys[issuer] = sign_kj.issuer_keys['']
        fp = open(sigkey_name, 'w')
        fp.write(json.dumps(sign_kj.export_jwks(private=True, issuer=issuer)))
        fp.close()

    return sign_kj
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
示例#8
0
def test_build_keyjar_missing(tmpdir):
    keys = [{
        "type": "RSA",
        "key": os.path.join(tmpdir.dirname, "missisng_file"),
        "use": ["enc", "sig"]
    }]

    jwks, keyjar, kidd = build_keyjar(keys)

    assert len(keyjar[""]) == 1

    assert "RSA" in kidd["enc"]
    assert "RSA" in kidd["sig"]
示例#9
0
def test_ace():
    jb = JWKSBundle('')
    for iss in ['https://example.org/', 'https://example.com/']:
        jb[iss] = build_keyjar(KEYDEFS)[1]
    kj = build_keyjar(KEYDEFS)[1]

    sign_serv = InternalSigningService('https://signer.example.com',
                                       signing_keys=kj)
    signer = Signer(sign_serv)
    signer.metadata_statements['response'] = {
        'https://example.org/': 'https://example.org/sms1'
    }

    ent = FederationEntity(None,
                           keyjar=kj,
                           signer=signer,
                           fo_bundle=public_jwks_bundle(jb))
    req = MetadataStatement(foo='bar')
    ent.ace(req, ['https://example.org/'], 'response')

    assert 'metadata_statements' in req
    assert 'signing_keys' not in req
示例#10
0
def test_pack_metadata_statement_other_alg():
    _keyjar = build_keyjar(KEYDEFS)[1]
    op = Operator(keyjar=_keyjar, iss='https://example.com/')
    req = MetadataStatement(issuer='https://example.org/op')
    sms = op.pack_metadata_statement(req, alg='ES256')
    assert sms  # Should be a signed JWT
    _jwt = factory(sms)
    _body = json.loads(as_unicode(_jwt.jwt.part[1]))
    assert _body['iss'] == 'https://example.com/'

    # verify signature
    _kj = public_keys_keyjar(_keyjar, '', None, op.iss)
    r = _jwt.verify_compact(sms, _kj.get_signing_key(owner=op.iss))
    assert r
示例#11
0
def test_get_metadata_statement():
    jb = JWKSBundle('')
    for iss in ['https://example.org/', 'https://example.com/']:
        jb[iss] = build_keyjar(KEYDEFS)[1]

    op = Operator(keyjar=jb['https://example.com/'],
                  iss='https://example.com/')
    req = MetadataStatement(foo='bar')
    sms = op.pack_metadata_statement(req, alg='RS256')
    sms_dir = {'https://example.com': sms}
    req['metadata_statements'] = Message(**sms_dir)
    ent = FederationEntity(None, fo_bundle=public_jwks_bundle(jb))
    loe = ent.get_metadata_statement(req)
    assert loe
示例#12
0
def init(keydefs, tool_iss, liss, lifetime):
    # The FOs signing keys
    sig_keys = build_keyjar(keydefs)[1]
    key_bundle = make_fs_jwks_bundle(tool_iss, liss, sig_keys, keydefs, './')

    #sig_keys = build_keyjar(keydefs)[1]

    operator = {}

    for entity, _keyjar in key_bundle.items():
        _keyjar[''] = _keyjar[entity]
        operator[entity] = Operator(iss=entity, keyjar=_keyjar,
                                    lifetime=lifetime)

    return {'operator': operator, 'key_bundle': key_bundle}
示例#13
0
    def setup(self):
        mkey = [
            {
                "type": "RSA",
                "use": ["sig"]
            },
            {
                "type": "RSA",
                "use": ["sig"]
            },
            {
                "type": "RSA",
                "use": ["sig"]
            },
        ]

        skey = [
            {
                "type": "RSA",
                "use": ["sig"]
            },
        ]

        kj1 = build_keyjar(mkey)[1]
        kj2 = build_keyjar(skey)[1]
        self.keyjar = KeyJar()
        self.keyjar['A'] = kj1['']
        self.keyjar['B'] = kj2['']

        _jws = JWS('{"aud": "A"}', alg='RS256')
        sig_key = self.keyjar.get_signing_key('rsa', owner='A')[0]
        self.sjwt_a = _jws.sign_compact([sig_key])

        _jws = JWS('{"aud": "B"}', alg='RS256')
        sig_key = self.keyjar.get_signing_key('rsa', owner='B')[0]
        self.sjwt_b = _jws.sign_compact([sig_key])
示例#14
0
def make_jwks_bundle(iss, fo_liss, sign_keyjar, keydefs, base_path=''):
    """
    Given a list of Federation identifiers creates a FSJWKBundle containing all
    the signing keys.

    :param iss: The issuer ID of the entity owning the JWKSBundle
    :param fo_liss: List of federation identifiers
    :param sign_keyjar: Keys that the JWKSBundel owner can use to sign
        an export version of the JWKS bundle.
    :param keydefs: What type of keys that should be created for each
        federation. The same for all of them.
    :return: A JWKSBundle instance.
    """
    jb = JWKSBundle(iss, sign_keyjar)

    for entity in fo_liss:
        _keydef = copy.deepcopy(keydefs)
        _jwks, _keyjar, _kidd = build_keyjar(_keydef)
        jb[entity] = _keyjar

    return jb
示例#15
0
def get_signing_keys(eid, keydef, key_file):
    """
    If the *key_file* file exists then read the keys from there, otherwise
    create the keys and store them a file with the name *key_file*.

    :param eid: The ID of the entity that the keys belongs to
    :param keydef: What keys to create
    :param key_file: A file name
    :return: A :py:class:`oic.utils.keyio.KeyJar` instance
    """
    if os.path.isfile(key_file):
        kj = KeyJar()
        kj.import_jwks(json.loads(open(key_file, 'r').read()), eid)
    else:
        kj = build_keyjar(keydef)[1]
        # make it know under both names
        fp = open(key_file, 'w')
        fp.write(json.dumps(kj.export_jwks()))
        fp.close()
        kj.issuer_keys[eid] = kj.issuer_keys['']

    return kj
示例#16
0
def test_build_keyjar():
    keys = [
        {
            "type": "RSA",
            "use": ["enc", "sig"]
        },
        {
            "type": "EC",
            "crv": "P-256",
            "use": ["sig"]
        },
    ]

    jwks, keyjar, kidd = build_keyjar(keys)
    for key in jwks["keys"]:
        assert "d" not in key  # the JWKS shouldn't contain the private part
        # of the keys

    assert len(keyjar[""]) == 2  # 1 with RSA keys and 1 with EC key

    assert "RSA" in kidd["enc"]
    assert "RSA" in kidd["sig"]
    assert "EC" in kidd["sig"]
示例#17
0
    def test_unpack_aggregated_response(self):
        claims = {
            "address": {
                "street_address": "1234 Hollywood Blvd.",
                "locality": "Los Angeles",
                "region": "CA",
                "postal_code": "90210",
                "country": "US"
            },
            "phone_number": "+1 (555) 123-4567"
        }

        _keyjar = build_keyjar(KEYSPEC)[1]

        srv = JWT(_keyjar, iss='https://example.org/op/', sign_alg='ES256')
        _jwt = srv.pack(payload=claims)

        resp = OpenIDSchema(sub='diana',
                            given_name='Diana',
                            family_name='krall',
                            _claim_names={
                                'address': 'src1',
                                'phone_number': 'src1'
                            },
                            _claim_sources={'src1': {
                                'JWT': _jwt
                            }})

        public_keys_keyjar(_keyjar, '', self.cli_info.keyjar,
                           'https://example.org/op/')

        _resp = self.req.parse_response(resp.to_json(), self.cli_info)
        assert set(_resp.keys()) == {
            'sub', 'given_name', 'family_name', '_claim_names',
            '_claim_sources', 'address', 'phone_number'
        }
示例#18
0
def test_pack_metadata_statement():
    jb = FSJWKSBundle('',
                      None,
                      'fo_jwks',
                      key_conv={
                          'to': quote_plus,
                          'from': unquote_plus
                      })
    _keyjar = build_keyjar(KEYDEFS)[1]
    op = Operator(keyjar=_keyjar, jwks_bundle=jb, iss='https://example.com/')
    req = MetadataStatement(issuer='https://example.org/op')
    sms = op.pack_metadata_statement(req)
    assert sms  # Should be a signed JWT
    _jwt = factory(sms)
    assert _jwt
    assert _jwt.jwt.headers['alg'] == 'RS256'
    _body = json.loads(as_unicode(_jwt.jwt.part[1]))
    assert _body['iss'] == op.iss
    assert _body['issuer'] == 'https://example.org/op'

    # verify signature
    _kj = public_keys_keyjar(_keyjar, '', None, op.iss)
    r = _jwt.verify_compact(sms, _kj.get_signing_key(owner=op.iss))
    assert r
示例#19
0
from oicmsg.key_jar import build_keyjar
from oicmsg.key_jar import public_keys_keyjar

ISS = 'https://example.com'
ISS2 = 'https://example.org'

KEYDEFS = [{
    "type": "RSA",
    "key": '',
    "use": ["sig"]
}, {
    "type": "EC",
    "crv": "P-256",
    "use": ["sig"]
}]
SIGN_KEYS = build_keyjar(KEYDEFS)[1]

KEYJAR = {}

for iss in [
        'https://www.swamid.se', 'https://www.sunet.se',
        'https://www.feide.no', 'https://www.uninett.no'
]:
    KEYJAR[iss] = build_keyjar(KEYDEFS)[1]


def test_create():
    bundle = JWKSBundle(ISS, SIGN_KEYS)
    assert bundle

示例#20
0
from fedoicmsg.bundle import jwks_to_keyjar
from fedoicmsg.utils import request_signed_by_signing_keys
from fedoicmsg.utils import self_sign_jwks
from fedoicmsg.utils import verify_request_signed_by_signing_keys
from fedoicmsg.utils import verify_self_signed_jwks

from oicmsg.key_jar import KeyJar
from oicmsg.key_jar import build_keyjar

KEYDEFS = [
    {"type": "RSA", "use": ["sig"]},
    {"type": "RSA", "use": ["sig"]},
    {"type": "EC", "crv": "P-256", "use": ["sig"]}
]

JWKS, KEYJAR, _ = build_keyjar(KEYDEFS)


def test_jwks_to_keyjar():
    _kj = jwks_to_keyjar(JWKS)
    assert list(_kj.owners()) == ['']
    assert len(_kj.get_signing_key('RSA',owner='')) == 2
    assert len(_kj.get_signing_key('EC',owner='')) == 1


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
示例#21
0
KEYSPEC = [
    {
        "type": "RSA",
        "use": ["enc"]
    },
    {
        "type": "EC",
        "crv": "P-256",
        "use": ["enc"]
    },
]

RECEIVER = 'https://example.org/op'

keyjar = build_keyjar(KEYSPEC)[1]

# reading and writing to the same KeyJAr instance
public_keys_keyjar(keyjar, '', keyjar, RECEIVER)


def test_request_object_encryption():
    msg = AuthorizationRequest(state='ABCDE',
                               redirect_uri='https://example.com/cb',
                               response_type='code')

    conf = {
        'redirect_uris': ['https://example.com/cli/authz_cb'],
        'client_id': 'client_1',
        'client_secret': 'abcdefghijklmnop',
    }
示例#22
0
from oicmsg.jwt import JWT
from oicmsg.key_jar import build_keyjar, KeyJar
from oicmsg.oic import JsonWebToken

__author__ = 'Roland Hedberg'

BASE_PATH = os.path.abspath(
    os.path.join(os.path.dirname(__file__), "data/keys"))

keys = [
    {"type": "RSA", "key": os.path.join(BASE_PATH, "cert.key"),
     "use": ["enc", "sig"]},
    {"type": "EC", "crv": "P-256", "use": ["sig"]},
    {"type": "EC", "crv": "P-256", "use": ["enc"]}
]
jwks, keyjar, kidd = build_keyjar(keys)
issuer = 'https://fedop.example.org'
receiver = 'https://example.com'
keyjar[issuer] = keyjar['']  # just testing right !?
keyjar[receiver] = keyjar['']


def _eq(l1, l2):
    return set(l1) == set(l2)


def test_jwt_pack():
    _jwt = JWT(keyjar, lifetime=3600, iss=issuer).pack()

    assert _jwt
    assert len(_jwt.split('.')) == 3
示例#23
0
}, {
    "type": "EC",
    "crv": "P-256",
    "use": ["sig"]
}]

KEYS = {}
ISSUER = {}
OPERATOR = {}

for entity in ['fo', 'fo1', 'org', 'inter', 'admin', 'ligo', 'op']:
    fname = os.path.join(BASE_PATH, "{}.key".format(entity))
    _keydef = KEYDEFS[:]
    _keydef[0]['key'] = fname

    _jwks, _keyjar, _kidd = build_keyjar(_keydef)
    KEYS[entity] = {
        'jwks': json.dumps(_jwks),
        'keyjar': _keyjar,
        'kidd': _kidd
    }
    ISSUER[entity] = 'https://{}.example.org'.format(entity)
    OPERATOR[entity] = Operator(keyjar=_keyjar, iss=ISSUER[entity])

FOP = OPERATOR['fo']
FOP.jwks_bundle = JWKSBundle(FOP.iss)
FOP.jwks_bundle[FOP.iss] = FOP.keyjar

FO1P = OPERATOR['fo1']
FO1P.jwks_bundle = JWKSBundle(FO1P.iss)
FO1P.jwks_bundle[FO1P.iss] = FO1P.keyjar
示例#24
0
from oicmsg.key_jar import KeyJar
from oicmsg.key_jar import build_keyjar

TEST_ISS = "https://test.example.com"
KEYDEFS = [{
    "type": "RSA",
    "key": '',
    "use": ["sig"]
}, {
    "type": "EC",
    "crv": "P-256",
    "use": ["sig"]
}]

SIGN_KEYJAR = build_keyjar(KEYDEFS)[1]

FO = {
    'swamid': 'https://swamid.sunet.se',
    'feide': 'https://www.feide.no',
    'edugain': 'https://edugain.com',
    'example': 'https://example.com'
}
OA = {'sunet': 'https://sunet.se', 'uninett': 'https://uninett.no'}

SMS_DEF = {
    OA['sunet']: {
        "discovery": {
            FO['swamid']: [{
                'request': {},
                'requester': OA['sunet'],
示例#25
0
keym = [
    {
        "type": "RSA",
        "use": ["sig"]
    },
    {
        "type": "RSA",
        "use": ["sig"]
    },
    {
        "type": "RSA",
        "use": ["sig"]
    },
]

KEYJAR = build_keyjar(keys)[1]
IKEYJAR = build_keyjar(keys)[1]
IKEYJAR.issuer_keys['issuer'] = IKEYJAR.issuer_keys['']
del IKEYJAR.issuer_keys['']

KEYJARS = {}
for iss in ['A', 'B', 'C']:
    _kj = build_keyjar(keym)[1]
    _kj.issuer_keys[iss] = _kj.issuer_keys['']
    del _kj.issuer_keys['']
    KEYJARS[iss] = _kj


def url_compare(url1, url2):
    url1 = urlparse(url1)
    url2 = urlparse(url2)