def get_freja_state(user): current_app.logger.debug('Getting state for user {!s}.'.format(user)) try: proofing_state = current_app.proofing_statedb.get_state_by_eppn(user.eppn) expire_time = current_app.config['FREJA_EXPIRE_TIME_HOURS'] if helpers.is_proofing_state_expired(proofing_state, expire_time): current_app.proofing_statedb.remove_state(proofing_state) current_app.stats.count(name='freja.proofing_state_expired') raise DocumentDoesNotExist(reason='freja proofing state expired') except DocumentDoesNotExist: return {} # Return request data current_app.logger.debug('Returning request data for user {!s}'.format(user)) current_app.stats.count(name='freja.proofing_state_returned') opaque_data = helpers.create_opaque_data(proofing_state.nonce, proofing_state.token) valid_until = helpers.get_proofing_state_valid_until(proofing_state, expire_time) request_data = { "iarp": current_app.config['FREJA_IARP'], "exp": int(valid_until.astimezone(UTC()).strftime('%s')) * 1000, # Milliseconds since 1970 in UTC "proto": current_app.config['FREJA_RESPONSE_PROTOCOL'], "opaque": opaque_data } jwk = binascii.unhexlify(current_app.config['FREJA_JWK_SECRET']) jws_header = { 'alg': current_app.config['FREJA_JWS_ALGORITHM'], 'kid': current_app.config['FREJA_JWS_KEY_ID'], } jws = jose.sign(request_data, jwk, headers=jws_header, algorithm=current_app.config['FREJA_JWS_ALGORITHM']) return { 'iaRequestData': jws }
def sign(self, claims, crypto_key=None): """Sign a set of claims. :param claims: JSON object containing the JWT claims to use. :param crypto_key: Optional existing crypto_key header content. The vapid public key will be appended to this data. :returns result: a hash containing the header fields to use in the subscription update. """ if not claims.get('exp'): claims['exp'] = int(time.time()) + 86400 if not claims.get('aud'): raise VapidException( "Missing 'aud' from claims. " "'aud' is your site's URL.") if not claims.get('sub'): raise VapidException( "Missing 'sub' from claims. " "'sub' is your admin email as a mailto: link.") sig = jws.sign(claims, self.private_key, algorithm="ES256") pkey = 'p256ecdsa=' pkey += self.public_key_urlsafe_base64 if crypto_key: crypto_key = crypto_key + ',' + pkey else: crypto_key = pkey return {"Authorization": "Bearer " + sig.strip('='), "Crypto-Key": crypto_key}
def test_validate_invalid_vapid_key_sets_status(self, start_recording): start_recording.is_callable().times_called(0) other_signing_key = ecdsa.SigningKey.generate(curve=ecdsa.NIST256p) signed_token = jws.sign(self.pa.vapid_key_token, other_signing_key, algorithm='ES256') self.pa.validate_vapid_key(signed_token) self.assertEqual(u'invalid', self.pa.vapid_key_status)
def test_validate_valid_vapid_key_sets_status_starts_recording( self, start_recording ): start_recording.expects_call() signed_token = jws.sign(self.pa.vapid_key_token, self.signing_key, algorithm='ES256') self.pa.validate_vapid_key(signed_token) self.assertEqual(u'valid', self.pa.vapid_key_status) self.assertIsNotNone(self.pa.validated)
def generate_token(pvt_key, secret, valid_for=3600, algorithm=ALGORITHMS.HS256): #generate JWT token jti = str(random.random()) iat = int(time.time()) valid_for = iat + 60 payload = {"iss": pvt_key, "iat": iat, "jti": jti, "exp": valid_for, } return jws.sign(payload, secret, algorithm=algorithm)
def _jwt_sign(self, header, payload, algorithm=jws.ALGORITHMS.RS256): """ Perform JWT signature of the header and payload. :param header: (dict) JWS header dictionary :param payload: (dict) content to sign :param algorithm: (string) which algorithm to use. Default: 'RS256' :return: (string) Signed base64 encoded content """ secret = crypto.dump_privatekey(crypto.FILETYPE_PEM, self.p12.get_privatekey()) return jws.sign(claims=payload, key=secret, headers=header, algorithm=algorithm)
def post(self, request): username = request.POST.get('username', None) password = request.POST.get('password', None) user = authenticate(username=username, password=password) if user: expiration = int(time.time()) + timedelta(days=settings.JWT_TOKEN_EXPIRATION).total_seconds() token = jws.sign({'username': user.username, 'expiration':expiration}, settings.JWT_KEY, algorithm=settings.JWT_ALGORITHM) response = HttpResponse(token, content_type='text/plain') else: response = Http401Response(www_auth_header='Bearer') return response
def _get_vapid(key=None, payload=None): if not payload: payload = {"aud": "https://pusher_origin.example.com", "exp": int(time.time()) + 86400, "sub": "mailto:[email protected]"} if not key: key = ecdsa.SigningKey.generate(curve=ecdsa.NIST256p) vk = key.get_verifying_key() auth = jws.sign(payload, key, algorithm="ES256").strip('=') crypto_key = base64.urlsafe_b64encode('\4' + vk.to_string()).strip('=') return {"auth": auth, "crypto-key": crypto_key, "key": key}
def sign_task(task_id, pvt_key, valid_for=3600, algorithm=ALGORITHMS.RS512): # reserved JWT claims, to be verified # Issued At iat = int(time.time()) # Expiration Time exp = iat + valid_for claims = { "iat": iat, "exp": exp, "taskId": task_id, "version": "1", } return jws.sign(claims, pvt_key, algorithm=algorithm)
def create_jwt(self, client_id, username, expires_in=60 * 60, extra_data={}): now = int(time.time()) payload = { "iss": "https://cognito-idp.{}.amazonaws.com/{}".format(self.region, self.id), "sub": self.users[username].id, "aud": client_id, "token_use": "id", "auth_time": now, "exp": now + expires_in, } payload.update(extra_data) return jws.sign(payload, self.json_web_key, algorithm='RS256'), expires_in
def validate(self, username, password): user = User.authenticate(username, password, self.request.db) if user: token = jws.sign({ 'user_id': user.id, 'user_type': user.user_type }, 'secret', algorithm='HS256') return { 'user_id': user.id, 'user_type': user.user_type, 'token': token, } else: raise exc.HTTPUnauthorized()
def encode(claims, key, algorithm=None, headers=None): """Encodes a claims set and returns a JWT string. JWTs are JWS signed objects with a few reserved claims. Args: claims (dict): A claims set to sign key (str): The key to use for signing the claim set algorithm (str, optional): The algorithm to use for signing the the claims. Defaults to HS256. headers (dict, optional): A set of headers that will be added to the default headers. Any headers that are added as additional headers will override the default headers. Returns: str: The string representation of the header, claims, and signature. Raises: JWTError: If there is an error encoding the claims. Examples: >>> jwt.encode({'a': 'b'}, 'secret', algorithm='HS256') 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' """ for time_claim in ['exp', 'iat', 'nbf']: # Convert datetime to a intDate value in known time-format claims if isinstance(claims.get(time_claim), datetime): claims[time_claim] = timegm(claims[time_claim].utctimetuple()) if algorithm: return jws.sign(claims, key, headers=headers, algorithm=algorithm) return jws.sign(claims, key, headers=headers)
def test_add_headers(self, payload): additional_headers = { 'test': 'header' } expected_headers = { 'test': 'header', 'alg': 'HS256', 'typ': 'JWT', } token = jws.sign(payload, 'secret', headers=additional_headers) header, payload, signing_input, signature = jws._load(token) assert expected_headers == header
def encode(claims, key, algorithm=ALGORITHMS.HS256, headers=None, access_token=None): """Encodes a claims set and returns a JWT string. JWTs are JWS signed objects with a few reserved claims. Args: claims (dict): A claims set to sign key (str or dict): The key to use for signing the claim set. Can be individual JWK or JWK set. algorithm (str, optional): The algorithm to use for signing the the claims. Defaults to HS256. headers (dict, optional): A set of headers that will be added to the default headers. Any headers that are added as additional headers will override the default headers. access_token (str, optional): If present, the 'at_hash' claim will be calculated and added to the claims present in the 'claims' parameter. Returns: str: The string representation of the header, claims, and signature. Raises: JWTError: If there is an error encoding the claims. Examples: >>> jwt.encode({'a': 'b'}, 'secret', algorithm='HS256') 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' """ for time_claim in ['exp', 'iat', 'nbf']: # Convert datetime to a intDate value in known time-format claims if isinstance(claims.get(time_claim), datetime): claims[time_claim] = timegm(claims[time_claim].utctimetuple()) if access_token: claims['at_hash'] = calculate_at_hash(access_token, ALGORITHMS.HASHES[algorithm]) return jws.sign(claims, key, headers=headers, algorithm=algorithm)
def generate_bearer_with_scope(self, scope, bad_claims=None): claims = { "iss": "https://auth-dev.mozilla.auth0.com/", "sub": "mc1l0G4sJI2eQfdWxqgVNcRAD9EAgHib@clients", "aud": "https://change.sso.allizom.org", "iat": (datetime.utcnow() - timedelta(seconds=3100)).strftime("%s"), "exp": (datetime.utcnow() + timedelta(seconds=3100)).strftime("%s"), "scope": scope, "gty": "client-credentials", } if bad_claims is not None: claims = bad_claims return jws.sign(claims, self.fake_signing_key_private, headers=self.additional_headers, algorithm="RS256")
def post(self, request): username = request.POST.get('username', None) password = request.POST.get('password', None) user = authenticate(username=username, password=password) if user: expiration = int(time.time()) + timedelta( days=settings.JWT_TOKEN_EXPIRATION).total_seconds() token = jws.sign( { 'username': user.username, 'expiration': expiration }, settings.JWT_KEY, algorithm=settings.JWT_ALGORITHM) response = HttpResponse(token, content_type='text/plain') else: response = Http401Response(www_auth_header='Bearer') return response
def generate_JWT(context): """Create and Sign a JWT valid for AMO HTTP requests. Uses context.config 'jwt_user' and 'jwt_secret' and sets an expiration of 4 minutes (AMO supports a max of 5) """ amo_instance = get_amo_instance_config_from_scope(context) user = amo_instance['jwt_user'] secret = amo_instance['jwt_secret'] jti = str(uuid4()) iat = int(time.time()) exp = iat + 60 * 4 # AMO has a 5 minute max, so set this to 4 minutes after issued payload = { 'iss': user, 'jti': jti, 'iat': iat, 'exp': exp, } token_str = jws.sign(payload, secret, algorithm='HS256') return token_str
def encode(claims, key, algorithm=ALGORITHMS.HS256, headers=None, access_token=None): """Encodes a claims set and returns a JWT string. JWTs are JWS signed objects with a few reserved claims. Args: claims (dict): A claims set to sign key (str): The key to use for signing the claim set algorithm (str, optional): The algorithm to use for signing the the claims. Defaults to HS256. headers (dict, optional): A set of headers that will be added to the default headers. Any headers that are added as additional headers will override the default headers. access_token (str, optional): If present, the 'at_hash' claim will be calculated and added to the claims present in the 'claims' parameter. Returns: str: The string representation of the header, claims, and signature. Raises: JWTError: If there is an error encoding the claims. Examples: >>> jwt.encode({'a': 'b'}, 'secret', algorithm='HS256') 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' """ for time_claim in ['exp', 'iat', 'nbf']: # Convert datetime to a intDate value in known time-format claims if isinstance(claims.get(time_claim), datetime): claims[time_claim] = timegm(claims[time_claim].utctimetuple()) if access_token: claims['at_hash'] = calculate_at_hash(access_token, ALGORITHMS.HASHES[algorithm]) return jws.sign(claims, key, headers=headers, algorithm=algorithm)
def create_jwt( self, client_id, username, token_use, expires_in=60 * 60, extra_data={} ): now = int(time.time()) payload = { "iss": "https://cognito-idp.{}.amazonaws.com/{}".format( self.region, self.id ), "sub": self.users[username].id, "aud": client_id, "token_use": token_use, "auth_time": now, "exp": now + expires_in, } payload.update(extra_data) headers = {"kid": "dummy"} # KID as present in jwks-public.json return ( jws.sign(payload, self.json_web_key, headers, algorithm="RS256"), expires_in, )
def login(self, **data): datastore_entity = model.UserAccount.get_by_key_name(data["user_id"]) if not datastore_entity: raise Exception("User ID does not exists!") if pbkdf2_sha256.verify(data["password"], datastore_entity.password_hash): auth_token = jws.sign(json.dumps({ "user_id": datastore_entity.user_id, "full_name": datastore_entity.full_name }), 'insecure secret', algorithm='HS256') return { "auth_token": auth_token, "full_name": datastore_entity.full_name } return None
def test_can_full_verify_jws_signed_assertion(self): """ I can input a JWS string I can extract the Assertion from the input signature string and store it as the canonical version of the Assertion. I can discover and retrieve key information from the Assertion. I can Access the signing key I can verify the key is associated with the listed issuer Profile I can verify the JWS signature has been created by a key trusted to correspond to the issuer Profile Next: I can verify an assertion with an ephemeral embedded badgeclass as well """ input_assertion = json.loads(test_components['2_0_basic_assertion']) input_assertion['verification'] = {'type': 'signed', 'creator': 'http://example.org/key1'} set_up_image_mock(u'https://example.org/beths-robot-badge.png') input_badgeclass = json.loads(test_components['2_0_basic_badgeclass']) set_up_image_mock(input_badgeclass['image']) input_issuer = json.loads(test_components['2_0_basic_issuer']) input_issuer['publicKey'] = input_assertion['verification']['creator'] key = RSA.generate(2048) public_key_pem = key.publickey().export_key() cryptographic_key_doc = { '@context': OPENBADGES_CONTEXT_V2_URI, 'id': input_assertion['verification']['creator'], 'type': 'CryptographicKey', 'owner': input_issuer['id'], 'publicKeyPem': public_key_pem.decode() } set_up_context_mock() for doc in [input_badgeclass, input_issuer, cryptographic_key_doc]: responses.add(responses.GET, doc['id'], json=doc, status=200) signature = jws.sign(input_assertion, key, algorithm='RS256') response = verify(signature, use_cache=False) self.assertTrue(response['report']['valid'])
def test_can_full_verify_with_revocation_check(self): input_assertion = json.loads(test_components['2_0_basic_assertion']) input_assertion['verification'] = {'type': 'signed', 'creator': 'http://example.org/key1'} set_up_image_mock(u'https://example.org/beths-robot-badge.png') input_badgeclass = json.loads(test_components['2_0_basic_badgeclass']) set_up_image_mock(input_badgeclass['image']) revocation_list = { '@context': OPENBADGES_CONTEXT_V2_URI, 'id': 'http://example.org/revocationList', 'type': 'RevocationList', 'revokedAssertions': []} input_issuer = json.loads(test_components['2_0_basic_issuer']) input_issuer['revocationList'] = revocation_list['id'] input_issuer['publicKey'] = input_assertion['verification']['creator'] key = RSA.generate(2048) public_key_pem = key.publickey().export_key() cryptographic_key_doc = { '@context': OPENBADGES_CONTEXT_V2_URI, 'id': input_assertion['verification']['creator'], 'type': 'CryptographicKey', 'owner': input_issuer['id'], 'publicKeyPem': public_key_pem.decode() } set_up_context_mock() for doc in [input_assertion, input_badgeclass, input_issuer, cryptographic_key_doc, revocation_list]: responses.add(responses.GET, doc['id'], json=doc, status=200) header = {'alg': 'RS256'} payload = json.dumps(input_assertion).encode() signature = jws.sign(input_assertion, key, algorithm='RS256') response = verify(signature, use_cache=False) self.assertTrue(response['report']['valid'])
def setUp(self): self.key = RSA.generate(2048) self.public_key_pem = self.key.publickey().export_key() self.signing_key_doc = { 'id': 'http://example.org/key1', 'type': 'CryptographicKey', 'owner': 'http://example.org/issuer', 'publicKeyPem': self.public_key_pem } self.issuer_data = { 'id': 'http://example.org/issuer', 'publicKey': 'http://example.org/key1' } self.badgeclass = { 'id': '_:b1', 'issuer': 'http://example.org/issuer' } self.verification_object = { 'id': '_:b0', 'type': 'SignedBadge', 'creator': 'http://example.org/key1' } self.assertion_data = { 'id': 'urn:uuid:bf8d3c3d-fe60-487c-87a3-06440d0d0163', 'verification': '_:b0', 'badge': '_:b1' } self.assertion = { 'id': 'urn:uuid:bf8d3c3d-fe60-487c-87a3-06440d0d0163', 'verification': self.verification_object, 'badge': self.badgeclass } self.signature = jws.sign(self.assertion, self.key, algorithm='RS256') self.state = { 'graph': [self.signing_key_doc, self.issuer_data, self.badgeclass, self.verification_object, self.assertion_data] }
def connector(self): dt = datetime.datetime.now() ts = time.mktime(dt.timetuple()) claims = { "email": self.email, "aud": "usr", "iat": int(ts), "jti": hex(random.getrandbits(64)) } key = { "kty": self.kty, "alg": self.alg, "crv": self.crv, "x": self.x, "y": self.y, "d": self.d } token = jws.sign(claims, key, headers={"kid": self.kid}, algorithm=ALGORITHMS.ES256) return token
def get_freja_state(user): current_app.logger.debug('Getting state for user {!s}.'.format(user)) try: proofing_state = current_app.proofing_statedb.get_state_by_eppn( user.eppn) expire_time = current_app.config.freja_expire_time_hours if helpers.is_proofing_state_expired(proofing_state, expire_time): current_app.proofing_statedb.remove_state(proofing_state) current_app.stats.count(name='freja.proofing_state_expired') raise DocumentDoesNotExist(reason='freja proofing state expired') except DocumentDoesNotExist: return {} # Return request data current_app.logger.debug( 'Returning request data for user {!s}'.format(user)) current_app.stats.count(name='freja.proofing_state_returned') opaque_data = helpers.create_opaque_data(proofing_state.nonce, proofing_state.token) valid_until = helpers.get_proofing_state_valid_until( proofing_state, expire_time) request_data = { "iarp": current_app.config.freja_iarp, "exp": int(valid_until.astimezone(UTC()).strftime('%s')) * 1000, # Milliseconds since 1970 in UTC "proto": current_app.config.freja_response_protocol, "opaque": opaque_data, } jwk = binascii.unhexlify(current_app.config.freja_jwk_secret) jws_header = { 'alg': current_app.config.freja_jws_algorithm, 'kid': current_app.config.freja_jws_key_id, } jws = jose.sign(request_data, jwk, headers=jws_header, algorithm=current_app.config.freja_jws_algorithm) return {'iaRequestData': jws}
def check_changes(db): #CAN BE DO WITH NORMAL DB CALL print("----------------------------------start thread----------------------------------") if deb2 else None while True: if Change.query.filter_by(flag=False).order_by(Change.time_req.desc()).first() is not None: app1 = Change.query.filter_by(flag=False).order_by(Change.time_req.desc()).first() if UserFarm.query.filter_by(pub_id=app1.pub_id).first() is not None: app2 = UserFarm.query.filter_by(pub_id=app1.pub_id).first() if Session.query.filter_by(pub_id=app1.pub_id, flag=True).first() is not None: app3 = Session.query.filter_by(pub_id=app1.pub_id, flag=True).first() data = {"ses_id": app3.session_id, 'dev': app1.dev, 'code': app1.code, 'val': app1.val, 'time_req': app1.time_req.strftime("%m/%d/%Y, %H:%M:%S.%f")} print("TH-data: ", data) if deb else None crypt_data = jws.sign(data, jws.verify(app2.pri_id, priv_id, algorithms=['HS256']).decode(), algorithm='HS256') print("TH-encrypt data: ", crypt_data) if deb else None sign_crypt_data = sign.sign_data(key.exportKey(), crypt_data) print("TH-sign of data: ", sign_crypt_data) if deb else None req = {"pub_id": app2.pub_id, "data": crypt_data, "sign": sign_crypt_data.decode()} print("TH-send: ", req) if deb else None emit('changes', req, room=app3.sid) print("TH CHECK CHANGE ---> user: "******"----------------------------------th restart loop----------------------------------") if deb2 else None time.sleep(5) print("----------------------------------finish thread----------------------------------") if deb2 else None
def create_jwt(payload, priv_key, output_file=None, alg='ES256'): """ Create JWT from JSON object :param payload: The JSON to be signed :param priv_key: The private key to sign JSON :param output_file: The output file to save the certificate :param alg: The signing algorithm :return: JWT token """ if alg == 'ES256': headers = {'alg': 'ES256'} algorithm = ALGORITHMS.ES256 else: raise ValueError(f'Unsupported algorithm {alg}') token = jws.sign(payload, priv_key, headers=headers, algorithm=algorithm) logger.debug(f'Created JWT token: {token}') if output_file: with open(output_file, 'w') as f: f.write(token) logger.debug(f'Saved JWT token to a file: {output_file}') return token
def _get_vapid(key=None, payload=None, endpoint=None): global CONNECTION_CONFIG if endpoint is None: endpoint = "{}://{}:{}".format( CONNECTION_CONFIG.get("endpoint_scheme"), CONNECTION_CONFIG.get("endpoint_hostname"), CONNECTION_CONFIG.get("endpoint_port"), ) if not payload: payload = {"aud": endpoint, "exp": int(time.time()) + 86400, "sub": "mailto:[email protected]"} if not payload.get("aud"): payload['aud'] = endpoint if not key: key = ecdsa.SigningKey.generate(curve=ecdsa.NIST256p) vk = key.get_verifying_key() auth = jws.sign(payload, key, algorithm="ES256").strip('=') crypto_key = base64url_encode('\4' + vk.to_string()) return {"auth": auth, "crypto-key": crypto_key, "key": key}
def post(self, request): """ the above token need to be saved in database, and a one-to-one relation should exist with the username/user_pk """ username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) if user: expiration = int(time.time()) + timedelta( days=settings.JWT_TOKEN_EXPIRATION).total_seconds() token = jws.sign( { 'username': user.username, 'expiration': expiration }, settings.JWT_KEY, algorithm=settings.JWT_ALGORITHM) return HttpResponse(token) else: return Http401Response(www_auth_header='Bearer')
def create_access_token( algorithm: str = 'RS256', claims: Optional[Dict] = None, expires_delta: Optional[datetime.timedelta] = None) -> str: """ Create a signed access token with claims :param algorithm: the RSA algorithm to use - can be RS256, RS384, RS512 :param claims: the claims to put in the key :param expires_delta: how long the token is good for :return: a JWT string """ if algorithm not in JWTBearerRSA.ALGORITHMS: raise ValueError(f'Unsupported Algorithm {algorithm}') if claims is None: claims = dict() if not set(claims).isdisjoint({'iat', 'exp'}): # I don't want the caller to deliver the issued at time nor the expiration for security raise ValueError('Invalid claims') issued = time.time() claims_to_encode = claims.copy() if expires_delta: expire = issued + expires_delta.total_seconds() else: expire = issued + TOKEN_LIFETIME_SECONDS claims_to_encode['iat'] = issued claims_to_encode['exp'] = expire # TODO: see if it makes more sense to use the same types that python-jose uses instead of a string here. encoded = jws.sign(claims_to_encode, get_private_key_str(), algorithm=algorithm) return encoded
def call( self, method_name: str, payload: Any, service_annotations: Mapping[str, Union[str, int, None]], method_annotations: Mapping[str, Union[str, int, None]], parameter_annotations: Mapping[str, Mapping[str, Union[str, int, None]]] ) -> Tuple[bool, Any]: logger = self.logger.getChild('call') signed_payload = sign({ '_method': method_name, **payload }, self.secret, algorithm=self.algorithm) request = urllib.request.Request( self.url, data=signed_payload.encode('ascii'), headers={ 'Accept': 'application/json', 'Content-Type': 'application/jose', }, ) logger.debug('An HTTP request for %s():\n%s %s\n%s\n\n%s', method_name, request.get_method(), request.full_url, request.headers, request.data) response = self.opener.open(request) try: content = json.load( io.TextIOWrapper(response, 'utf-8') # type: ignore ) except ValueError: response.seek(0) raise UnexpectedNirumResponseError(response.read().decode()) status = getattr(response, 'code', getattr(response, 'status', None)) assert status is not None return 200 <= status < 400, content
def pkcs11_jws_sign(data, key=None, headers=None) -> str: """ Perform JWS Sign with a key stored in an PKCS#11 token. This requires some trickery - temporary switch out the key class for the algorithm to P11Key before calling jws.sign. It is not possible to just register a new algorithm, say ECP11, because the algorithm is included in the JWT and the consumer of the JWT would expect ES256 (or similar) and not know how to handle ECP11. :return: A signed JWT """ global P11Key_params _p11key = P11Key('', '', P11Key_params) _alg = _p11key.get_jwk_alg() orig_key = jwk.get_key(_alg) try: jwk.register_key(_alg, P11Key) res = jws.sign(data, key, algorithm=_alg, headers=headers) except: raise finally: jwk.register_key(_alg, orig_key) return res
def on_connect_response(*resp): print(resp) if deb else None if type(resp[0]) == int: errors.manage_error(resp[0]) else: print('CONNECT RESPONSE') if deb2 else None print("response: ", resp[0]) if deb else None print("data response: ", resp[0]['data']) if deb else None print("sign response: ", resp[0]['sign']) if deb else None resp_data = json.loads( jws.verify(resp[0]['data'], pri_id, algorithms=['HS256']).decode()) print("decrypt data response: ", resp_data) if deb else None print("key in data response: ", resp_data['key']) if deb else None if sign.verify_sign(resp_data['key'], resp[0]['sign'], resp[0]['data']): print("valid sign") if deb else None global server_key server_key = resp_data['key'] req_data = {"otp": resp_data['otp']} print("data to send: ", req_data) if deb else None crypt_data = jws.sign(req_data, pri_id, algorithm='HS256') print("encrypt data to send: ", crypt_data) if deb else None sign_crypt_data = sign.sign_data(key.exportKey(), crypt_data) print("sign of en data send: ", sign_crypt_data) if deb else None req2 = { "pub_id": pub_id, "data": crypt_data, "sign": sign_crypt_data.decode() } print("send: ", req2) if deb else None print("CONNECT RESPONSE DONE") if deb2 else None socketIO.emit('connect_confirm', req2) socketIO.on('connect_estab', on_connect_estab) socketIO.wait(seconds=3) else: errors.manage_error(6)
def test_wrong_alg(self, payload): token = jws.sign(payload, ec_private_key, algorithm=ALGORITHMS.ES256) with pytest.raises(JWSError): jws.verify(token, rsa_public_key, ALGORITHMS.ES384)
def create_jws(self, id_token, client_secret, algorithm): from jose import jws return jws.sign(id_token, client_secret, algorithm=algorithm)
def test_wrong_alg(self, claims): token = jws.sign(claims, 'secret', algorithm=ALGORITHMS.HS256) with pytest.raises(JWSError): jws.verify(token, 'secret', ALGORITHMS.HS384)
def test_wrong_key(self, payload): token = jws.sign(payload, 'secret', algorithm=ALGORITHMS.HS256) with pytest.raises(JWSError): jws.verify(token, 'another', ALGORITHMS.HS256)
def test_invalid_key(self, payload): with pytest.raises(JWSError): jws.sign(payload, 'secret', algorithm='RS256')
def test_EC256K(self, payload): token = jws.sign(payload, ec_private_key, algorithm=ALGORITHMS.ES256K) assert jws.verify(token, ec_public_key, ALGORITHMS.ES256K) == payload
def test_e2e(self): # Go to dashboard and click sign-in self.selenium.get('%s' % self.site) self._wait_for_element_and_click('a.sign-in-btn') # On FxA site, click "Have an account? Sign in." and fill in the form self._wait_for_element_and_click('a.sign-in') self.selenium.find_element_by_css_selector('input.email').send_keys( self.email ) self.selenium.find_element_by_css_selector('input.password').send_keys( self.password ) self.selenium.find_element_by_css_selector("button#submit-btn").click() # Back at dashboard; should see manage apps button self._wait_for_element_and_click('a#manage-push-apps-btn') # Create a test app with vapid key app_name = 'selenium-%s' % str(uuid.uuid4()) self.selenium.find_element_by_css_selector('input#id_name').send_keys( app_name ) self.selenium.find_element_by_css_selector( 'input#id_vapid_key' ).send_keys( self.vapid_key ) self.selenium.find_element_by_css_selector("input#add-app-btn").click() # Sign JWS claims payload and submit jws_claims = self.selenium.find_element_by_css_selector( "input#vapid-key-token" ).get_attribute('value') signed_token = jws.sign(jws_claims, self.signing_key, algorithm='ES256') self.selenium.find_element_by_css_selector( 'input#id_signed_token' ).send_keys( signed_token ) self.selenium.find_element_by_css_selector( "input#validate-jwt-btn" ).click() self.assertIn( 'VAPID Key validated', self.selenium.find_element_by_css_selector('.callout.success').text ) # go to the push test page to create a pushManager to receive the push # test message # TODO: use dom.push.testing.ignorePermission in the firefox_profile # to make the page skip the permission prompt self.selenium.get('%s/push-test-page/' % self.site) # get the subscription info object off the page self._wait_for_element('pre#subscription_json') subscription_json = self.selenium.find_element_by_css_selector( 'pre#subscription_json' ) subscription = json.loads(subscription_json.text) # Send a push message with the VAPID headers message = "Testing push service" vapid = py_vapid.Vapid(private_key=self.signing_key.to_pem()) headers = vapid.sign({ "aud": "http://test.com", "sub": "mailto:[email protected]" }) WebPusher(subscription).send(message, headers) # go back to the push app page on the dashboard and poll for the # message to show up self.selenium.get('%s/push/apps/' % self.site) self._wait_for_element_and_click('a#%s' % app_name) self._wait_for_element('dl#push-app-info') message_found = False while not message_found: try: self.selenium.find_element_by_css_selector('tr.push-message') message_found = True except NoSuchElementException: self.selenium.refresh()
def test_invalid_key(self, claims): with pytest.raises(JWSError): jws.sign(claims, 'secret', algorithm='RS256')
def make_image_request_jwt(org_id, camera_id): return jws.sign(get_image_request_claim(org_id, camera_id), decrypt(jws_secret_key_b64_enc), algorithm='HS256')
def get_jws(path_name, camera_id): return jws.sign(claim_info(get_file_hash(path_name), extract_timestamp(path_name), camera_id), decrypt(jws_secret_key_b64_enc), algorithm='HS256')
def testHMAC512(self, claims): token = jws.sign(claims, 'secret', algorithm=ALGORITHMS.HS512) assert jws.verify(token, 'secret', ALGORITHMS.HS512) == claims
def testHMAC512(self, payload): token = jws.sign(payload, 'secret', algorithm=ALGORITHMS.HS512) assert jws.verify(token, 'secret', ALGORITHMS.HS512) == payload
def create_jwt(subject): return jws.sign(claim_info(subject), decrypt(hmac_secret_key_b64_cipher), algorithm='HS256')
def test_unsupported_alg(self, payload): with pytest.raises(JWSError): jws.sign(payload, 'secret', algorithm='SOMETHING')
def test_EC512(self, claims): token = jws.sign(claims, ec_private_key, algorithm=ALGORITHMS.ES512) assert jws.verify(token, ec_public_key, ALGORITHMS.ES512) == claims
def test_RSA512(self, payload): token = jws.sign(payload, rsa_private_key, algorithm=ALGORITHMS.RS512) assert jws.verify(token, rsa_public_key, ALGORITHMS.RS512) == payload
def test_wrong_key(self, claims): token = jws.sign(claims, rsa_private_key, algorithm=ALGORITHMS.RS256) with pytest.raises(JWSError): jws.verify(token, rsa_public_key, ALGORITHMS.HS256)
def test_RSA384(self, claims): token = jws.sign(claims, rsa_private_key, algorithm=ALGORITHMS.RS384) assert jws.verify(token, rsa_public_key, ALGORITHMS.RS384) == claims
def test_RSA384(self, payload): token = jws.sign(payload, rsa_private_key, algorithm=ALGORITHMS.RS384) assert jws.verify(token, rsa_public_key, ALGORITHMS.RS384) == payload
def test_EC512(self, payload): token = jws.sign(payload, ec_private_key, algorithm=ALGORITHMS.ES512) assert jws.verify(token, ec_public_key, ALGORITHMS.ES512) == payload
def _gen_jwt(self, header, payload): sk256p = ecdsa.SigningKey.generate(curve=ecdsa.NIST256p) vk = sk256p.get_verifying_key() sig = jws.sign(payload, sk256p, algorithm="ES256").strip('=') crypto_key = utils.base64url_encode(vk.to_string()).strip('=') return sig, crypto_key
def test_unsupported_alg(self, claims): with pytest.raises(JWSError): jws.sign(claims, 'secret', algorithm='SOMETHING')