Example #1
0
    def do_start(self, config):
        '''
        this is called by the protocol when we receive a command from the TS
        to start a new collection phase
        return None if failure, otherwise the protocol will encode the result
        in json and send it back to TS
        '''
        logging.info("got command to start new collection phase")
        # keep the start config to send to the TS at the end of the collection
        # deepcopy so we can delete the (encrypted) secrets from the shares
        self.start_config = deepcopy(config)
        # discard the secrets
        # we haven't checked if any shares are present, so don't assume
        for share in self.start_config.get('shares', []):
            # this is still encrypted, so there's no need for a secure delete
            del share['secret']
            share['secret'] = "(encrypted blinding share, deleted by share keeper)"
        # sort the shares, so that their order is consistent between rounds
        self.start_config.get('shares', []).sort()

        if ('shares' not in config):
            logging.warning("start command from tally server cannot be completed due to missing shares")
            return None

        combined_counters = self.check_start_config(config)

        if combined_counters is None:
            return None
        else:
            config['counters'] = combined_counters

        self.keystore = SecureCounters(config['counters'], counter_modulus())
        share_list = config['shares']

        private_key = load_private_key_file(self.config['key'])
        for share in share_list:
            encrypted_secret = share['secret']
            secret = decrypt(private_key, encrypted_secret)
            # TODO: secure delete
            share['secret'] = secret
            blinding_result = self.keystore.import_blinding_share(share)
            if not blinding_result:
                # the structure of the imported share did not match the
                # configured counters
                # this is likely a configuration error or a programming bug,
                # but there is also no way to detect the TS modifying the data
                logging.warning("failed to import blinding share {} config {}"
                                .format(share, config))
                # TODO: secure delete
                del private_key
                return None

        logging.info("successfully started and imported {} blinding shares for {} counters ({} bins)"
                     .format(len(share_list), len(config['counters']), count_bins(config['counters'])))
        # TODO: secure delete
        del private_key
        return {}
Example #2
0
def check_encdec(pub_key, priv_key, data_structure):
    """
    Check that data_structure survives encryption and descryption intact
    """
    logging.debug("Encrypting data structure:")
    ciphertext = encrypt(pub_key, data_structure)
    logging.debug("Decrypting data structure:")
    result_structure = decrypt(priv_key, ciphertext)
    check_equality(data_structure, result_structure)
    logging.debug("Decrypted data was identical to the original data!")