def __init__(self):
     self.g_config = {}
     with open("../src/config/config.json") as j:
         self.g_config = json.load(j)
     wkh = WellKnownHandler(self.g_config["auth_server_url"], secure=False)
     self.__TOKEN_ENDPOINT = wkh.get(TYPE_OIDC, KEY_OIDC_TOKEN_ENDPOINT)
     #Generate ID Token
     _rsakey = RSA.generate(2048)
     _private_key = _rsakey.exportKey()
     _public_key = _rsakey.publickey().exportKey()
     file_out = open("private.pem", "wb")
     file_out.write(_private_key)
     file_out.close()
     file_out = open("public.pem", "wb")
     file_out.write(_public_key)
     file_out.close()
     _rsajwk = RSAKey(kid='RSA1', key=import_rsa_key(_private_key))
     _payload = { 
                 "iss": self.g_config["client_id"],
                 "sub": self.g_config["client_secret"],
                 "aud": self.__TOKEN_ENDPOINT,
                 "jti": datetime.datetime.today().strftime('%Y%m%d%s'),
                 "exp": int(time.time())+3600
             }
     _jws = JWS(_payload, alg="RS256")
     self.jwt = _jws.sign_compact(keys=[_rsajwk])
     self.scopes = 'public_access'
     self.resourceName = "TestResourcePEP10"
     self.PEP_HOST = "http://localhost:5566"
     status, self.resourceID = self.createTestResource()
     print(self.jwt)
     print(self.resourceID)
    def test_handle_authn_response_returns_id_token_for_verified_affiliation(
            self, signing_key_path, context, scope_value, affiliation):
        authn_req = AuthorizationRequest(
            scope='openid ' + scope_value,
            client_id='client1',
            redirect_uri='https://client.example.com',
            response_type='id_token')
        context.state[self.frontend.name] = {
            'oidc_request': authn_req.to_urlencoded()
        }
        internal_response = InternalResponse(
            AuthenticationInformation(None, str(datetime.now()),
                                      'https://idp.example.com'))
        internal_response.attributes['affiliation'] = [affiliation]
        internal_response.user_id = 'user1'

        resp = self.frontend.handle_authn_response(context, internal_response)
        auth_resp = AuthorizationResponse().from_urlencoded(
            urlparse(resp.message).fragment)

        id_token = IdToken().from_jwt(
            auth_resp['id_token'],
            key=[RSAKey(key=rsa_load(signing_key_path))])
        assert id_token['iss'] == self.frontend.base_url
        assert id_token['aud'] == ['client1']
        assert id_token['auth_time'] == internal_response.auth_info.timestamp
Exemple #3
0
def test_pjwt_with_jwe_jwk():
    keys = KEYS()
    keys.append(RSAKey(use="enc", key=rsa, kid="some-key-id"))

    jwe = JWE(alg="RSA-OAEP", enc="A256CBC-HS512")

    pj = PopJWT(
        "https://server.example.com",
        "https://client.example.org",
        sub="12345678",
        jwe=jwe,
        keys=keys,
    )

    jwk = {
        "kty": "oct",
        "alg": "HS256",
        "k": "ZoRSOrFzN_FzUA5XKMYoVHyzff5oRJxl-IXRtztJ6uE",
    }

    pjwt = pj.pack_jwe(jwk=jwk, kid="some-key-id")

    s = pjwt.to_json()

    de_pjwt = PJWT().from_json(s)
    assert _eq(de_pjwt.keys(), ["iss", "aud", "exp", "cnf", "sub", "iat"])
    assert list(de_pjwt["cnf"].keys()) == ["jwe"]
    _jwe = de_pjwt["cnf"]["jwe"]
    msg = jwe.decrypt(_jwe, keys.keys())
    assert msg

    assert json.loads(msg.decode("utf8")) == jwk
Exemple #4
0
 def __create_jwt(self):
     if self.jks_path != None:
         _rsajwk = RSAKey(kid=self._kid,
                          key=import_rsa_key_from_file(self.jks_path))
     else:
         _rsajwk = RSAKey(kid=self._kid,
                          key=import_rsa_key(self.__getRSAPrivateKey()))
     _payload = {
         "iss": self.client_id,
         "sub": self.client_id,
         "aud": self.__TOKEN_ENDPOINT,
         "jti": datetime.datetime.today().strftime('%Y%m%d%s'),
         "exp": int(time.time()) + 3600
     }
     _jws = JWS(_payload, alg="RS256")
     return _jws.sign_compact(keys=[_rsajwk])
Exemple #5
0
def rsa_init(spec):
    """
    Initiates a :py:class:`oicmsg.oauth.keybundle.KeyBundle` instance
    containing newly minted RSA keys according to a spec.
    
    Example of specification::
        {'name': 'myrsakey', 'path': 'keystore', 'size':2048, 
         'use': ['enc', 'sig'] }
         
    Using the spec above 2 RSA keys would be minted, one for 
    encryption and one for signing.
        
    :param spec:
    :return: KeyBundle
    """
    arg = {}
    for param in ["name", "path", "size"]:
        try:
            arg[param] = spec[param]
        except KeyError:
            pass

    kb = KeyBundle(keytype="RSA")
    for use in harmonize_usage(spec["use"]):
        _key = create_and_store_rsa_key_pair(use=use, **arg)
        kb.append(RSAKey(use=use, key=_key))
    return kb
Exemple #6
0
    def setup(self):
        httpretty.enable()

        self.key = RSAKey(kid='testkey').load(
            os.path.join(FIXTURE_ROOT, 'testkey.pem'))

        def jwks(_request, _uri, headers):  # noqa: E306
            ks = KEYS()
            ks.add(self.key.serialize())
            return 200, headers, ks.dump_jwks()

        httpretty.register_uri(httpretty.GET,
                               oidc_rp_settings.PROVIDER_JWKS_ENDPOINT,
                               status=200,
                               body=jwks)
        httpretty.register_uri(httpretty.POST,
                               oidc_rp_settings.PROVIDER_TOKEN_ENDPOINT,
                               body=json.dumps({
                                   'id_token': self.generate_jws(),
                                   'access_token': 'accesstoken',
                                   'refresh_token': 'refreshtoken',
                               }),
                               content_type='text/json')
        httpretty.register_uri(httpretty.GET,
                               oidc_rp_settings.PROVIDER_USERINFO_ENDPOINT,
                               body=json.dumps({
                                   'sub': '1234',
                                   'email': '*****@*****.**',
                               }),
                               content_type='text/json')

        yield

        httpretty.disable()
 def _add_key_to_keyjar(self, pkey, owner=''):
     kb = keyio.KeyBundle()
     priv_key = RSA.importKey(pkey)
     key = RSAKey().load_key(priv_key)
     key.use = "sig"
     kb.append(key)
     self.keyjar.add_kb(owner, kb)
Exemple #8
0
    def get_jwt_keys(self) -> list[Key]:
        """
        Takes a provider and returns the set of keys associated with it.
        Returns a list of keys.
        """
        if self.jwt_alg == JWTAlgorithms.RS256:
            # if the user selected RS256 but didn't select a
            # CertificateKeyPair, we fall back to HS256
            if not self.rsa_key:
                Event.new(
                    EventAction.CONFIGURATION_ERROR,
                    provider=self,
                    message=
                    "Provider was configured for RS256, but no key was selected.",
                ).save()
                self.jwt_alg = JWTAlgorithms.HS256
                self.save()
            else:
                # Because the JWT Library uses python cryptodome,
                # we can't directly pass the RSAPublicKey
                # object, but have to load it ourselves
                key = import_rsa_key(self.rsa_key.key_data)
                keys = [RSAKey(key=key, kid=self.rsa_key.kid)]
                if not keys:
                    raise Exception("You must add at least one RSA Key.")
                return keys

        if self.jwt_alg == JWTAlgorithms.HS256:
            return [SYMKey(key=self.client_secret, alg=self.jwt_alg)]

        raise Exception("Unsupported key algorithm.")
Exemple #9
0
def test_pjwt_unpack_jwe():
    keys = KEYS()
    keys.append(RSAKey(use="enc", key=rsa, kid="some-key-id"))

    pj = PopJWT("https://server.example.com",
                "https://client.example.org",
                sub="12345678")

    jwk = {
        "kty": "oct",
        "alg": "HS256",
        "k": "ZoRSOrFzN_FzUA5XKMYoVHyzff5oRJxl-IXRtztJ6uE",
    }

    jwe = JWE(json.dumps(jwk), alg="RSA-OAEP", enc="A256CBC-HS512")
    _jwe = jwe.encrypt(keys=keys.keys(), kid="some-key-id")

    pjwt = pj.pack_jwe(jwe=_jwe)

    s = pjwt.to_json()

    _jwt = PopJWT(jwe=jwe, keys=keys).unpack(s)

    assert _eq(_jwt.keys(), ["iss", "aud", "exp", "cnf", "sub", "iat"])
    assert _eq(_jwt["cnf"].keys(), ["jwk", "jwe"])

    assert _jwt["cnf"]["jwk"] == jwk
Exemple #10
0
def test_pjwt_with_jwe_jwk():
    keys = KEYS()
    keys.append(RSAKey(use="enc", key=rsa, kid="some-key-id"))

    jwe = JWE(alg="RSA-OAEP", enc="A256CBC-HS512")

    pj = PopJWT("https://server.example.com",
                "https://client.example.org",
                sub='12345678',
                jwe=jwe,
                keys=keys)

    jwk = {
        "kty": "oct",
        "alg": "HS256",
        "k": "ZoRSOrFzN_FzUA5XKMYoVHyzff5oRJxl-IXRtztJ6uE"
    }

    pjwt = pj.pack_jwe(jwk=jwk, kid='some-key-id')

    s = pjwt.to_json()

    de_pjwt = PJWT().from_json(s)
    assert _eq(de_pjwt.keys(), ['iss', 'aud', 'exp', 'cnf', 'sub', 'iat'])
    assert list(de_pjwt['cnf'].keys()) == ['jwe']
    _jwe = de_pjwt['cnf']['jwe']
    msg = jwe.decrypt(_jwe, keys.keys())
    assert msg

    assert json.loads(msg.decode('utf8')) == jwk
    def test_full_flow(self, account_linking_config, internal_response, context):
        ticket = "ticket"
        with responses.RequestsMock() as rsps:
            rsps.add(
                responses.GET,
                "%s/get_id" % account_linking_config["api_url"],
                status=404,
                body=ticket,
                content_type="text/html"
            )
            result = self.account_linking.process(context, internal_response)
        assert isinstance(result, Redirect)
        assert result.message.startswith(account_linking_config["redirect_url"])

        data = {
            "idp": internal_response.auth_info.issuer,
            "id": internal_response.user_id,
            "redirect_endpoint": self.account_linking.base_url + "/account_linking/handle_account_linking"
        }
        key = RSAKey(key=rsa_load(account_linking_config["sign_key"]), use="sig", alg="RS256")
        jws = JWS(json.dumps(data), alg=key.alg).sign_compact([key])
        uuid = "uuid"
        with responses.RequestsMock() as rsps:
            # account is linked, 200 OK
            rsps.add(
                responses.GET,
                "%s/get_id?jwt=%s" % (account_linking_config["api_url"], jws),
                status=200,
                body=uuid,
                content_type="text/html",
                match_querystring=True
            )
            internal_response = self.account_linking._handle_al_response(context)
        assert internal_response.user_id == uuid
Exemple #12
0
    def setUp(self):
        super().setUp()

        self.rsa_key_id = "1"
        # Generate RSA and save exports
        rsa_key = RSA.generate(2048)
        self.key = RSAKey(key=rsa_key, kid=self.rsa_key_id)
        self.public_key = rsa_key.publickey().export_key()

        self.xblock_attributes = {
            'lti_version': 'lti_1p3',
            'lti_1p3_launch_url': 'http://tool.example/launch',
            'lti_1p3_oidc_url': 'http://tool.example/oidc',
            # We need to set the values below because they are not automatically
            # generated until the user selects `lti_version == 'lti_1p3'` on the
            # Studio configuration view.
            'lti_1p3_tool_public_key': self.public_key,
            'has_score': True,
        }
        self.xblock = make_xblock('lti_consumer', LtiConsumerXBlock,
                                  self.xblock_attributes)
        # Set dummy location so that UsageKey lookup is valid
        self.xblock.location = 'block-v1:course+test+2020+type@problem+block@test'

        # Creates an LTI configuration objects for testing
        self.lti_1p1_config = LtiConfiguration.objects.create(
            location=str(self.xblock.location),
            version=LtiConfiguration.LTI_1P1)

        self.lti_1p3_config = LtiConfiguration.objects.create(
            location=str(self.xblock.location),
            version=LtiConfiguration.LTI_1P3)
Exemple #13
0
    def test_jws(self):
        keys = [
            SYMKey(key=TestMDQHandler.SYM_KEY_PHRASE, alg="HS256"),
            RSAKey(key=import_rsa_key_from_file(
                full_test_path("test_data/certs/rsa2048.pub"))),
            TestMDQHandler.EC_KEY
        ]

        # Test support for algorithms with supplied keys are working
        for alg in TestMDQHandler.SIGNING_ALGS_SUPPORTED:
            response = requests.get(
                TestMDQHandler.URL,
                params={MDQHandler.SIGNING_ALG_QUERY_PARAM: alg},
                headers=TestMDQHandler.HEADERS)

            payload = JWS().verify_compact(response.text, keys)
            assert json.loads(payload) == TestMDQHandler.METADATA_FROM_FILE[
                TestMDQHandler.CLIENT_ID]

        # Unsupported signing algorithm
        response = requests.get(
            TestMDQHandler.URL,
            params={MDQHandler.SIGNING_ALG_QUERY_PARAM: "PS256"},
            headers=TestMDQHandler.HEADERS)
        assert response.status_code == 400

        # Request signing with MDQ server without keys
        TestMDQHandler.MDQ = MDQHandler(TestMDQHandler.file_name, 36000)
        response = requests.get(
            TestMDQHandler.URL,
            params={MDQHandler.SIGNING_ALG_QUERY_PARAM: "PS256"},
            headers=TestMDQHandler.HEADERS)
        assert response.status_code == 400
    def setUpClass(cls):
        cls.g_config = {}
        with open("../src/config/config.json") as j:
            cls.g_config = json.load(j)

        wkh = WellKnownHandler(cls.g_config["auth_server_url"], secure=False)
        cls.__TOKEN_ENDPOINT = wkh.get(TYPE_OIDC, KEY_OIDC_TOKEN_ENDPOINT)

        _rsajwk = RSAKey(kid="RSA1",
                         key=import_rsa_key_from_file("../src/private.pem"))
        _payload = {
            "iss": cls.g_config["client_id"],
            "sub": cls.g_config["client_id"],
            "aud": cls.__TOKEN_ENDPOINT,
            "user_name": "admin",
            "jti": datetime.datetime.today().strftime('%Y%m%d%s'),
            "exp": int(time.time()) + 3600,
            "isOperator": False
        }
        _jws = JWS(_payload, alg="RS256")

        cls.jwt = _jws.sign_compact(keys=[_rsajwk])

        cls.scopes = 'protected_access'
        cls.PDP_HOST = "http://" + cls.g_config["host"]
        cls.PDP_PORT = cls.g_config["port"]
        cls.UID = cls.g_config["client_id"]
    def test_existing_account_linking_with_known_known_uuid(
            self, account_linking_config, internal_response, context):
        uuid = "uuid"
        data = {
            "idp":
            internal_response.auth_info.issuer,
            "id":
            internal_response.subject_id,
            "redirect_endpoint":
            self.account_linking.base_url +
            "/account_linking/handle_account_linking"
        }
        key = RSAKey(key=rsa_load(account_linking_config["sign_key"]),
                     use="sig",
                     alg="RS256")
        jws = JWS(json.dumps(data), alg=key.alg).sign_compact([key])
        responses.add(responses.GET,
                      "%s/get_id?jwt=%s" %
                      (account_linking_config["api_url"], jws),
                      status=200,
                      body=uuid,
                      content_type="text/html",
                      match_querystring=True)

        self.account_linking.process(context, internal_response)
        assert internal_response.subject_id == uuid
Exemple #16
0
    def __init__(self, config, callback_func):
        """
        :type config: satosa.satosa_config.SATOSAConfig
        :type callback_func:
        (satosa.context.Context, satosa.internal_data.InternalResponse) -> satosa.response.Response

        :param config: The SATOSA proxy config
        :param callback_func: Callback function when the linking is done
        """
        self.config = config
        self.callback_func = callback_func
        self.enabled = \
            "ACCOUNT_LINKING" in config and ("enable" not in config.ACCOUNT_LINKING or
                                             config.ACCOUNT_LINKING["enable"])
        if self.enabled:
            self.proxy_base = config.BASE
            self.al_rest_uri = config.ACCOUNT_LINKING["rest_uri"]
            self.al_redirect = config.ACCOUNT_LINKING["redirect"]
            self.endpoint = config.ACCOUNT_LINKING["endpoint"]
            self.verify_ssl = True if "verify_ssl" not in config.ACCOUNT_LINKING else \
                config.ACCOUNT_LINKING["verify_ssl"]
            _bkey = rsa_load(config.ACCOUNT_LINKING["sign_key"])
            self.sign_key = RSAKey().load_key(_bkey)
            self.sign_key.use = "sig"
            LOGGER.info("Account linking is active")
        else:
            LOGGER.info("Account linking is not active")
Exemple #17
0
def test_pjwt_unpack_jwe():
    keys = KEYS()
    keys.append(RSAKey(use="enc", key=rsa, kid="some-key-id"))

    pj = PopJWT("https://server.example.com",
                "https://client.example.org",
                sub='12345678')

    jwk = {
        "kty": "oct",
        "alg": "HS256",
        "k": "ZoRSOrFzN_FzUA5XKMYoVHyzff5oRJxl-IXRtztJ6uE"
    }

    jwe = JWE(json.dumps(jwk), alg="RSA-OAEP", enc="A256CBC-HS512")
    _jwe = jwe.encrypt(keys=keys.keys(), kid="some-key-id")

    pjwt = pj.pack_jwe(jwe=_jwe)

    s = pjwt.to_json()

    _jwt = PopJWT(jwe=jwe, keys=keys).unpack(s)

    assert _eq(_jwt.keys(), ['iss', 'aud', 'exp', 'cnf', 'sub', 'iat'])
    assert _eq(_jwt['cnf'].keys(), ['jwk', 'jwe'])

    assert _jwt['cnf']['jwk'] == jwk
Exemple #18
0
    def __call__(self):
        keyjar = self.conv.entity.keyjar
        self.conv.entity.original_keyjar = keyjar.copy()

        # invalidate the old key
        old_key_spec = self.op_args["old_key"]
        old_key = keyjar.keys_by_alg_and_usage('', old_key_spec['alg'],
                                               old_key_spec['use'])[0]
        old_key.inactive_since = time.time()

        # setup new key
        key_spec = self.op_args["new_key"]
        typ = key_spec["type"].upper()
        if typ == "RSA":
            kb = KeyBundle(keytype=typ, keyusage=key_spec["use"])
            kb.append(RSAKey(use=key_spec["use"][0]).load_key(
                RSA.generate(key_spec["bits"])))
        elif typ == "EC":
            kb = ec_init(key_spec)
        else:
            raise Unknown('keytype: {}'.format(typ))

        # add new key to keyjar with
        list(kb.keys())[0].kid = self.op_args["new_kid"]
        keyjar.add_kb("", kb)

        # make jwks and update file
        keys = []
        for kb in keyjar[""]:
            keys.extend(
                [k.to_dict() for k in list(kb.keys()) if not k.inactive_since])
        jwks = dict(keys=keys)
        with open(self.op_args["jwks_path"], "w") as f:
            f.write(json.dumps(jwks))
 def __init__(self, patch, config={}):
     Server.__init__(self)
     self.patch = patch
     self.session = None
     self.config = {
         'issuer': 'https://example.com',
     }
     self.config.update(config)
     self.authz_codes = {}
     self.access_tokens = {}
     self.client = {
         'test-client': {
             'client_name': 'Test Client',
             'client_secret': 'test-secret',
             'post_logout_redirect_uris': [
                 'http://localhost:5000/sign-out',
             ],
             'redirect_uris': [
                 'http://localhost:5000/oidc_callback',
             ],
             'response_types': ['code'],
         }
     }
     self.access_token_lifetime = 3600
     self.authorization_code_lifetime = 600
     self.id_token_lifetime = 3600
     self.registration_expires_in = 3600
     self.host = ''
     self.userinfo_signed_response_alg = ''
     self.signing_key = RSAKey(key=rsa_load('signing_key.pem'), alg='RS256')
     self.urls = []
Exemple #20
0
def init_oidc_provider(app):
    with app.app_context():
        issuer = url_for('oidc_provider.index')[:-1]
        authentication_endpoint = url_for('oidc_provider.authentication_endpoint')
        jwks_uri = url_for('oidc_provider.jwks_uri')
        token_endpoint = url_for('oidc_provider.token_endpoint')
        userinfo_endpoint = url_for('oidc_provider.userinfo_endpoint')
        registration_endpoint = url_for('oidc_provider.registration_endpoint')
        end_session_endpoint = url_for('oidc_provider.end_session_endpoint')
        userinfo_ldap = LdapUserInfo()

    configuration_information = {
        'issuer': issuer,
        'authorization_endpoint': authentication_endpoint,
        'jwks_uri': jwks_uri,
        'token_endpoint': token_endpoint,
        'userinfo_endpoint': userinfo_endpoint,
        'registration_endpoint': registration_endpoint,
        'end_session_endpoint': end_session_endpoint,
        'scopes_supported': ['openid', 'profile'],
        'response_types_supported': ['code', 'code id_token', 'code token', 'code id_token token'],  # code and hybrid
        'response_modes_supported': ['query', 'fragment'],
        'grant_types_supported': ['authorization_code', 'implicit'],
        'subject_types_supported': ['pairwise'],
        'token_endpoint_auth_methods_supported': ['client_secret_basic'],
        'claims_parameter_supported': True
    }

    signing_key = RSAKey(key=rsa_load('signing_key.pem'), alg='RS256')
    provider = Provider(signing_key, configuration_information,
                        AuthorizationState(HashBasedSubjectIdentifierFactory(app.config['SUBJECT_ID_HASH_SALT'])),
                        {}, userinfo_ldap)

    return provider
Exemple #21
0
def test_cmp_rsa_ec():
    _key1 = RSAKey()
    _key1.load_key(pem_cert2rsa(CERT))

    _key2 = ECKey(**ECKEY)

    assert _key1 != _key2
Exemple #22
0
def test_pop_jwe():
    jwk = {"kty": "oct", "alg": "HS256",
           "k": "ZoRSOrFzN_FzUA5XKMYoVHyzff5oRJxl-IXRtztJ6uE"}

    encryption_keys = [RSAKey(use="enc", key=rsa,
                              kid="some-key-id")]
    jwe = JWE(json.dumps(jwk), alg="RSA-OAEP", enc="A256CBC-HS512")
    _jwe = jwe.encrypt(keys=encryption_keys, kid="some-key-id")

    jwt = {
        "iss": "https://server.example.com",
        "aud": "https://client.example.org",
        "exp": 1361398824,
        "cnf": {
            "jwe": _jwe
        }
    }

    pjwt = PJWT(**jwt)

    s = pjwt.to_json()

    de_pjwt = PJWT().from_json(s)
    assert _eq(de_pjwt.keys(), ['iss', 'aud', 'exp', 'cnf'])
    assert list(de_pjwt['cnf'].keys()) == ['jwe']
    _jwe = de_pjwt['cnf']['jwe']
    msg = jwe.decrypt(_jwe, encryption_keys)
    assert msg

    assert json.loads(msg.decode('utf8')) == jwk
Exemple #23
0
def key_setup(vault, **kwargs):
    """
    :param vault: Where the keys are kept
    :return: 2-tuple: result of urlsplit and a dictionary with
        parameter name as key and url and value
    """
    vault_path = proper_path(vault)

    if not os.path.exists(vault_path):
        os.makedirs(vault_path)

    kb = KeyBundle()
    for usage in ["sig", "enc"]:
        if usage in kwargs:
            if kwargs[usage] is None:
                continue

            _args = kwargs[usage]
            if _args["alg"].upper() == "RSA":
                try:
                    _key = rsa_load('%s%s' % (vault_path, "pyoidc"))
                except Exception:
                    devnull = open(os.devnull, 'w')
                    with RedirectStdStreams(stdout=devnull, stderr=devnull):
                        _key = create_and_store_rsa_key_pair(path=vault_path)

                k = RSAKey(key=_key, use=usage)
                k.add_kid()
                kb.append(k)
    return kb
    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
Exemple #25
0
    def verify_JWT_token(self, token, key):
        try:
            header = str(token).split(".")[0]
            paddedHeader = header + '=' * (4 - len(header) % 4)
            decodedHeader = base64.b64decode(paddedHeader)
            #to remove byte-code
            decodedHeader_format = decodedHeader.decode('utf-8')
            decoded_str_header = json.loads(decodedHeader_format)

            payload = str(token).split(".")[1]
            paddedPayload = payload + '=' * (4 - len(payload) % 4)
            decoded = base64.b64decode(paddedPayload)
            #to remove byte-code
            decoded = decoded.decode('utf-8')
            decoded_str = json.loads(decoded)

            if self.getVerificationConfig() == True:
                if decoded_str_header['kid'] != "RSA1":
                    verificator = JWT_Verification()
                    result = verificator.verify_signature_JWT(token)
                else:
                    #validate signature for rpt
                    rsajwk = RSAKey(
                        kid="RSA1",
                        key=import_rsa_key_from_file("config/public.pem"))
                    dict_rpt_values = JWS().verify_compact(token,
                                                           keys=[rsajwk],
                                                           sigalg="RS256")

                    if dict_rpt_values == decoded_str:
                        result = True
                    else:
                        result = False

                if result == False:
                    self.logger.debug(
                        "Verification of the signature for the JWT failed!")
                    raise Exception
                else:
                    self.logger.debug("Signature verification is correct!")

            user_value = None
            if decoded_str.get(key):
                user_value = decoded_str[key]
            elif decoded_str.get("pct_claims"):
                if decoded_str.get("pct_claims").get(key):
                    user_value = decoded_str['pct_claims'][key]
            if isinstance(user_value,
                          list) and len(user_value) != 0 and user_value[0]:
                user_value = user_value[0]
            if user_value is None:
                raise Exception

            return user_value
        except Exception as e:
            self.logger.debug(
                "Authenticated RPT Resource. No Valid JWT id token passed! " +
                str(e))
            return None
Exemple #26
0
    def setUp(self):
        super().setUp()

        # Create custom LTI Block
        self.rsa_key_id = "1"
        rsa_key = RSA.generate(2048)
        self.key = RSAKey(
            key=rsa_key,
            kid=self.rsa_key_id
        )
        self.public_key = rsa_key.publickey().export_key()

        self.xblock_attributes = {
            'lti_version': 'lti_1p3',
            'lti_1p3_launch_url': 'http://tool.example/launch',
            'lti_1p3_oidc_url': 'http://tool.example/oidc',
            # Intentionally using the same key for tool key to
            # allow using signing methods and make testing easier.
            'lti_1p3_tool_public_key': self.public_key,

            # LTI NRPS related attributes
            'lti_1p3_enable_nrps': True
        }

        self.xblock = make_xblock('lti_consumer', LtiConsumerXBlock, self.xblock_attributes)

        # Set dummy location so that UsageKey lookup is valid
        self.xblock.location = 'block-v1:course+test+2020+type@problem+block@test'

        # Create configuration
        self.lti_config = LtiConfiguration.objects.create(
            location=str(self.xblock.location),
            version=LtiConfiguration.LTI_1P3,
        )
        # Preload XBlock to avoid calls to modulestore
        self.lti_config.block = self.xblock

        # Patch internal method to avoid calls to modulestore
        patcher = patch(
            'lti_consumer.models.LtiConfiguration.block',
            new_callable=PropertyMock,
            return_value=self.xblock
        )
        self.addCleanup(patcher.stop)
        self._lti_block_patch = patcher.start()

        self.context_membership_endpoint = reverse(
            'lti_consumer:lti-nrps-memberships-view-list',
            kwargs={
                "lti_config_id": self.lti_config.id
            }
        )

        batch_external_id_patcher = patch(
            'lti_consumer.plugin.views.compat.batch_get_or_create_externalids',
            return_value=ExternalIDMapping()
        )

        self._batch_external_id_patcher = batch_external_id_patcher.start()
Exemple #27
0
    def _get_oidc_mocks(self):
        private_key = RSA.generate(2048)
        generatedjwk = RSAKey(key=private_key.publickey()).serialize()
        kid = "somekey"
        private_pem = private_key.exportKey("PEM")

        token_data = {
            "iss": app.config["TESTOIDC_LOGIN_CONFIG"]["OIDC_SERVER"],
            "aud": app.config["TESTOIDC_LOGIN_CONFIG"]["CLIENT_ID"],
            "nbf": int(time.time()),
            "iat": int(time.time()),
            "exp": int(time.time() + 600),
            "sub": "cool.user",
        }

        token_headers = {
            "kid": kid,
        }

        id_token = jwt.encode(token_data, private_pem, "RS256", headers=token_headers)

        @urlmatch(netloc=r"fakeoidc", path="/token")
        def token_handler(_, request):
            if request.body.find("code=somecode") >= 0:
                content = {"access_token": "someaccesstoken", "id_token": id_token.decode("ascii")}
                return py_json.dumps(content)
            else:
                return {"status_code": 400, "content": '{"message": "Invalid code"}'}

        @urlmatch(netloc=r"fakeoidc", path="/user")
        def user_handler(_, __):
            content = {
                "sub": "cool.user",
                "preferred_username": "******",
                "email": "*****@*****.**",
                "email_verified": True,
            }
            return py_json.dumps(content)

        @urlmatch(netloc=r"fakeoidc", path="/jwks")
        def jwks_handler(_, __):
            jwk = generatedjwk.copy()
            jwk.update({"kid": kid})

            content = {"keys": [jwk]}
            return py_json.dumps(content)

        @urlmatch(netloc=r"fakeoidc", path=".+openid.+")
        def discovery_handler(_, __):
            content = {
                "scopes_supported": ["profile"],
                "authorization_endpoint": "http://fakeoidc/authorize",
                "token_endpoint": "http://fakeoidc/token",
                "userinfo_endpoint": "http://fakeoidc/userinfo",
                "jwks_uri": "http://fakeoidc/jwks",
            }
            return py_json.dumps(content)

        return (discovery_handler, jwks_handler, token_handler, user_handler)
    def setup(self):
        self.consent_db = ConsentDatasetDB("salt", 12)
        self.ticket_db = ConsentRequestDatasetDB("salt")
        self.max_month = 12
        self.signing_key = RSAKey(key=RSA.generate(1024), alg='RS256')

        self.cm = ConsentManager(self.consent_db, self.ticket_db,
                                 [self.signing_key], 3600, self.max_month)
Exemple #29
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
Exemple #30
0
def signing_key():
    private_key = RSA.generate(2048)
    jwk = RSAKey(key=private_key.publickey()).serialize()
    return {
        "id": "somekey",
        "private_key": private_key.exportKey("PEM"),
        "jwk": jwk,
    }