예제 #1
0
 def _decrypt_token(self, id_phone, ciphertext):
     """
     decrypts incoming tokens from SmartPhones
     if decryption succeeds, datetime of id_phone is updated
     alerts on invalid token, datetime not updated
     :param id_phone: skt of the token's phone
     :param ciphertext: ciphertext encrypted from beacon
     :return: None
     """
     update_execution_log(["New Token", id_phone, ciphertext])
     print("New Token from ID Phone: {0}, Ciphertext: {1}".format(
         id_phone, ciphertext))
     key = self._get_key(id_phone)
     if key is not None:
         try:
             new_datetime_string = Fernet(key).decrypt(
                 str.encode(ciphertext)).decode()
             new_datetime = dt.strptime(new_datetime_string,
                                        database_dt_format)
             database_datetime = dt.strptime(self._database[id_phone][2],
                                             database_dt_format)
             if new_datetime > database_datetime:
                 self._database[id_phone][2] = new_datetime_string
                 with open(self._database_path, 'w') as j:
                     json.dump(self._database, j, indent=0)
         except InvalidToken:
             update_execution_log(["Invalid Token", id_phone, ciphertext])
예제 #2
0
 def random_bluetooth(self, prob=0.5):
     """
     called when the phone's bluetooth is off
     :param prob: probability of phone's bluetooth turning on
     :return:
     """
     update_execution_log(["Smartphone Bluetooth Off", self._id_phone])
     self._bluetooth = False if random.rand() < prob else True
예제 #3
0
 def random_on(self, prob=0.5):
     """
     called when the phone is off
     :param prob: probability of phone turning on
     :return: None
     """
     update_execution_log(["Smartphone Off", self._id_phone])
     self._on = False if random.rand() < prob else True
예제 #4
0
 def routine(self, id_phone, id_beacon, key):
     """
     Health Authority starts a client session to communicate a new patient
     :param id_phone: skt of the new patient's phone
     :param id_beacon: identifies the beacon associated to the patient
     :param key: key for symmetric encryption
     :return: None
     """
     update_execution_log([health_authority_header, id_phone, id_beacon, key])
     self._client_session(separator.join([health_authority_header, id_phone, id_beacon, key]))
예제 #5
0
 def add_beacon(self, id_beacon, info):
     """
     stores a new id_beacon with info into AuthorityBackend database
     :param id_beacon: identifies the new beacon added
     :param info: info regarding the new patient
     :return: None
     """
     update_execution_log(["New Beacon", id_beacon, info])
     self._database[id_beacon] = info
     with open(self._database_path, 'w') as j:
         json.dump(self._database, j, indent=0)
예제 #6
0
 def _get_key(self, id_phone):
     """
     retrieves key for symmetric encryption of id_phone
     alerts on invalid id_phone
     :param id_phone: skt of the phone sending the ciphertext to AppBackend
     :return: 44bit key
     """
     if id_phone in self._database:
         return self._database[id_phone][1]
     else:
         update_execution_log(["Invalid Phone", id_phone])
예제 #7
0
 def control_routine(self, td_expire):
     """
     control routine used to check violations
     if datetime expires, AppBackend sends an alert to AuthorityBackend
     :param td_expire: time tolerance from last datetime update
     :return: None
     """
     for id_phone in self._database:
         id_beacon = self._database[id_phone][0]
         expire_dt = dt.strptime(self._database[id_phone][2],
                                 database_dt_format) + td(seconds=td_expire)
         if dt.utcnow() > expire_dt:
             update_execution_log([app_header, id_beacon])
             self._client_session(separator.join([app_header, id_beacon]))
예제 #8
0
 def _add_phone(self, id_phone, id_beacon, key):
     """
     adds a new phone to AppBackend's database
     stores the actual datetime
     database is stored on a json file in the root directory of AppBackend
     :param id_phone: skt of the phone
     :param id_beacon: identifies the associated beacon
     :param key: key for symmetric encryption
     :return: None
     """
     update_execution_log(["New Patient", id_phone, id_beacon, key])
     self._database[id_phone] = [
         id_beacon, key,
         dt.utcnow().strftime(database_dt_format)
     ]
     with open(self._database_path, 'w') as j:
         json.dump(self._database, j, indent=0)
예제 #9
0
 def routine(self, on=True, prob=0.5):
     """
     can't build up properly Bluetooth transmission
     transmissions are simulated through a header.txt file
     if beacon is on, encrypts a plaintext for the SmartPhone on the header.txt file
     if beacon is off, there's no encryption and the file is truncated
     :param on: routine changes according to beacon on/off status
     :param prob: probability of beacon turning on
     :return: None
     """
     if on:
         plaintext = str.encode(dt.utcnow().strftime(database_dt_format))
         ciphertext = Fernet(self._key).encrypt(plaintext).decode()
         update_execution_log(
             ["New Encryption", self._id_beacon, self._header, ciphertext])
         with open(self._packet, "w") as f:
             f.write(ciphertext)
     else:
         update_execution_log(["Beacon Off", self._id_beacon, self._header])
         open(self._packet, "w").close()
         self._on = False if random.rand() < prob else True
예제 #10
0
    def routine(self, wifi=True, prob=0.5):
        """
        if wifi is on, forwards the last token received
        if wifi is off, stores all incoming tokens into a log file
        if wifi turns on, last stored token is sent to AppBackend
        :param wifi: routine changes according to phone's wifi on/off status
        :param prob: probability of phone's wifi turning on
        :return: None
        """
        last_ciphertext = None
        for packet in [packet for packet in os.listdir(self._packets_root) if packet.startswith(self._header)]:
            if os.path.getsize(os.path.join(self._packets_root, packet)) > 0:
                with open(os.path.join(self._packets_root, packet), "r") as f:
                    ciphertext = f.read()
                    if wifi:
                        update_execution_log([smartphone_header, self._id_phone, ciphertext])
                        self._client_session(separator.join([smartphone_header, self._id_phone, ciphertext]))
                    else:
                        last_ciphertext = ciphertext
                        with open(self._log_path, "w") as j:
                            self._log[dt.utcnow().strftime(database_dt_format)] = last_ciphertext
                            json.dump(self._log, j, indent=0)

        if not wifi:
            update_execution_log(["Smartphone WiFi Off", self._id_phone])
            self._wifi = False if random.rand() < prob else True
            if self._wifi and last_ciphertext is not None:
                update_execution_log([smartphone_header, self._id_phone, last_ciphertext])
                self._client_session(separator.join([smartphone_header, self._id_phone, last_ciphertext]))
예제 #11
0
 def _add_datetime(self, id_beacon):
     """
     adds to log the datetime of id_beacon's violation
     :param id_beacon: identifies the beacon involved in the violation
     :return: None
     """
     update_execution_log(
         ["Quarantine Violation", id_beacon, self._database[id_beacon]])
     print("Quarantine Violation from ID Beacon: {0}, Info: {1}".format(
         id_beacon, self._database[id_beacon]))
     if id_beacon in self._database:
         if id_beacon not in self._log:
             self._log[id_beacon] = [
                 dt.utcnow().strftime(database_dt_format)
             ]
         else:
             self._log[id_beacon].append(
                 dt.utcnow().strftime(database_dt_format))
         with open(self._log_path, 'w') as j:
             json.dump(self._log, j, indent=0)
     else:
         update_execution_log(["Invalid Beacon", id_beacon])