コード例 #1
0
ファイル: message_launch.py プロジェクト: shurrey/pylti1.3
    def get_public_key(self):
        public_key_set = self._registration.get_key_set()
        key_set_url = self._registration.get_key_set_url()

        if not public_key_set:
            if key_set_url.startswith(('http://', 'https://')):
                public_key_set = self.fetch_public_key(key_set_url)
                self._registration.set_key_set(public_key_set)
            else:
                raise LtiException("Invalid URL: " + key_set_url)

        # Find key used to sign the JWT (matches the KID in the header)
        kid = self._jwt.get('header', {}).get('kid', None)
        alg = self._jwt.get('header', {}).get('alg', None)

        if not kid:
            raise LtiException("JWT KID not found")
        if not alg:
            raise LtiException("JWT ALG not found")

        for key in public_key_set['keys']:
            key_kid = key.get('kid')
            key_alg = key.get('alg', 'RS256')
            if key_kid and key_kid == kid and key_alg == alg:
                try:
                    key_json = json.dumps(key)
                    jwk_obj = JWK.from_json(key_json)
                    return jwk_obj.export_to_pem()
                except (ValueError, TypeError):
                    raise LtiException("Can't convert JWT key to PEM format")

        # Could not find public key with a matching kid and alg.
        raise LtiException("Unable to find public key")
コード例 #2
0
ファイル: utils.py プロジェクト: ShariqT/tribes-python-django
def encrypt_raw_event(evt, public_key, is_dict=False):
    payload = evt.to_jsonld()
    if is_dict is True:
        if type(public_key) is str:

            public_key = JWK.from_json(json_encode(eval(public_key)))
        else:
            public_key = JWK.from_json(json_encode(public_key))
    protected_header = {
        "alg": "RSA-OAEP-256",
        "enc": "A256CBC-HS512",
        "typ": "JWE",
        "kid": public_key.thumbprint(),
    }
    data = JWE(payload.encode('utf-8'),
               recipient=public_key,
               protected=protected_header)

    return data.serialize()
コード例 #3
0
    def _validate_token_offline(self, access_token):
        """
        Validate access token using cached information from the provider
        :param access_token:
        :return: tuple(valid, credential) or tuple(False, None)
        """

        def decode(key):
            log.debug('Attempt decoding using key={}'.format(key.export()))
            try:
                if 'wlcg' in issuer:
                    audience = 'https://wlcg.cern.ch/jwt/v1/any'
                    credential = jwt.decode(access_token,
                                            key.export_to_pem(),
                                            algorithms=[algorithm],
                                            audience=audience
                                            )
                else:
                    # We don't check audience for non-WLCG token
                    credential = jwt.decode(access_token,
                                            key.export_to_pem(),
                                            algorithms=[algorithm],
                                            options={'verify_aud': False}
                                            )
                return credential
            except Exception:
                return None

        log.debug('entered validate_token_offline')
        credential = None
        try:
            unverified_payload = jwt.decode(access_token, verify=False)
            unverified_header = jwt.get_unverified_header(access_token)
            issuer = unverified_payload['iss']
            key_id = unverified_header.get('kid')
            algorithm = unverified_header.get('alg')
            log.debug('issuer={}, key_id={}, alg={}'.format(issuer, key_id, algorithm))
            # Retrieval of keys
            keys = oidc_manager.filter_provider_keys(issuer, key_id, algorithm)
            jwkeys = [JWK.from_json(json.dumps(key.to_dict())) for key in keys]

            # Find the first key which decodes the token
            for jwkey in jwkeys:
                credential = decode(jwkey)
                if credential is not None:
                    log.debug('offline_response::: {}'.format(credential))
                    break
        except Exception as ex:
            log.debug('return False, Exception: {}'.format(ex))
            return False, None

        if credential is None:
            log.debug('No key managed to decode the token')
        log.debug('return {}, credential'.format(credential is not None))
        return (credential is not None), credential
コード例 #4
0
def get_jwk():
    jwk_config = None
    # Get JWK (if exists)
    if 'jwk' in app_secrets and 'kty' in app_secrets['jwk']:
        key_type = app_secrets['jwk']['kty'].lower()
        if key_type == "oct" and 'k' in app_secrets['jwk']:
            jwk_config = {'kty': key_type, 'k': app_secrets['jwk']['k']}
        # Add support for other key types here;
        # For now, we only support octat sequence ("oct")

    if jwk_config is not None:
        return JWK.from_json(json.dumps(jwk_config))
    return None
コード例 #5
0
    def upload_picture(self, picture_stream):
        """
        Upload the file on the given path to the server
        via HTTP post

        Uses class configuration to determine the url and key to sign
        Authorization Bearer token with JWT
        """
        # skip if improperly configured    
        if not self.upload_url or not self.upload_auth_jwk_path:
            return

        if not self.upload_auth_jwk:
            with open(self.upload_auth_jwk_path, 'rb') as f:
                self.upload_auth_jwk = JWK.from_json(f.read())
        
        try:
            picture_stream.seek(0)
            auth_token = JWT(header={'alg': 'EdDSA', 'kid': self.upload_auth_jwk.key_id}, default_claims={'iat':None, 'exp': None})
            auth_token.validity=300
            auth_token.claims={}
            auth_token.make_signed_token(self.upload_auth_jwk)

            auth_header = 'Bearer {}'.format(auth_token.serialize())
            response = requests.post(
                self.upload_url, 
                files={'file': picture_stream},
                headers={
                    'Authorization': auth_header
                }
            )
            if not response.ok:
                logger.error("Error uploading snapshot. Status code {}".format(response.status_code))
            
        except Exception as exc:
            logger.exception("Error uploading snapshot.")
        else:
            # log success
            logger.info("Snapshot uploaded")
        finally:
            picture_stream.seek(0)
コード例 #6
0
import os
import json
import datetime

import requests
from jwcrypto.jwk import JWK
from jwcrypto.jwt import JWT

raw_token = open('temp-token.txt').read()
jwks_resp = requests.get(os.environ['OAUTH_SERVER'] + '/v1/keys')

first_key = jwks_resp.json()['keys'][0]
key = JWK.from_json(json.dumps(first_key))

# Validate token as per procedure described in:
# https://developer.okta.com/authentication-guide/tokens/validating-id-tokens/#verify-the-claims

# Use built-in claim validation for exact matching
# https://jwcrypto.readthedocs.io/en/latest/jwt.html
expected_claims = {
    "iss": os.environ['OAUTH_SERVER'],
    "aud": os.environ['CLIENT_ID']
}

# Creating JWT object also validates the signature
token = JWT(jwt=raw_token, key=key, check_claims=expected_claims)
claims = json.loads(token.claims)

# Perform issued at and expiration time checks
print('IAT validation: ' + str(
    datetime.datetime.fromtimestamp(claims['iat']) < datetime.datetime.now()))
コード例 #7
0
    async def handle_client(self, reader, writer):
        try:
            req = await read(reader)
            # FIXME: カプセル化……
            # jwcryptoではJWTの署名を検証する前にペイロードにアクセスする良い方法がない
            req.token.objects['valid'] = True
            reqclaims = json.loads(req.token.payload.decode('utf-8'))
            print(f"got claims: {reqclaims}")

            reqtype = reqclaims['msgtype']
            print(f"msgtype: {reqtype}")
            if reqtype == 'ctr_init':  # カウンタの初期化
                nonce = reqclaims['nonce']
                client_pubkey = JWK.from_json(reqclaims['pubkey'])

                vinit = 42  # TODO: 適切な初期値
                key = self.data.add_new(vinit, client_pubkey)

                await write(
                    writer, {
                        'msgtype': 'ctr_init_ok',
                        'nonce': nonce,
                        'key': key,
                        'ctr': vinit
                    }, self.privkey)

            elif reqtype == 'ctr_access':  # カウンタに0以上加算して結果を返す
                nonce0 = reqclaims['nonce0']
                key = reqclaims['key']
                inc = reqclaims['inc']

                # key がわからないと対応する公開鍵もわからない
                client_pubkey = self.data.pubkey(key)

                # reqのロード時に検証できなかったのでここで検証
                try:
                    req.token.verify(client_pubkey)
                except InvalidJWSSignature:
                    await write(writer, {
                        'msgtype': 'error',
                        'info': 'invalid_signature'
                    }, self.privkey)
                    return

                nonce1 = random.randrange(2**32)
                await write(
                    writer, {
                        'msgtype': 'ctr_access_ack0',
                        'nonce0': nonce0,
                        'nonce1': nonce1
                    }, self.privkey)

                req1 = await read(reader, client_pubkey)
                print(f'req1: {req1.claims}')
                # TODO: 署名検証の例外処理
                req1claims = json.loads(req1.claims)
                print(f'got claims: {req1claims}')

                if req1claims['msgtype'] != 'ctr_access_ack1':
                    await write(writer, {
                        'msgtype': 'error',
                        'info': 'invalid_request'
                    }, self.privkey)
                    return
                if req1claims['nonce0'] != nonce0 or req1claims[
                        'nonce1'] != nonce1:
                    await write(writer, {
                        'msgtype': 'error',
                        'info': 'nonce_mismatch'
                    }, self.privkey)
                    return

                v = self.data.increment(key, inc)
                await write(
                    writer, {
                        'msgtype': 'ctr_access_ok',
                        'nonce0': nonce0,
                        'nonce1': nonce1,
                        'ctr': v
                    }, self.privkey)

            elif reqtype == 'time_query':  # 時刻のクエリ
                # クエリの署名検証はしない
                nonce = reqclaims["nonce"]
                t = time.time()

                await write(writer, {
                    'msgtype': 'time_answer',
                    'time': t,
                    'nonce': nonce
                }, self.privkey)

            else:  # 不明なリクエスト
                await write(writer, {
                    'msgtype': 'error',
                    'info': 'invalid_request'
                }, self.privkey)

        #except KeyError:
        #    await write(writer, {'msgtype': 'error', 'info': 'key_error'}, self.privkey)

        except ValueError:
            await write(writer, {
                'msgtype': 'error',
                'info': 'value_error'
            }, self.privkey)

        #except InvalidJWSSignature:
        #    await write(writer, {'msgtype': 'error', 'info': 'invalid_signature'}, self.privkey)

        finally:
            writer.close()
            await writer.wait_closed()
コード例 #8
0
from jwcrypto.jwk import JWK
import requests
import json
from web.src.SAP import create_app

app = create_app()

# Get JWK from identity provider
idp = os.environ["IDP"]
headers = {"Accept": "application/json"}

r = requests.get(idp + "/.well-known/jwks.json", params={}, headers=headers)

jsonkeys = r.json()
jsonkey = jsonkeys["keys"][0]
jwk_json = json.dumps(jsonkey)
jwk = JWK.from_json(jwk_json)

# Convert JWK to PEM so that JWTManager can consume it
pem = jwk.export_to_pem()

# Configure JWTManager
app.config["JWT_PUBLIC_KEY"] = pem
app.config["JWT_DECODE_AUDIENCE"] = os.environ["SOFI_CLIENT_ID"]
app.config["JWT_IDENTITY_CLAIM"] = "email"
app.config["JWT_ALGORITHM"] = jsonkey["alg"]
JWTManager(app)

if __name__ == "__main__":
    app.run(host="0.0.0.0")
コード例 #9
0
def verify_token(token, pub_key):
    jwk = JWK.from_json(json.dumps(pub_key))
    return jwt.verify_jwt(token, jwk, ['RS256'], checks_optional=True)
コード例 #10
0
def verify_token(token, pub_key):
    print(f"\n\n\n^^^^verifying token")
    jwk = JWK.from_json(json.dumps(pub_key))
    print(f"\n\n\n^^^^jwk obtained")

    return jwt.verify_jwt(token, jwk, ["RS256"], checks_optional=True)