Beispiel #1
0
 def validate(ticket):
     try:
         utils.verify_signature(ticket.get_unique_repr(), ticket.signature,
                                ticket.node.public_key)
     except InvalidSignature:
         ticket.errors = "Invalid ballot claim ticket signature"
         raise InvalidSignature(ticket.errors)
Beispiel #2
0
 def validate_transaction(transaction):
     """Validates a transaction's signature and returns whether its content matches the signature. Note that this validation
     may not be enough for a transaction; the content for a specific transaction may need further validation. Use this method 
     as a first-step verification of any transaction.
     Args:
         transaction         transaction to be validated
     """
     try:
         utils.verify_signature(
             transaction.get_unique_repr(**transaction.signature_kwargs),
             transaction.signature, transaction.node.public_key)
     except InvalidSignature as e:
         public_key = transaction.node.public_key
         raise InvalidSignature(
             'Invalid signature by public key: {}'.format(hash(public_key)))
Beispiel #3
0
def trigger_build():
    """
    Endpoint where GitHub will send a POST request to (payload URL), with
    details of a subscribed event. For now, we only do something special when
    we get a 'push' event.

    Events: https://developer.github.com/webhooks/#events
    """
    delivery_id = request.headers.get('X-Github-Delivery')  # soon for logging
    event = request.headers.get('X-Github-Event')
    signature = request.headers.get('X-Hub-Signature')

    if event != 'push':
        return (jsonify({'msg': 'Payload received'}), 200)

    data = request.get_data()
    if not verify_signature(data, signature):
        return (jsonify({'msg': 'Hash signatures do not match'}), 400)

    payload = request.get_json()

    # This part is where we execute our deploy/build scripts, depending on how
    # we want it to be run.
    # For this case, we do the following:
    # 1) Check branch, only proceed if branch is `master`.
    # 2) Get project/repository name (for handling many repositories' webhooks)
    # 3) Check if there are npm dependency changes via commits' modified files
    # 4) If so, make sure we could tell the deploy script (using flags, etc.)
    # 5) Execute deploy script with the project name, and the above flag (#4)

    # only proceed if branch is master
    if payload.get('ref') == 'refs/heads/master':
        # get project name
        project_name = payload.get('repository').get('name')

        # check if there are npm dependency changes
        commits = payload.get('commits')
        dependency_change_commits = [commit for commit in commits
                                     if 'package.json' in commit['modified']]

        # take directory of deploy script from environment variable
        default_script_dir = os.path.join(os.getcwd(), 'deploy.sh')
        command_params = [config('DEPLOY_SCRIPT_DIR', default_script_dir)]

        # append command params, add -d flag if npm dependency changes exist
        if len(dependency_change_commits) > 1:
            command_params.append('-d')
        command_params.append(project_name)

        # TODO: Add logging
        try:
            cmd_output = subprocess.check_output(command_params,)
            return (jsonify({
                'msg': 'Build success',
                'output': cmd_output.decode('utf-8')
            }), 200)
        except subprocess.CalledProcessError as error:
            return (jsonify({'msg': error.output.decode('utf-8')}), 400)

    return (jsonify({'msg': 'Valid, but push not in master branch'}), 200)
Beispiel #4
0
def get_packages_data():
    "Function queries the iQuality website for packages json data"
    if config.use_local_json_files:
        with open(r"%s\packages.json" % config.local_json_files_path,
                  'r') as f:
            data = f.read()
        return json.loads(data, object_pairs_hook=OrderedDict)

    try:
        obj = urllib2.urlopen(config.packages_json_url,
                              timeout=config.webservices_timeout)
        data = obj.read()
        obj.close()
        obj = urllib2.urlopen("%s.sign" % config.packages_json_url,
                              timeout=config.webservices_timeout)
        sign = obj.read()
        obj.close()

        assert utils.verify_signature(data, sign, config.pubkey_path)
        log.debug('packages_json_url signature check passed')
        return json.loads(data, object_pairs_hook=OrderedDict)
    except:
        log.error('packages_json_url signature check FAILED:')
        log.error(traceback.format_exc())
    return {}
Beispiel #5
0
def handle_payload():
    content = request.get_json(silent=True)
    #embed()
    header_signature = request.headers['X-Hub-Signature']
    embed()
    if header_signature is None:
        abort(403)
    if not utils.verify_signature(header_signature,request.data,GITHUB_HOOK_SECRET):
        abort(403)

    return "Authenticated request :D"
Beispiel #6
0
	def post(self):

		# FIXME implement some sort of size limits, i.e. no results over 1MB or something like that
		# FIXME implement some sort of rate limits, i.e. no client can submit over 1000 results per hour or something like that

		args = result_parser().parse_args()

		# fetch info about the machine
		with DB() as (conn, cursor):
			
			cursor.execute('SELECT id, secret_key FROM machines WHERE name = %(name)s AND is_approved AND is_active', {'name' : args.machine})
			machine = cursor.fetchone()

			if not machine:
				abort(401, message="unknown / inactive machine")

			# verify the signature
			if not verify_signature(args, secret=machine['secret_key'], signature=args.signature):
				abort(401, message='invalid signature')

			cursor.execute('SELECT v.id AS id FROM distribution_versions v JOIN distributions d ON (d.id = v.dist_id) WHERE dist_name = %(name)s AND version_number = %(version)s',
							{'name' : args.distribution, 'version' : args.version})
			version = cursor.fetchone()

			if not version:
				abort(401, message="unknown distribution/version")

			# check that we haven't seen the UUID before (this means someone bad can't replay the message over and over)
			cursor.execute('SELECT result_uuid AS uuid FROM results WHERE result_uuid = %(uuid)s LIMIT 1', {'uuid' : args.uuid})
			result = cursor.fetchone()

			if result:
				abort(401, message="duplicate uuid")

		# OK, so the submitted result seems to be OK ... let's store the data
		with DB(False) as (conn, cursor):
			
			cursor.execute('''INSERT INTO results (result_uuid, machine_id, dist_version_id, pg_version, pg_config, env_info, load_result, install_result, check_result,
												   load_duration, install_duration, check_duration, log_load, log_install, log_check, check_diff)
							  VALUES (%(uuid)s, %(machine)s, %(version)s, %(pgversion)s, %(config)s, %(env)s, %(load)s, %(install)s, %(check)s,
									  %(load_duration)s, %(install_duration)s, %(check_duration)s, %(load_log)s, %(install_log)s, %(check_log)s, %(diff)s)''',
							  {'uuid' : args.uuid, 'machine' : machine['id'], 'version' : version['id'], 'pgversion' : get_pg_version(args.config),
							   'load' : (args.load != 'unknown' and args.load or None), 'install' : (args.install != 'unknown' and args.install or None), 'check' : (args.check != 'unknown' and args.check or None),
							   'install_log' : base64.b64decode(args.install_log), 'load_log' : base64.b64decode(args.load_log), 'check_log' : base64.b64decode(args.check_log), 'diff' : base64.b64decode(args.check_diff),
							   'install_duration' : args.install_duration, 'load_duration' : args.load_duration, 'check_duration' : args.check_duration, 
							   'config' : args.config, 'env' : args.env})

			conn.commit()

		return {'uuid' : args.uuid}
Beispiel #7
0
def get_packages_data():
	"Function queries the iQuality website for packages json data"
	try:
		obj = urllib2.urlopen(config.packages_json_url, timeout=config.webservices_timeout)
		data = obj.read()
		obj.close()
		obj = urllib2.urlopen("%s.sign" % config.packages_json_url, timeout=config.webservices_timeout)
		sign = obj.read()
		obj.close()
		
		assert utils.verify_signature(data, sign, config.pubkey_path)
		log.debug('packages_json_url signature check passed')
		return json.loads(data, object_pairs_hook=OrderedDict)
	except:
		log.error('packages_json_url signature check FAILED:')
		log.error(traceback.format_exc())
	return {}
Beispiel #8
0
    def verify_server(self, message):
        if self.state != SERVER_AUTH:
            logger.debug("Invalid state")
            self.transport.close()
            self.loop.stop()

        logger.info("Verifying server")

        data = message.get("data", None)
        server_certificate = certificate_object_from_pem(
            base64.b64decode(data['certificate'].encode()))
        signed_nonce = base64.b64decode(data['sign_nonce'].encode())

        certificates = load_certificates("client_certs/")

        chain = []
        chain_completed = construct_certificate_chain(chain,
                                                      server_certificate,
                                                      certificates)

        if not chain_completed:
            error_message = "Couldn't complete the certificate chain"
            logger.warning(error_message)
            message = {"type": "ERROR", "message": error_message}
            self._send(message)
            self.transport.close()
            self.loop.stop()
        else:
            valid_chain, error_messages = validate_certificate_chain(chain)

            if not valid_chain:
                logger.error(error_messages)
                message = {"type": "ERROR", "message": error_messages}
                self._send(message)
                self.transport.close()
                self.loop.stop()
            else:
                if verify_signature(server_certificate, signed_nonce,
                                    self.nonce):
                    message = {"type": "SUCCESS_AUTH"}
                    self._send(message)

        self.state = STATE_AUTH
Beispiel #9
0
def get_components_data():
    "Function queries the iQuality website for components json data"
    try:
        obj = urllib2.urlopen(config.components_json_url,
                              timeout=config.webservices_timeout)
        data = obj.read()
        obj.close()
        obj = urllib2.urlopen("%s.sign" % config.components_json_url,
                              timeout=config.webservices_timeout)
        sign = obj.read()
        obj.close()

        assert utils.verify_signature(data, sign, config.pubkey_path)
        log.debug('components_json_url signature check passed')
        return json.loads(data, object_pairs_hook=OrderedDict)
    except:
        log.error('components_json_url signature check FAILED:')
        log.error('config.components_json_url = %s' %
                  config.components_json_url)
        log.error(traceback.format_exc())
        return {}
Beispiel #10
0
def get_components_data():
	"Function queries the iQuality website for components json data"
	if config.use_local_json_files:
		with open(r"%s\components.json" % config.local_json_files_path, 'r') as f:
			data = f.read()
		return json.loads(data, object_pairs_hook=OrderedDict)
		
	try:
		obj = urllib2.urlopen(config.components_json_url, timeout=config.webservices_timeout)
		data = obj.read()
		obj.close()
		obj = urllib2.urlopen("%s.sign" % config.components_json_url, timeout=config.webservices_timeout)
		sign = obj.read()
		obj.close()
		
		assert utils.verify_signature(data, sign, config.pubkey_path)
		log.debug('components_json_url signature check passed')
		return json.loads(data, object_pairs_hook=OrderedDict)
	except:
		log.error('components_json_url signature check FAILED:')
		log.error(traceback.format_exc())
	return {}
Beispiel #11
0
 def test_verify_signature(self):
     message = "nooneknows"
     message_encoded = message.encode('utf8')
     signature = rsa.sign(message_encoded, self.privkey, "SHA-256")
     actual = utils.verify_signature(message_encoded, signature, self.pubkey)
     self.assertTrue(actual, True)
Beispiel #12
0
async def stripe_hook(request: web.Request):
    if not verify_signature(request, signing_key):
        return web.Response(status=401)

    print(await request.json())
    return web.Response()
Beispiel #13
0
def abort_submission(request):
    logger = utils.CloudLogger().log_request(request)
    try:

        data = request.get_json()

        # 1) Validate the token

        if not isinstance(data, dict):
            return ({
                'error':
                "Bad Request",
                'message': ("No data was provided" if data is None else
                            "Expected JSON dictionary in request body")
            }, 400)

        token = utils.extract_token(request.headers, data)
        if token is None:
            return ({
                'error': 'Bad Request',
                'message': 'Token must be provided in header or body'
            }, 400)

        token_info = utils.get_token_info(token)
        if 'error' in token_info:
            return ({
                'error':
                'Invalid Token',
                'message':
                token_info['error_description'] if 'error_description'
                in token_info else 'Google rejected the client token'
            }, 401)

        if not utils.validate_token(token_info):
            return ({
                'error':
                'Rejected token',
                'message':
                'Token was valid but did not meet Lapdog security requirements. Token must have email, profile, openid, and devstorage.read_write scopes.'
                ' Broad users must authenticate via a LapdogToken'
            }, 403)

        # 2) Validate user's permission for the bucket

        if 'bucket' not in data:
            return ({
                'error': 'Bad Request',
                'message': 'Missing required parameter "bucket"'
            }, 400)

        session = utils.generate_user_session(token)

        read, write = utils.validate_permissions(session, data['bucket'])
        if read is None:
            # Error, write will contain a message
            return ({
                'error': 'Cannot Validate Bucket Permissions',
                'message': write
            }, 400)
        if not (read and write):
            # User doesn't have full permissions to the bucket
            return ({
                'error':
                'Not Authorized',
                'message':
                'User lacks read/write permissions to the requested bucket'
            }, 401)

        # 3) Check that submission.json exists, and is less than 1 Gib

        if 'submission_id' not in data:
            return ({
                'error': 'Bad Request',
                'message': 'Missing required parameter "submission_id"'
            }, 400)

        submission = utils.fetch_submission_blob(session, data['bucket'],
                                                 data['submission_id'])

        result, message = utils.validate_submission_file(submission)
        if not result:
            return ({'error': 'Bad Submission', 'message': message}, 400)

        # 4) Download submission and parse operation

        try:
            submission = json.loads(submission.download_as_string().decode())
        except:
            return ({
                'error': 'Invalid Submission',
                'message': 'Submission was not valid JSON'
            }, 400)

        if 'operation' not in submission:
            return ({
                'error': 'Invalid Submission',
                'message': 'Submission contained no operation metadata'
            }, 400)

        signature_blob = utils.getblob(
            'gs://{bucket}/lapdog-executions/{submission_id}/signature'.format(
                bucket=data['bucket'], submission_id=data['submission_id']),
            credentials=session.credentials)
        if not signature_blob.exists():
            return ({
                'error':
                'No Signature',
                'message':
                'The submission signature could not be found. Refusing to abort job'
            }, 403)

        if not utils.verify_signature(
                signature_blob,
            (data['submission_id'] + submission['operation']).encode()):
            return ({
                'error':
                'Invalid Signature',
                'message':
                'Could not validate submission signature. Refusing to abort job'
            }, 403)

        core_session = utils.generate_core_session()

        # 5) Generate abort key

        logger.log("Generating new signature", data=data['submission_id'])

        utils.sign_object(
            data['submission_id'].encode(),
            utils.getblob(
                'gs://{bucket}/lapdog-executions/{submission_id}/abort-key'.
                format(bucket=data['bucket'],
                       submission_id=data['submission_id']),
                credentials=session.credentials), core_session.credentials)

        if 'hard' in data and data['hard']:
            # 6) Abort operation
            logger.log("Hard-aborting submission",
                       submission_id=data['submission_id'],
                       operation_id=submission['operation'],
                       severity='NOTICE')
            response = core_session.post(
                "https://genomics.googleapis.com/v2alpha1/{operation}:cancel".
                format(operation=quote(
                    submission['operation'])  # Do not quote slashes here
                       ))

            return response.text, response.status_code
        return ({
            'status':
            'Aborting',
            'message':
            'A soft-abort request has been sent.'
            ' If the submission does not abort soon, abort it with hard=True to force-kill the cromwell server'
        }, 200)
    except:
        logger.log_exception()
        return ({
            'error': 'Unknown Error',
            'message': traceback.format_exc()
        }, 500)
Beispiel #14
0
    def setup(self):
        print("The merchant is running on port: 3000.")
        print(
            "\n -------------------------------------------------------------------------------------------- \n"
        )

        # -------------------------------------- Setup protocol ----------------------------------------
        print("Setup sub-protocol: \n")

        # 2
        # receive data
        data = self.connection.recv(4096)

        # deserialize data
        payload = pickle.loads(data)

        # Hybrid decryption of AES and RSA client's key
        k, self.public_client_key = hybrid_decryption(payload,
                                                      self.private_key)
        print(f"[RECEIVED] Client's AES key: \n{k}\n")
        print(f"[RECEIVED] Client's public key: \n{self.public_client_key}\n")

        # Create session id and digital signature using private merchant RSA key
        session_id = utils.get_session_id()
        client_signature = utils.proceed_signature(session_id,
                                                   self.private_key)

        print(f"[CREATE] Session id: \n{session_id}\n")
        print(f"[CREATE] Client signature: \n{client_signature}\n")

        # Encrypt data with AES key
        k = utils.generate_k()
        encrypted_session_id = utils.aes_encryption(k, session_id)
        encrypted_client_signature = utils.aes_encryption(k, client_signature)

        # Encrypt AES key with client's RSA public key
        encrypted_k = utils.rsa_encryption(
            k, RSA.importKey(self.public_client_key))

        # Send payload to client
        prepared_payload = {
            "session_id": encrypted_session_id,
            "sid_signature": encrypted_client_signature,
            "k_encryption": encrypted_k
        }

        print(f"[SENT] Encrypted session id: \n{encrypted_session_id}\n")
        print(
            f"[SENT] Encrypted client signature: \n{encrypted_client_signature}\n"
        )
        self.connection.send(pickle.dumps(prepared_payload))

        # ---------------------------------- Exchange protocol -----------------------------------------

        print(
            "\n -------------------------------------------------------------------------------------------- \n"
        )
        print("Exchange protocol:\n")
        # receive data
        data = self.connection.recv(4096)

        # deserialize data
        second_payload = pickle.loads(data)

        # decrypt
        pm_po_key = utils.rsa_decryption(second_payload["pm_po_key"],
                                         self.private_key)
        pm_po = utils.aes_decryption(pm_po_key, second_payload["pm_po"])

        # deserialize PM, PO
        loaded_pm_po = pickle.loads(pm_po)
        pm, po = loaded_pm_po[0], loaded_pm_po[1]

        print(f"[RECEIVED] PM: \n{pm}\n")
        print(f"[RECEIVED] PO: \n{po}\n")

        # verify signature
        if utils.verify_signature(
                pickle.dumps(
                    [po["OrderDesc"], po["SID"], po["Amount"], po["NC"]]),
                RSA.importKey(self.public_client_key), po["SigC"]):

            # 4.
            # Create signature for pg using merchant private key (SigM(SID, Amount, PubKC))
            merchant_signature = utils.proceed_signature(
                pickle.dumps([po["SID"], po["Amount"],
                              self.public_client_key]), self.private_key)

            print(f"[CREATE] Merchant signature: \n{merchant_signature}\n")

            # Encrypt data (PM, SigM) and AES symmetric key
            k = utils.generate_k()
            encrypted_pm = utils.aes_encryption(
                k, pickle.dumps([pm, merchant_signature]))
            encrypted_pm_k = utils.rsa_encryption(k, self.pg_public_key)

            # Prepare payload
            prepared_pg_payload = {
                "encrypted_pm": encrypted_pm,
                "encrypted_pm_k": encrypted_pm_k
            }

            # Connecting to PG server
            self.pg_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.pg_socket.connect(("127.0.0.1", 3001))

            # Send data to PG (PM + SigM(Sid, PubKC, Amount))
            print(
                f"[SENT] Encrypted PM + SigM(Sid, PubKC, Amount): \n{encrypted_pm}\n"
            )
            self.pg_socket.send(pickle.dumps(prepared_pg_payload))

            # 5
            # Receive data from PG (Resp, Sid, SigPG(Resp, Sid, Amount, NC))
            data = self.pg_socket.recv(4096)
            pg_payload = pickle.loads(data)

            decrypted_pg_key = utils.rsa_decryption(pg_payload[1],
                                                    self.private_key)
            decrypted_pg_payload = utils.aes_decryption(
                decrypted_pg_key, pg_payload[0])
            deserialized_pg_payload = pickle.loads(decrypted_pg_payload)

            print(
                f"[RECEIVED] Resp, Sid, SigPG(Resp, Sid, Amount, NC): \n{deserialized_pg_payload}\n"
            )

            # 6
            # Verify PG signature and session id.
            if session_id == deserialized_pg_payload["SID"]:
                if utils.verify_signature(
                        pickle.dumps([
                            deserialized_pg_payload["Resp"], po["SID"],
                            po["Amount"], po["NC"]
                        ]), self.pg_public_key,
                        deserialized_pg_payload["SigPG"]):

                    # Encrypt data (Resp, Sid, SigPG(Resp, Sid, Amount, NC)) with client's public key
                    k = utils.generate_k()
                    encrypted_merchant_payload = utils.aes_encryption(
                        k, decrypted_pg_payload)
                    encrypted_merchant_key = utils.rsa_encryption(
                        k, RSA.importKey(self.public_client_key))

                    prepared_payload = {
                        "encrypted_payload": encrypted_merchant_payload,
                        "encrypted_key": encrypted_merchant_key
                    }

                    print(
                        f"[SENT] Resp, Sid, SigPG(Resp, Sid, Amount, NC): \n{prepared_payload}\n"
                    )
                    self.connection.send(pickle.dumps(prepared_payload))

                else:
                    print(f"[ERROR] Invalid signature")
                    exit(2)
            else:
                print(f"[ERROR] Invalid session id")
                exit(1)

        else:
            print("[ERROR] Invalid signature")
            exit(0)

        self.connection.close()
Beispiel #15
0
def add_coins(request):
    """
    Add Pinna coins to the current user's account
    """
    session = utils.check_auth_token(request)
    if not session:
        return utils.invalid_auth_response()

    coins = request.DATA.get('coins', None)
    purchase_data = request.DATA.get('purchase_data', None)
    signature = request.DATA.get('signature', None)

    if not (coins and purchase_data and signature):
        msg = "Missing: "

        misses = []
        if not coins:
            misses.append("coins")

        if not purchase_data:
            misses.append("purchase_data")

        if not signature:
            misses.append("signature")

        msg += ",".join(misses)
        return utils.failed_response(msg, "empty_fields")

    try:
        json_data = json.loads(purchase_data)
    except:
        msg = "Invalid purchase_data"
        return utils.failed_response(msg, "invalid_purchase_data")

    if not utils.verify_signature(purchase_data, signature):
        msg = "Signature does not match"
        return utils.failed_response(msg, "signature_not_match")

    order_id = json_data.get('orderId', '')
    date = datetime.fromtimestamp(json_data.get('purchaseTime')/1000)
    state = json_data.get('purchase_state', 1)
    try:
        PinnaOrder.objects.get(pk=order_id)
        msg = "The order already existed"
        return utils.failed_response(msg, "order_existed")
    except PinnaOrder.DoesNotExist:
        order = None
        try:
            order = PinnaOrder.objects.create(order_id=order_id,
                                      user=session.user,
                                      purchase_state=state,
                                      purchase_time=date,
                                      purchase_data=purchase_data)
            session.user.profile.amount += int(coins)
            session.user.profile.save()
            msg = "%s PINNA coins were added to the user account" %coins
            return utils.successful_response(msg, "ok", amount=session.user.profile.amount)
        except:
            if order:
                order.delete()
            msg = "Can't add PINNA coins to the user account"
            return utils.failed_response(msg, "failed")
    def run(self):
        # -------------------------------------- Exchange protocol ------------------------------------------------
        print("\nExchange protocol: \n")
        data = self.connection.recv(4096)
        payload = pickle.loads(data)

        # Decrypt PM from merchant
        decrypted_pm_key = utils.rsa_decryption(payload["encrypted_pm_k"],
                                                self.private_key)
        decrypted_pm = utils.aes_decryption(decrypted_pm_key,
                                            payload["encrypted_pm"])

        deserialized_pm = pickle.loads(
            decrypted_pm)  # contains PM, merchant signature.

        # Decrypt PI, SigC(PI)
        decrypted_pi_key = utils.rsa_decryption(
            deserialized_pm[0]["encrypted_key"], self.private_key)
        decrypted_pi = utils.aes_decryption(
            decrypted_pi_key, deserialized_pm[0]["encrypted_data"])

        # PI
        pi = pickle.loads(decrypted_pi)[0]

        # SigC(PI)
        pi_client_signature = pickle.loads(decrypted_pi)[1]

        # Decrypted merchant signature SigM(Sid, PubKC, Amount)
        decrypted_merchant_signature = deserialized_pm[1]

        print(f"[RECEIVED] PI: \n{pi}\n")
        print(f"[RECEIVED] SigC(PI): \n{pi_client_signature}\n")
        print(
            f"[RECEIVED] SigM(Sid, PubKC, Amount): \n{decrypted_merchant_signature}\n"
        )

        self.get_merchant_public_key()

        # Verify merchant's signature SigM(Sid, Amount, PubKC)
        if utils.verify_signature(
                pickle.dumps([pi["SID"], pi["Amount"], pi["PubKC"]]),
                self.merchant_public_key, decrypted_merchant_signature):

            # Verify client's signature SigC(PI)
            if utils.verify_signature(pickle.dumps(pi),
                                      RSA.importKey(pi["PubKC"]),
                                      pi_client_signature):
                response = None
                for i in range(len(bank)):
                    item = bank[i]
                    if item["CardN"] == pi["CardN"] and item["CardExp"] == pi["CardExp"] and \
                            item["CCode"] == pi["CCode"]:

                        if pi["Amount"] <= item["Balance"]:
                            item["Balance"] -= pi["Amount"]
                            response = "Transaction accepted"
                            bank[i] = item
                            json.dump(bank, open("bank/accounts.json", "w"))
                        else:
                            response = "Transaction refused"

                        # 5.
                        # Creating PG signature SigPG(Resp, Sid, Amount, NC)
                        pg_signature = utils.proceed_signature(
                            pickle.dumps(
                                [response, pi["SID"], pi["Amount"], pi["NC"]]),
                            self.private_key)

                        print(
                            f"[CREATE] Payment gateway signature: \n{pg_signature}\n"
                        )

                        # Preparing payload to be sent to merchant.
                        prepared_payload = {
                            "Resp": response,
                            "SID": pi["SID"],
                            "SigPG": pg_signature
                        }

                        # Hybrid encryption using merchant's public key
                        k = utils.generate_k()
                        encrypted_payload = utils.aes_encryption(
                            k, pickle.dumps(prepared_payload))
                        encrypted_payload_key = utils.rsa_encryption(
                            k, self.merchant_public_key)

                        # Send data to merchant (Resp, Sid, SigPG(Resp, Sid, Amount, NC))
                        print(
                            f"[SENT] Resp, Sid, SigPG(Resp, Sid, Amount, NC): "
                            f"\n{pickle.dumps([encrypted_payload_key, encrypted_payload])}\n"
                        )

                        self.connection.send(
                            pickle.dumps(
                                [encrypted_payload, encrypted_payload_key]))
            else:
                print(f"[ERROR] Invalid signature")
                exit(1)
        else:
            print(f"[ERROR] Invalid signature")
            exit(0)

        self.connection.close()
Beispiel #17
0
    def connect_to_merchant(self, host, port):
        self.socket.connect((host, port))

        # -------------------------------------- Setup protocol -------------------------------------------

        # 1
        self.get_merchant_public_key()

        # Encrypt client key with AES symmetric key + AES symmetric key encrypted with merchant rsa public key
        payload = hybrid_encryption(self.public_key, self.merchant_public_key)
        self.socket.send(pickle.dumps(payload))

        # Received data from Merchant. (Session id and SigM(Sid))
        data = self.socket.recv(8192)
        payload = pickle.loads(data)

        encrypted_aes_key = payload['k_encryption']
        decrypted_aes_key = utils.rsa_decryption(encrypted_aes_key,
                                                 self.private_key)

        self.session_id = utils.aes_decryption(decrypted_aes_key,
                                               payload['session_id'])
        self.session_signature = utils.aes_decryption(decrypted_aes_key,
                                                      payload['sid_signature'])

        if utils.verify_signature(self.session_id, self.merchant_public_key,
                                  self.session_signature):
            print(f"[RECEIVED] Session id: \n{self.session_id}\n")
            print(
                f"[RECEIVED] Session signature: \n{self.session_signature}\n")
        else:
            print("[ERROR] Invalid signature")
            exit(0)

        # ------------------------------------------- Exchange -------------------------------------------

        self.get_pg_public_key()
        nonce = random.getrandbits(16)
        order_description = "Omen by HP 15-dc0018nq"
        amount = 3000

        # PO signature
        po_client_signature = utils.proceed_signature(
            pickle.dumps([order_description, self.session_id, amount, nonce]),
            self.private_key)

        # payment order
        po = {
            "OrderDesc": order_description,
            "SID": self.session_id,
            "Amount": amount,
            "NC": nonce,
            "SigC": po_client_signature
        }

        # payment information
        pi = {
            "CardN": "4034783123305160",
            "CardExp": "04/2025",
            "CCode": "627",
            "SID": self.session_id,
            "Amount": amount,
            "PubKC": self.public_key,
            "NC": nonce,
            "M": "Amazon"
        }

        print(f"[CREATE] PO: \n{po}\n")
        print(f"[CREATE] PI: \n{pi}\n")

        # PI client signature
        pi_client_signature = utils.proceed_signature(pickle.dumps(pi),
                                                      self.private_key)

        print(f"[CREATE] PI Client Signature: \n{pi_client_signature}\n")

        # Encrypt PI, SigC(PI) with PG RSA public key
        k = utils.generate_k()
        encrypted_pi = utils.aes_encryption(
            k, pickle.dumps([pi, pi_client_signature]))
        encrypted_key = utils.rsa_encryption(k, self.pg_public_key)

        pm = {
            "encrypted_data": encrypted_pi,  # encrypted_data = PI, SigC(PI)
            "encrypted_key": encrypted_key
        }

        print(f"[CREATE] PM: \n{pm}\n")

        # Encrypt PM, PO with M rsa public key
        k = utils.generate_k()
        encrypted_pm_po = utils.aes_encryption(k, pickle.dumps([pm, po]))
        encrypted_pm_po_key = utils.rsa_encryption(k, self.merchant_public_key)

        payload = {"pm_po": encrypted_pm_po, "pm_po_key": encrypted_pm_po_key}

        # 3.
        print(f"[SENT] PM, PO: \n{payload}\n")
        self.socket.send(pickle.dumps(payload))

        # 6.
        # Receive payload Resp, Sid, SigPG(Resp, Sid, Amount, NC)
        data = self.socket.recv(4096)
        payload = pickle.loads(data)
        print(
            f"[RECEIVED] Resp, Sid, SigPG(Resp, Sid, Amount, NC): \n{payload}\n"
        )

        # Decrypt data
        decrypted_payload_key = utils.rsa_decryption(payload["encrypted_key"],
                                                     self.private_key)
        decrypted_payload = pickle.loads(
            utils.aes_decryption(decrypted_payload_key,
                                 payload["encrypted_payload"]))

        # Verify signature and session id
        if self.session_id == decrypted_payload["SID"]:
            if utils.verify_signature(
                    pickle.dumps([
                        decrypted_payload["Resp"], self.session_id,
                        pi["Amount"], pi["NC"]
                    ]), self.pg_public_key, decrypted_payload["SigPG"]):

                print(
                    f"[RECEIVED] Response of transaction: \n{decrypted_payload['Resp']}\n"
                )
                self.socket.close()

            else:
                print(f"[ERROR] Invalid signature")
        else:
            print(f"[ERROR] Invalid session id")
Beispiel #18
0
    def login(self, message):
        if self.state != LOGIN:
            logger.warning("Invalid State")
            return False

        logger.info(f"Loging in")

        data = message.get("data", None)

        self.state = LOGIN_FINISH
        status = False  # status = False -> if login wasn't a success
        if AUTH_TYPE == AUTH_MEM:
            new_otp = base64.b64decode(data["otp"].encode())
            current_otp_client = digest(new_otp, "SHA256")

            message = {
                "type": "ERROR",
                "message": "Invalid credentials for logging in"
            }

            if self.current_otp == current_otp_client:  # success login
                status = True

                if self.clear_credentials:
                    logger.info(
                        "Clearing old credentials and saving new ones.")

                    self.current_otp_index = self.new_index + 1
                    self.current_otp_root = self.new_root
                    new_otp = self.new_otp

                with open(f"credentials/{self.user_id}_index", "wb") as file:
                    file.write(f"{self.current_otp_index - 1}".encode())
                with open(f"credentials/{self.user_id}_root", "wb") as file:
                    file.write(self.current_otp_root)
                with open(f"credentials/{self.user_id}_otp", "wb") as file:
                    file.write(new_otp)

                logger.info(
                    "User logged in with success! Credentials updated.")
            else:
                logger.info(
                    "User not logged in! Wrong credentials where given.")
        elif AUTH_TYPE == AUTH_CC:
            cc_certificate = certificate_object(
                base64.b64decode(data["certificate"].encode()))
            signed_nonce = base64.b64decode(data["sign_nonce"].encode())

            certificates = load_certificates("cc_certificates/")

            chain = []
            chain_completed = construct_certificate_chain(
                chain, cc_certificate, certificates)

            if not chain_completed:
                error_message = "Couldn't complete the certificate chain"
                logger.warning(error_message)
                message = {"type": "ERROR", "message": error_message}
                status = False
            else:
                valid_chain, error_messages = validate_certificate_chain(chain)
                if not valid_chain:
                    logger.error(error_messages)
                    message = {"type": "ERROR", "message": error_messages}
                    status = False
                else:
                    status = verify_signature(cc_certificate, signed_nonce,
                                              self.nonce)

            if status:
                oid = ObjectIdentifier(
                    "2.5.4.5")  # oid of citizens card's CI (civil id)
                self.user_id = cc_certificate.subject.get_attributes_for_oid(
                    oid)[0].value

                logger.info("User logged in with success")
                message = {"type": "OK"}

        # Access verification
        if status:
            access_result = self.check_access()
            if not access_result[0]:
                logger.warning(access_result[1])

                status = False
                message = {"type": "ERROR", "message": access_result[1]}
            else:
                message = {"type": "OK"}
                logger.info(access_result[1])

        self._send(message)
        return status
Beispiel #19
0
    def server_init(self):

        # Generating server nonce
        self.generate_server_nonce()

        # Reading from server certificate to send it to client
        with open (self.servercert, 'r') as data:
            server_certificate = data.read()

        # Generating the message for client, using | as delimiter, with the nonce, the acknowledgement
        # of the cipher and the server certificate  
        self.serverinit = 'ServerInit' + '|' + self.server_nonce + '|' + self.client_cipher + '|' + server_certificate

        if self.authentication == 'ClientAuth':
            self.serverinit = self.serverinit + '|' + 'CertReq'

        self.clientsock.send(self.serverinit)

        # We store serverinit without the cipher for the checksum message
        # (it's in the slide, but I wouldn't do this)
        self.serverinit = 'ServerInit' + '|' + self.server_nonce + '|' + server_certificate
        if self.authentication == 'ClientAuth':
            self.serverinit = self.serverinit + '|' + 'CertReq'





        # ------------------------------------------------------------------------------




        # Getting response from client to go on with the handshake procedure

        client_response = self.clientsock.recv(8192)
        print '-------------------------------\n'
        print client_response
        print '\n-------------------------------'

        # Splitting the message and checking if it is the expected type
        splitted_response = client_response.split('|')
        if not splitted_response[0] == 'ClientKex':
            self.clientsock.close()
            raise Exception('Unexpected message type')

        rsa_encrypted_pms = splitted_response[1]

        # If the authentication type requires the client cert:
        if self.authentication == 'ClientAuth':
            self.client_certificate = splitted_response[3]
            nonce_signature = splitted_response[4]

            # Checking client certs
            if not self.certificate_is_valid(self.client_certificate):
                self.clientsock.send('Invalid certificate')
                raise Exception('Invalid certificate')
                self.server_connection.close()

            # Checking if the received nonce is valid to prevent attacks

            client_pubkey = utils.read_pubkey_from_pem(self.client_certificate)


            
            if not utils.verify_signature(client_pubkey, nonce_signature, self.server_nonce + rsa_encrypted_pms):
                self.clientsock.send('Server nonce verification failed')
                raise Exception('Server nonce verification failed')
                self.server_connection.close()





        # Getting server's private key and decrypting the pms sent by the server
        # and encrypted with the server pubkey
        with open (self.serverprivatekey, 'r') as server_key:
            server_key_data=server_key.read()
        privkey = utils.read_privkey_from_pem(server_key_data)

        pre_master_secret = utils.decrypt_rsa(privkey, rsa_encrypted_pms)

        # Generating key couple
        key_1_payload = binascii.unhexlify(self.client_nonce + self.server_nonce + '00000000')
        key_2_payload = binascii.unhexlify(self.client_nonce + self.server_nonce + '11111111')
        self.key_1 = utils.create_hmac(pre_master_secret, key_1_payload)
        self.key_2 = utils.create_hmac(pre_master_secret, key_2_payload)

        
        # Check if message_checksum is legit, terminate and send back error to client
        # otherwise
        message_checksum = splitted_response[2]
        
        message_control = utils.create_hmac(
            self.key_2,
            self.clientinit + self.serverinit
            )


        if message_checksum != message_control:
            self.clientsock.send('Wrong message checksum')
            raise Exception('Wrong message checksum')
            self.clientsock.close()
            

        # Generate check for last msg and send it back
        if self.authentication == 'ClientAuth':
            _verifymessage = client_response.replace('|' + splitted_response[4], '')
        else:
            _verifymessage = client_response

        server_message_checksum = utils.create_hmac(self.key_2, _verifymessage)

        self.clientsock.send(server_message_checksum)

        self.handshake_done = True
 def verify_transaction(transaction):
     """Validates a transaction's signature and returns whether its content matches its hash"""
     return utils.verify_signature(
         transaction.get_signature_contents(**transaction.signature_kwargs),
         transaction.signature, transaction.node.public_key)
Beispiel #21
0
def update(request):
    """
    Handles update request from the master update webhook
    """
    logger = utils.CloudLogger().log_request(request)
    try:
        # 1) Validate the request
        if 'X-Lapdog-Signature' not in request.headers:
            return {
                'error': 'Missing Signature',
                'message': "The required X-Lapdog-Signature header was not provided"
            }, 400

        signature = request.headers['X-Lapdog-Signature']
        data = request.get_json()
        if not isinstance(data, dict):
            return (
                {
                    'error': "Bad Request",
                    'message': ("No data was provided" if data is None else "Expected JSON dictionary in request body")
                },
                400
            )
        result = utils.verify_signature(
            bytes.fromhex(signature),
            json.dumps(data).encode(),
            utils.UPDATE_KEY_PATH,
            _is_blob=False
        )
        if not result:
            return {
                'error': 'Bad Signature',
                'message': "The provided signature for this update was invalid"
            }, 403
        if not ('tag' in data and 'url' in data and 'random' in data and 'timestamp' in data):
            return {
                'error': 'Missing parameters',
                'message': 'Missing one or more of the required parameters "tag", "url", "timestamp", and "random"',
            }, 400

        if (datetime.datetime.utcnow().timestamp() - data['timestamp']) > 300:
            return {
                'error': 'Expired',
                'message': 'This update signature has expired'
            }, 403

        # 2) Build pipeline to boot update VM

        regions = utils.enabled_regions()
        if len(regions) < 1:
            return {
                'error': 'No regions',
                'message': 'There are no regions enabled in this project'
            }, 503

        pipeline = {
            'pipeline': {
                'actions': [
                    {
                        'imageUri': 'gcr.io/broad-cga-aarong-gtex/self_update:' + utils.UPDATE_IMAGE_TAG,
                        'commands': ['/update.sh'],
                        'environment': {
                            'LAPDOG_PROJECT': os.environ.get('GCP_PROJECT'),
                            'LAPDOG_LOG_PATH': "gs://{bucket}/update-logs/{time}-{tag}/".format(
                                bucket=utils.ld_meta_bucket_for_project(),
                                tag=data['tag'],
                                time=int(time.time())
                            ),
                            'LAPDOG_CLONE_URL': data['url'],
                            'LAPDOG_NAMESPACE': utils.getblob(
                                'gs://{bucket}/resolution'.format(
                                    bucket=utils.ld_meta_bucket_for_project(os.environ.get('GCP_PROJECT'))
                                )
                            ).download_as_string().decode(),
                            'LAPDOG_TAG': data['tag']
                        }
                    }
                ],
                'resources': {
                    'regions': regions,
                    'virtualMachine': {
                        'machineType': 'f1-micro',
                        'preemptible': False,
                        'labels': {
                            'lapdog-execution-role': 'self-update',
                        },
                        'serviceAccount': {
                            'email': 'lapdog-update@{}.iam.gserviceaccount.com'.format(os.environ.get('GCP_PROJECT')),
                            'scopes': [
                                "https://www.googleapis.com/auth/cloud-platform",
                                "https://www.googleapis.com/auth/compute",
                                "https://www.googleapis.com/auth/devstorage.read_write",
                                "https://www.googleapis.com/auth/genomics"
                            ]
                        },
                        'bootDiskSizeGb': 20,
                        'network': {
                            'network': 'default',
                            'usePrivateAddress': False
                        }
                    }
                },
            }
        }

        # 3) Launch pipeline

        papi_url = 'https://lifesciences.googleapis.com/v2beta/projects/{}/locations/{}/pipelines:run'.format(
            os.environ.get('GCP_PROJECT'),
            regions[0]
        )
        logger.log(
            "Launching PAPIv2 pipeline",
            pipeline=pipeline['pipeline'],
            url=papi_url,
            severity='NOTICE'
        )
        response = utils.generate_default_session(
            [
                "https://www.googleapis.com/auth/cloud-platform",
                "https://www.googleapis.com/auth/compute",
                "https://www.googleapis.com/auth/genomics"
            ]
        ).post(
            papi_url,
            headers={
                'Content-Type': 'application/json'
            },
            json=pipeline
        )
        try:
            if response.status_code == 200:
                return response.json()['name'], 200
            return (
                {
                    'error': 'Unable to start update',
                    'message': 'Google rejected the pipeline request (%d) : %s' % (response.status_code, response.text)
                },
                400
            )
        except:
            logger.log_exception("PAPIv2 request failed")
            return (
                {
                    'error': 'Unable to start update',
                    'message': traceback.format_exc()
                },
                500
            )
    except:
        logger.log_exception()
        return {
            'error': 'Unknown error',
            'message': traceback.format_exc()
        }, 500