Beispiel #1
0
def test_cmp_rsa_ec():
    _key1 = RSAKey()
    _key1.load_key(pem_cert2rsa(CERT))

    _key2 = ECKey(**ECKEY)

    assert _key1 != _key2
    def __init__(self, public_key=None, keyset_url=None):
        """
        Instance message validator

        Import a public key from the tool by either using a keyset url
        or a combination of public key + key id.

        Keyset URL takes precedence because it makes key rotation easier to do.
        """
        # Only store keyset URL to avoid blocking the class
        # instancing on an external url, which is only used
        # when validating a token.
        self.keyset_url = keyset_url
        self.public_key = None

        # Import from public key
        if public_key:
            try:
                new_key = RSAKey(use='sig')

                # Unescape key before importing it
                raw_key = codecs.decode(public_key, 'unicode_escape')

                # Import Key and save to internal state
                new_key.load_key(RSA.import_key(raw_key))
                self.public_key = new_key
            except ValueError as err:
                raise exceptions.InvalidRsaKey() from err
Beispiel #3
0
def test_cmp_rsa_ec():
    _key1 = RSAKey()
    _key1.load_key(pem_cert2rsa(CERT))

    _key2 = ECKey(**ECKEY)

    assert _key1 != _key2
Beispiel #4
0
def test_extract_rsa_from_cert_2():
    _ckey = pem_cert2rsa(CERT)
    _key = RSAKey()
    _key.load_key(_ckey)

    print(_key)

    assert _ckey.n == _key.get_key().n
Beispiel #5
0
def test_cmp_rsa():
    _key1 = RSAKey()
    _key1.load_key(pem_cert2rsa(CERT))

    _key2 = RSAKey()
    _key2.load_key(pem_cert2rsa(CERT))

    assert _key1 == _key2
Beispiel #6
0
def test_extract_rsa_from_cert_2():
    _ckey = pem_cert2rsa(CERT)
    _key = RSAKey()
    _key.load_key(_ckey)

    print(_key)

    assert _ckey.n == _key.get_key().n
Beispiel #7
0
def test_cmp_rsa():
    _key1 = RSAKey()
    _key1.load_key(pem_cert2rsa(CERT))

    _key2 = RSAKey()
    _key2.load_key(pem_cert2rsa(CERT))

    assert _key1 == _key2
Beispiel #8
0
def test_kspec():
    _ckey = pem_cert2rsa(CERT)
    _key = RSAKey()
    _key.load_key(_ckey)

    print(_key)
    jwk = _key.serialize()
    assert jwk["kty"] == "RSA"
    assert jwk["e"] == JWK["keys"][0]["e"]
    assert jwk["n"] == JWK["keys"][0]["n"]
Beispiel #9
0
def test_kspec():
    _ckey = pem_cert2rsa(CERT)
    _key = RSAKey()
    _key.load_key(_ckey)

    print(_key)
    jwk = _key.serialize()
    assert jwk["kty"] == "RSA"
    assert jwk["e"] == JWK["keys"][0]["e"].encode("utf-8")
    assert jwk["n"] == JWK["keys"][0]["n"].encode("utf-8")
Beispiel #10
0
def test_cmp_rsa_ec():
    _key1 = RSAKey()
    _key1.load_key(pem_cert2rsa(CERT))

    _key2 = ECKey(**ECKEY)

    try:
        assert _key1 == _key2
    except AssertionError:
        pass
    else:
        assert False
Beispiel #11
0
def test_cmp_rsa_ec():
    _key1 = RSAKey()
    _key1.load_key(pem_cert2rsa(CERT))

    _key2 = ECKey(**ECKEY)

    try:
        assert _key1 == _key2
    except AssertionError:
        pass
    else:
        assert False
Beispiel #12
0
def keybundle_from_local_file(filename, typ, usage, kid):
    if typ.upper() == "RSA":
        kb = KeyBundle()
        k = RSAKey(kid=kid)
        k.load(filename)
        k.use = usage[0]
        kb.append(k)
        for use in usage[1:]:
            _k = RSAKey(kid=kid + "1")
            _k.use = use
            _k.load_key(k.key)
            kb.append(_k)
    elif typ.lower() == "jwk":
        kb = KeyBundle(source=filename, fileformat="jwk", keyusage=usage)
    else:
        raise UnknownKeyType("Unsupported key type")
    return kb
Beispiel #13
0
def keybundle_from_local_file(filename, typ, usage, kid):
    if typ.upper() == "RSA":
        kb = KeyBundle()
        k = RSAKey(kid=kid)
        k.load(filename)
        k.use = usage[0]
        kb.append(k)
        for use in usage[1:]:
            _k = RSAKey(kid=kid + "1")
            _k.use = use
            _k.load_key(k.key)
            kb.append(_k)
    elif typ.lower() == "jwk":
        kb = KeyBundle(source=filename, fileformat="jwk", keyusage=usage)
    else:
        raise UnknownKeyType("Unsupported key type")
    return kb
Beispiel #14
0
def test_verify_2():
    _key = RSAKey()
    _key.load_key(pem_cert2rsa(CERT))
    assert _key.verify()
Beispiel #15
0
def test_verify_2():
    _key = RSAKey()
    _key.load_key(pem_cert2rsa(CERT))
    assert _key.verify()
Beispiel #16
0
def vetting_result():
    if not current_app.config.get('FREJA_CALLBACK_X5T_CERT'):
        current_app.logger.info('Configuration error: FREJA_CALLBACK_X5T_CERT is not set')
        return make_response('Configuration error', 500)

    _freja_callback_x5t_cert = current_app.config.get('FREJA_CALLBACK_X5T_CERT')
    _freja_callback_x5t_pub_key = RSA.importKey(_freja_callback_x5t_cert)
    _freja_callback_rsa_pub_key = RSAKey()
    _freja_callback_rsa_pub_key.load_key(_freja_callback_x5t_pub_key)

    current_app.logger.debug('flask.request.headers: \'{!s}\''.format(flask.request.headers))
    current_app.logger.debug('flask.request.data: \'{!s}\''.format(flask.request.get_data()))

    try:
        if flask.request.headers['Content-Type'] == 'application/jose':
            current_app.logger.info('Received a callback with MIME application/jose')
        else:
            current_app.logger.info('Received a callback with an invalid MIME: \'{!s}\''
                                    .format(flask.request.headers['Content-Type']))
            return make_response('Invalid MIME', 400)
    except KeyError:
        current_app.logger.info('Received a callback without a MIME')
        return make_response('No MIME specified', 400)

    try:
        data = flask.request.get_json(force=True)
    except:
        current_app.logger.info('Invalid verisec callback: missing or invalid JSON')
        return make_response('missing or invalid JSON', 400)

    if not data:
        current_app.logger.info('Invalid verisec callback: no JSON data provided')
        return make_response('Missing JSON data', 400)

    ia_response_data = data.get('iaResponseData')

    if not ia_response_data:
        current_app.logger.info('Missing iaResponseData in verisec callback: \'{!s}\''.format(data))
        return make_response('Missing iaResponseData', 400)

    current_app.logger.info('Received verisec iaResponseData: \'{!s}\''.format(ia_response_data))

    jws_parts = ia_response_data.split('.')

    # A correctly formatted JWS is made up of 3 parts
    if len(jws_parts) != 3:
        current_app.logger.info('iaResponseData response doesn\'t seems to be a JWS')
        return make_response('iaResponseData is not a JWS', 400)

    # This is for testing only and therefore we do not verify the JWS yet
    unverified_header = jws_parts[0]
    unverified_payload = jws_parts[1]

    # It should be possible to base64 decode the header and payload
    try:
        # urlsafe_b64decode returns bytes object so we decode to get str aka utf8
        unverified_header_decoded = urlsafe_b64decode(unverified_header + '=' * (4 - (len(unverified_header) % 4))).decode('utf8')
        unverified_payload_decoded = urlsafe_b64decode(unverified_payload + '=' * (4 - (len(unverified_payload) % 4))).decode('utf8')
    except UnicodeDecodeError:
        current_app.logger.info('Couldn\'t urlsafe_b64decode iaResponseData because it contains invalid UTF-8')
        return make_response('Incorrect UTF-8 in iaResponseData', 400)
    except binascii.Error:
        current_app.logger.info('Couldn\'t urlsafe_b64decode iaResponseData because non-base64 digit found')
        return make_response('Incorrect UTF-8 in iaResponseData', 400)
    except TypeError:
        current_app.logger.info('Couldn\'t urlsafe_b64decode iaResponseData')
        return make_response('Incorrect base64 encoded iaResponseData', 400)

    try:
        json.loads(unverified_header_decoded)
        json.loads(unverified_payload_decoded)
    except JSONDecodeError:
        current_app.logger.info('Incorrect UTF-8 BOM or invalid JSON data from base64 decoded iaResponseData')
        return make_response('Incorrectly encoded JSON in base64 decoded iaResponseData', 400)
    except TypeError:
        current_app.logger.info('JSON in base64 decoded iaResponseData is not str')
        return make_response('Incorrectly encoded JSON in base64 decoded iaResponseData', 400)

    try:
        verified_payload = JWS().verify_compact(ia_response_data, keys=[_freja_callback_rsa_pub_key], sigalg='RS256')
    except BadSignature as e:
        current_app.logger.info('The JWS was not properly signed')
        return make_response('Invalid signature', 400)
    except Exception as e:
        current_app.logger.info(str(e))
        return make_response('Invalid JWS', 400)

    try:
        verified_payload_country = verified_payload.pop('country')
        verified_payload_opaque = verified_payload.pop('opaque') # The opaque contains nonce and token
        verified_payload_ref = verified_payload.pop('ref')
        verified_payload_ssn = verified_payload.pop('ssn')
    except KeyError:
        current_app.logger.info('The verified JWS payload is missing some required claims')
        return make_response('The verified JWS payload is missing some required claims', 400)

    # Make sure that we have processed all claims in the payload
    if len(verified_payload) == 0:

        try:
            verified_opaque_deserialized = parse_opaque_data(verified_payload_opaque)
        except InvalidOpaqueDataError as e:
            # This is by design since we want the message from this exception
            return make_response(str(e), 400)

        if verified_opaque_deserialized['nonce'] == current_app.config.get('FREJA_TEST_NONCE', None):
            current_app.logger.info('Received a valid callback-test')
            return make_response('OK', 200)

        auth_req_data = current_app.authn_requests.pop(verified_opaque_deserialized['nonce'], None)
        if not auth_req_data:
            current_app.logger.info('Unknown nonce in verified JWS payload: \'{!s}\''.format(verified_opaque_deserialized['nonce']))
            return make_response('Unknown nonce in verified JWS payload', 400)

        user_id = str(uuid.uuid4())

        current_app.users[user_id] = {
            'results': {
                'freja_eid': {
                    'vetting_time': time.time(),
                    'country': verified_payload_country,
                    'opaque': verified_payload_opaque,
                    'ref': verified_payload_ref,
                    'ssn': verified_payload_ssn,
                }
            }
        }

        auth_req = AuthorizationRequest(**auth_req_data)
        authn_response = create_authentication_response(auth_req=auth_req,
                                                        user_id=user_id,
                                                        extra_userinfo=extra_userinfo)

        response_url = authn_response.request(auth_req['redirect_uri'], should_fragment_encode(auth_req))
        headers = {'Authorization': 'Bearer {}'.format(verified_opaque_deserialized['token'])}
        current_app.authn_response_queue.enqueue(deliver_response_task, response_url, headers=headers)

        return make_response('OK', 200)

    current_app.logger.info('Received an invalid verisec callback')
    return make_response('Invalid request', 400)