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)
Example #2
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.")
Example #3
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')

    configuration_information = {
        'issuer': issuer,
        'authorization_endpoint': authentication_endpoint,
        'jwks_uri': jwks_uri,
        'token_endpoint': token_endpoint,
        'userinfo_endpoint': userinfo_endpoint,
        'scopes_supported': ['openid'],
        '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
    }

    clients_db = OpStorageWrapper(app.config['DB_URI'], 'clients')
    userinfo_db = Userinfo(app.users)
    with open(app.config['PROVIDER_SIGNING_KEY']['PATH']) as f:
        key = f.read()
    signing_key = RSAKey(key=import_rsa_key(key), kid=app.config['PROVIDER_SIGNING_KEY']['KID'], alg='RS256')
    provider = Provider(signing_key, configuration_information, init_authorization_state(app), clients_db, userinfo_db)

    provider.authentication_request_validators.append(_request_contains_nonce)

    return provider
Example #4
0
    def test_jwks_endpoint(self):
        resp = self.app.test_client().get('/jwks')
        assert resp.status_code == 200
        jwks = json.loads(resp.data.decode('utf-8'))
        assert len(jwks['keys']) == 1
        jwks_key = RSAKey(**jwks['keys'][0])

        basename = os.path.dirname(os.path.realpath(__file__))
        with open(os.path.join(basename, '../private.pem')) as f:
            expected_key = RSAKey(key=import_rsa_key(f.read()), kid=jwks_key.kid, alg='RS256')

        assert jwks_key == expected_key
Example #5
0
 def add_issuer_key(self, private_key):
     """
     Adds a private key to the list of keys available for decryption and signatures
     :return: Boolean - Whether the key is already in the list
     """
     new_key = RSAKey(key=import_rsa_key(private_key),
                      kid=self.__generate_key_id(private_key))
     for key in self.issuer_private_keys:
         if new_key.kid == key.kid:
             return False
     self.issuer_private_keys.append(new_key)
     self.loaded_issuer_private_keys[new_key.kid] = PKCS1_OAEP.new(
         RSA.importKey(private_key))
Example #6
0
    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)

        #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()

        #Admin JWT
        _rsajwk = RSAKey(kid='RSA1', key=import_rsa_key(_private_key))
        _payload = { 
                    "iss": cls.g_config["client_id"],
                    "sub": cls.g_config["client_id"],
                    "aud": cls.__TOKEN_ENDPOINT,
                    "jti": datetime.datetime.today().strftime('%Y%m%d%s'),
                    "exp": int(time.time())+3600,
                    "isOperator": False
                }
        _jws = JWS(_payload, alg="RS256")
        cls.jwt_admin = _jws.sign_compact(keys=[_rsajwk])

        #ROTest user JWT
        _payload = { 
                    "iss": cls.g_config["client_id"],
                    "sub": "54d10251-6cb5-4aee-8e1f-f492f1105c94",
                    "aud": cls.__TOKEN_ENDPOINT,
                    "jti": datetime.datetime.today().strftime('%Y%m%d%s'),
                    "exp": int(time.time())+3600,
                    "isOperator": False
                }
        _jws = JWS(_payload, alg="RS256")
        cls.jwt_rotest = _jws.sign_compact(keys=[_rsajwk])

        cls.scopes = 'public_access'
        cls.resourceName = "TestROChangePEP"
        cls.PEP_HOST = "http://localhost:5566"
Example #7
0
 def add_issuer_key(self, private_key):
     """
     Adds a private key to the list of keys available for decryption
     and signatures
     :return: Boolean - Whether the key is already in the list
     """
     new_key = RSAKey(key=import_rsa_key(private_key),
                      kid=self.__generate_key_id(private_key))
     for key in self.issuer_private_keys:
         if new_key.kid == key.kid:
             return False
     self.issuer_private_keys.append(new_key)
     self.loaded_issuer_private_keys[new_key.kid] = PKCS1_OAEP.new(
         RSA.importKey(private_key))
     return True
Example #8
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])
Example #9
0
def _extract_x509_certificates(x509_certificates):
    keys = []
    for kid, certificate in x509_certificates.iteritems():
        try:
            if certificate.startswith(jwk.PREFIX):
                # The certificate is PEM-encoded
                der = ssl.PEM_cert_to_DER_cert(certificate)
                key = jwk.der2rsa(der)
            else:
                key = jwk.import_rsa_key(certificate)
        except Exception as exception:
            raise UnauthenticatedException(u"Cannot load X.509 certificate",
                                           exception)
        rsa_key = jwk.RSAKey().load_key(key)
        rsa_key.kid = kid
        keys.append(rsa_key)
    return keys
Example #10
0
    def clientPayloadCreation(self,
                              clientName,
                              grantTypes,
                              redirectURIs,
                              logoutURI,
                              responseTypes,
                              scopes,
                              sectorIdentifier,
                              token_endpoint_auth_method,
                              useJWT=0):
        # Check the auth method is allowed by Auth Server.
        # Since this value can change dynamically, we check it each time this function is called.
        allowed_auth_methods = self.wkh.get(
            TYPE_OIDC, KEY_OIDC_SUPPORTED_AUTH_METHODS_TOKEN_ENDPOINT)
        if token_endpoint_auth_method not in allowed_auth_methods:
            raise Exception("Auth method '" + token_endpoint_auth_method +
                            "' is not currently allowed by Auth Server: " +
                            str(allowed_auth_methods))

        payload = "{ \"client_name\": \"" + clientName + "\", \"grant_types\":["
        for grant in grantTypes:
            payload += "\"" + grant.strip() + "\", "
        payload = payload[:-2] + "], \"redirect_uris\" : ["
        for uri in redirectURIs:
            payload += "\"" + uri.strip() + "\", "
        payload = payload[:
                          -2] + "], \"post_logout_redirect_uris\": [\"" + logoutURI + "\"], \"scope\": \""
        for scope in scopes:
            payload += scope.strip() + " "
        payload = payload[:-1] + "\", "
        if sectorIdentifier is not None:
            payload += "\"sector_identifier_uri\": "
            payload += "\"" + sectorIdentifier.strip() + "\", "
            payload = payload[:-2] + ", "
        payload += "\"response_types\": [  "
        for response in responseTypes:
            payload += "\"" + response.strip() + "\",  "
        payload = payload[:-2] + "]"
        if useJWT == 1:
            payload += ", \"jwks\": {\"keys\": [ " + str(
                RSAKey(kid=self._kid,
                       key=import_rsa_key(self.__getRSAPublicKey()))) + "]}"
        payload += ", \"token_endpoint_auth_method\": \"" + token_endpoint_auth_method + "\""
        payload += "}"
        return payload
Example #11
0
    def _cache_public_key(self, kid, public_key):
        """
        Generate an RSAKey with the public key, and store within the public
        key cache. This only occurs if an RSAKey has not already been cached
        for the given `kid` and public key.
        :param kid: string of the `kid`
        :param public_key: string of the public key
        :return:
        """
        if not self._public_key_cache.get(kid):
            try:
                rsa_key = RSAKey(key=import_rsa_key(public_key), kid=kid)

            except (TypeError, ValueError):
                raise UnexpectedAPIResponse("RSA parsing error for public key"
                                            ": %s" % public_key)

            self._public_key_cache[kid] = rsa_key
Example #12
0
    def assert_registstration_req(self, request, sign_key_str):
        split_path = request.path_url.lstrip("/").split("/")
        assert len(split_path) == 2

        jwks = split_path[1]

        # Verify signature
        public_key = import_rsa_key(private_to_public_key(sign_key_str))
        sign_key = RSAKey().load_key(public_key)
        sign_key.use = "sig"
        _jw = jws.factory(jwks)
        _jw.verify_compact(jwks, [sign_key])

        # Verify JWT
        _jwt = JWT().unpack(jwks)
        consent_args = _jwt.payload()

        assert "attr" in consent_args
        assert "redirect_endpoint" in consent_args
        assert "id" in consent_args
Example #13
0
    def assert_registstration_req(self, request, sign_key_str):
        split_path = request.path_url.lstrip("/").split("/")
        assert len(split_path) == 2

        jwks = split_path[1]

        # Verify signature
        public_key = import_rsa_key(private_to_public_key(sign_key_str))
        sign_key = RSAKey().load_key(public_key)
        sign_key.use = "sig"
        _jw = jws.factory(jwks)
        _jw.verify_compact(jwks, [sign_key])

        # Verify JWT
        _jwt = JWT().unpack(jwks)
        consent_args = _jwt.payload()

        assert "attr" in consent_args
        assert "redirect_endpoint" in consent_args
        assert "id" in consent_args
Example #14
0
 def api_public_keys(self):
     """The public key retrieved from the LaunchKey API. The result is cached for API_CACHE_TIME"""
     now = int(time())
     if self._api_public_keys[
             1] is None or now - self._api_public_keys[1] > API_CACHE_TIME:
         response = self.get("/public/v3/public-key", None)
         try:
             key = RSAKey(key=import_rsa_key(response.data),
                          kid=response.headers.get('X-IOV-KEY-ID'))
         except (IndexError, TypeError):
             raise UnexpectedAPIResponse(
                 "Unexpected api public key received: %s" % response.data)
         except ValueError:
             raise UnexpectedAPIResponse(
                 "Unexpected api public key received, RSA parsing error: %s"
                 % response.data)
         if key not in self._api_public_keys[0]:
             self._api_public_keys[0].append(key)
         self._api_public_keys = self._api_public_keys[0], now
     return self._api_public_keys[0]
Example #15
0
 def api_public_keys(self):
     """
     The public key retrieved from the LaunchKey API. The result is
     cached for API_CACHE_TIME
     """
     now = int(time())
     if self._api_public_keys[1] is None \
             or now - self._api_public_keys[1] > API_CACHE_TIME:
         response = self.get("/public/v3/public-key", None)
         try:
             key = RSAKey(key=import_rsa_key(response.data),
                          kid=response.headers.get('X-IOV-KEY-ID'))
         except (IndexError, TypeError):
             raise UnexpectedAPIResponse(
                 "Unexpected api public key received: %s" % response.data)
         except ValueError:
             raise UnexpectedAPIResponse("Unexpected api public key "
                                         "received, RSA parsing error"
                                         ": %s" % response.data)
         if key not in self._api_public_keys[0]:
             self._api_public_keys[0].append(key)
         self._api_public_keys = self._api_public_keys[0], now
     return self._api_public_keys[0]
Example #16
0
    def get(self, request: HttpRequest, application_slug: str) -> HttpResponse:
        """Show RSA Key data for Provider"""
        application = get_object_or_404(Application, slug=application_slug)
        provider: OAuth2Provider = get_object_or_404(
            OAuth2Provider, pk=application.provider_id)

        response_data = {}

        if provider.jwt_alg == JWTAlgorithms.RS256:
            public_key = import_rsa_key(provider.rsa_key.key_data).publickey()
            response_data["keys"] = [{
                "kty": "RSA",
                "alg": "RS256",
                "use": "sig",
                "kid": provider.rsa_key.kid,
                "n": long_to_base64(public_key.n),
                "e": long_to_base64(public_key.e),
            }]

        response = JsonResponse(response_data)
        response["Access-Control-Allow-Origin"] = "*"

        return response
def create_signed_sws(sws_data, pem):
    sws = SWSMessage(**sws_data)
    rsa_key = import_rsa_key(pem)
    key = [RSAKey().load_key(rsa_key)]
    alg = 'RS256'
    return sws.to_jwt(key=key, algorithm=alg)
Example #18
0
 def create_jwt(payload, p_key):
     rsajwk = RSAKey(kid="RSA1", key=import_rsa_key(p_key))
     jws = JWS(payload, alg="RS256")
     return jws.sign_compact(keys=[rsajwk])
Example #19
0
__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": g_config["client_id"],
            "sub": g_config["client_secret"],
            "aud": __TOKEN_ENDPOINT,
            "jti": datetime.datetime.today().strftime('%Y%m%d%s'),
            "exp": int(time.time())+3600
        }
_jws = JWS(_payload, alg="RS256")
jwt = _jws.sign_compact(keys=[_rsajwk])

#payload = { "resource_scopes":[ "Authenticated"], "icon_uri":"/testResourcePEP", "name":"TestResourcePEP" }
headers = { 'content-type': "application/json", "cache-control": "no-cache", "Authorization": "Bearer filler"  }
res = requests.get("http://localhost:5566/resources/1b107ef3-36f3-44d1-adb4-fe6a073d5db", headers=headers, verify=False)
print(res.status_code)
print(res.text)