Ejemplo n.º 1
0
def index():
    public_file = (open(str(settings.ROOT) + "/public.pub", "r"))
    public_key = jwk.JWK.from_pem(public_file.read().encode())
    ks = jwk.JWKSet()
    ks.add(public_key)
    return ks.export(as_dict=True)

    ks2 = jwk.JWKSet()
    ks2.import_keyset(ks.export(False))
    kkk = ks2.get_key(public_key.key_id)
    return kkk.export_to_pem(True, None)
Ejemplo n.º 2
0
    def decrypt_and_verify(self, content):
      # decrypt
      jwetoken = jwe.JWE()
      jwetoken.deserialize(content, key=encryption_private_key)
      if json.loads(jwetoken.objects['protected'])['alg'] != 'RSA-OAEP-256' or json.loads(jwetoken.objects['protected'])['enc'] != 'A256CBC-HS512':
        raise Exception('Unsupported encryption') # we have to check those, otherwise other encryptions can be used as an attack vector

      # verify
      jwstoken = jws.JWS()
      jwstoken.deserialize(jwetoken.payload)

      if signature_public_key is None:
        jku = json.loads(jwstoken.objects['protected'])['jku']
        kid = json.loads(jwstoken.objects['protected'])['kid']

        #NOTE: to be certain to use a valid public key, one would have to check the
        #      domain name and SSL certificate's Common Name against a whitelisted list
        keys = requests.get(jku).content
        keyset = jwk.JWKSet()
        keyset.import_keyset(keys)
        verification_key = keyset.get_key(kid)
      else:
        verification_key = signature_public_key

      if json.loads(jwstoken.objects['protected'])['alg'] != 'RS512':
        raise Exception('Unsupported signature algorithm') # we have to check, otherwise other algorithms can be used as an attack vector

      jwstoken.verify(verification_key) # if there's no exception, the signature is valid
      return jwstoken.payload
Ejemplo n.º 3
0
def get_key_from_jwks_json(tenant, kid):
    fetcher = CacheFetcher()
    data = fetcher.fetch("https://" + tenant + "/oauth2/.well-known/jwks.json",
                         600)
    try:
        key = jwk.JWKSet().from_json(data).get_key(kid)
        return key
    except Exception:
        raise UnauthorizedAccess
Ejemplo n.º 4
0
def read_key_from_file(filename):
    with open(filename, 'r') as fn:
        full_key_json = json.load(fn)

    if full_key_json.get('keys', None):
        print("Input is keyset.")
        key_set = jwk.JWKSet()
        key_set.import_keyset(**full_key_json)
        full_key = key_set
    else:
        print("Input is not keyset.")
        full_key = jwk.JWK(**full_key_json)

    return full_key
Ejemplo n.º 5
0
def get_key_from_jwks_json(tenant, kid):
    fetcher = CacheFetcher()
    data = fetcher.fetch("https://" + tenant + "/oauth2/.well-known/jwks.json",
                         600)
    try:
        key = jwk.JWKSet().from_json(data).get_key(kid)
        return key
    except Exception:
        raise AxiomsError(
            {
                "error": "unauthorized_access",
                "error_description": "Invalid access token",
            },
            401,
        )
Ejemplo n.º 6
0
    def client_config(self):
        redirect_uri = 'http://localhost:8000/complete/test/?state=1234'

        jwks = jwk.JWKSet()
        jwks['keys'].add(
            jwk.JWK.generate(kty='RSA',
                             alg='RS256',
                             size=2048,
                             kid=secrets.token_urlsafe(32)))

        ret = OpenIDClient.objects.create(
            client_id='test',
            redirect_uris=redirect_uri,
            client_auth_type=OpenIDClient.CLIENT_AUTH_TYPE_BASIC,
            jwks=jwks.export(True))
        ret.set_client_secret('b')
        ret.save()
        ret.parsed_jwks = jwks
        return ret
Ejemplo n.º 7
0
def load_keys(key_list_path: str):
    global keys
    # Load the RSA keys from the keys folder
    keys = jwk.JWKSet()
    with open(key_list_path, mode="r") as key_list_file:

        # Read the locations of the keys
        key_list = json.load(key_list_file)
        print(f"Keylist contains {len(key_list)} elements.")
        for key_list_item in key_list:

            # Read the PEM key file
            with open(key_list_item["path"], mode="rb") as key_file:
                # Create JWK from file
                k = jwk.JWK.from_pem(key_file.read())
                k._params["kid"] = key_list_item["name"]
                keys.add(k)

        print("JWKSet has been loaded.", keys)
    load_key()
Ejemplo n.º 8
0
    def handle(self, *args, **kwargs):
        """
        Creates JWT keys at the location pointed by settings.OPENID_JWT_PRIVATE_KEY, settings.OPENID_JWT_PUBLIC_KEY
        """
        jwks = jwk.JWKSet()

        jwks['keys'].add(jwk.JWK.generate(kty='RSA', alg='RS256', size=2048, kid=secrets.token_urlsafe(32)))
        jwks['keys'].add(jwk.JWK.generate(kty='RSA', alg='RS512', size=4096, kid=secrets.token_urlsafe(32)))
        jwks['keys'].add(jwk.JWK.generate(kty='EC', crv='P-256', alg='ES256', kid=secrets.token_urlsafe(32)))
        jwks['keys'].add(jwk.JWK.generate(kty='EC', crv='P-384', alg='ES384', kid=secrets.token_urlsafe(32)))
        jwks['keys'].add(jwk.JWK.generate(kty='EC', crv='P-521', alg='ES512', kid=secrets.token_urlsafe(32)))
        jwks['keys'].add(jwk.JWK.generate(kty='oct', alg='AES', size=16*8, kid=secrets.token_urlsafe(32)))

        client = OpenIDClient.objects.get_or_create(client_id=OpenIDClient.SELF_CLIENT_ID,
                                                    defaults={
                                                        'client_auth_type': OpenIDClient.CLIENT_AUTH_TYPE_INVALID,
                                                        'client_name': 'This server'
                                                    })[0]
        client.jwks = json.dumps(json.loads(jwks.export(private_keys=True)), indent=True)
        client.save()
Ejemplo n.º 9
0
def create_JWK(key):
    return jwk.JWKSet()
Ejemplo n.º 10
0
 def jwks(self, req, **query):
     keyset = jwk.JWKSet()
     keyset.add(self.__get_id_token_jwk(req))
     return keyset.export(private_keys=False)
Ejemplo n.º 11
0
def generate_keyset(keys):
    keyset = jwk.JWKSet()
    for key in keys:
        keyset.add(key)
    return keyset
Ejemplo n.º 12
0
    def post(self, request, success_url=None) :
        encoded = request.POST.get('JWT')
        if encoded is None:
            return self.launcherror('This URL is expecting a POST with a JWT to initiate a launch')

        try:
            header = jwt.get_unverified_header(encoded)
        except:
            return self.launcherror('Could not load header from JWT',encoded)

        try:
            kid = header.get('kid')
        except:
            return self.launcherror('The JWT is missing a key ID (kid)', encoded)

        # Check if we already have the kid
        public_key = TSUGI_JWK_LIST.get(kid, False)

        # Lets get the keyset, retrieve the key, and cache it
        if public_key == False :
            keyset_proxy = False
            try :
                if settings.TSUGI_PROXY is not False: keyset_proxy = {'http' : settings.TSUGI_PROXY}
            except:
                pass

            try :
                keyset_url = settings.TSUGI_KEYSET
            except :
                print("Please set TSUGI_KEYSET in your settings.py, using dev1.tsugicloud.org as default")
                keyset_url = "https://dev1.tsugicloud.org/tsugi/lti/keyset-ext"

            status_code = False
            try:
                if keyset_proxy : print(keyset_proxy)
                response = requests.get(keyset_url, proxies=keyset_proxy, timeout=10)
                status_code = response.status_code
                dat = response.text
            except Exception as e:
                print('Keyset load failure', keyset_url, e)
                return self.launcherror('Could not retrieve keyset from '+keyset_url+' ('+str(e)+')')

            if len(dat) < 1 :
                print('Keyset load error', keyset_url, status_code)
                return self.launcherror('Could not load keyset from '+keyset_url+' ('+str(status_code)+')')

            # https://github.com/latchset/jwcrypto/blob/master/jwcrypto/tests.py
            # https://jwcrypto.readthedocs.io/en/latest/jwk.html#classes
            try:
                ks = jwk.JWKSet()
                ks.import_keyset(dat)
            except Exception as e:
                print('Keyset parse error', keyset_url, e)
                print(dat[:1000])
                return self.launcherror('Could not parse keyset from '+keyset_url,encoded)


            try:
                k1 = ks.get_key(kid)
                public_key = jwk.JWK.export_to_pem(k1)
            except:
                print('Keyset extract error', keyset_url)
                print(dat[:1000])
                return self.launcherror('Could not extract kid='+kid+' from '+keyset_url,encoded)

            if len(TSUGI_JWK_LIST) > 10 :
                TSUGI_JWK_LIST.clear()
            TSUGI_JWK_LIST[kid] = public_key

        try:
            lti_launch = jwt.decode(encoded, public_key, algorithms=['RS256'])
            print('Forwarding valid launch')
            print(lti_launch)
        except Exception as e:
            return self.launcherror('Could not decode JSON Web Token: '+str(e),encoded)

        # Check to see how they want us to launch...
        debug = request.GET.get('debug')
        force_cookie = request.GET.get('force_cookie')
        if success_url :
            destination = success_url
            print('from successurl',destination)
        else:
            destination = request.GET.get('destination', None)
            print('from GET',destination)

        if destination is None:
            return self.launcherror('Must have a success_url or a destination parameter')

        lti_launch['launch_destination'] = destination
        lti_launch['launch_force_cookie'] = force_cookie
        lti_launch['launch_debug'] = debug
        request.session['lti_launch'] = lti_launch

        redirect_url = reverse(destination)
        request.session['lti_destination'] = redirect_url
        if debug == "true" or force_cookie == "true" :
            redirect_url = reverse('django_tsugi:start')


        # Copy GET parameters
        params = request.GET.copy()
        params['destination'] = destination
        redirect_url = redirect_url + "?" + urllib.parse.urlencode(params)
        return redirect(redirect_url)
Ejemplo n.º 13
0
 def __init__(self, jwk_file):
     keys_json = open(jwk_file, 'r').read()
     self.key_set = jwk.JWKSet().from_json(keys_json)
     self.logger = logging.getLogger(__name__)
     self.header_key = 'TOKEN'
Ejemplo n.º 14
0
def jwks_view(req):
    keyset = jwk.JWKSet()
    keyset.add(decryption_key)
    keyset.add(signing_key)
    return sanic.response.json(json.loads(keyset.export(False)))
Ejemplo n.º 15
0
 def get(self):
     keyset = jwk.JWKSet()
     keyset.add(get_id_token_jwk())
     return keyset.export(private_keys=False)