def verify_id(self, vote_id): # check if valid vote ID if not formatutil.is_vote_verification_id(vote_id): # We don't know how large vote_id is, so don't write to disk evlog.log_error("Malformed vote ID") raise HTSVerifyException, evcommon.VERIFY_ERROR vote_id = vote_id.lower() otp_key = htscommon.get_verification_key(vote_id) # check if corresponding OTP exists if not self._rreg.check(otp_key): evlog.log_error("No such vote ID: %s" % vote_id) raise HTSVerifyException, evcommon.VERIFY_ERROR self._voter_code = self._rreg.read_string_value(\ otp_key, "voter").value.rstrip() # check if timestamp is OK current = int(time.time()) created = self._rreg.read_integer_value(otp_key, "timestamp").value timeout = Election().get_verification_time() * 60 if created + timeout < current: evlog.log("Vote ID %s has expired" % vote_id) self.__revoke_vote_id() raise HTSVerifyException, evcommon.VERIFY_ERROR # check if count is OK count = self._rreg.read_integer_value(otp_key, "count").value if count <= 0: evlog.log_error("Vote ID %s count is zero, but had not been revoked") self.__revoke_vote_id() raise HTSVerifyException, evcommon.VERIFY_ERROR self._vote_id = vote_id
def __decrease_count(self): otp_key = htscommon.get_verification_key(self._vote_id) count = self._rreg.read_integer_value(otp_key, "count").value - 1 if count > 0: self._rreg.create_integer_value(otp_key, "count", count) else: self.__revoke_vote_id()
def init_hts(self): import htscommon election.Election().get_root_reg().ensure_key(\ htscommon.get_verification_key()) self.__quest.create_keys(G_HTS_KEYS) self.__quest.create_revlog()
def __create_vote_key(self): reg = Election().get_root_reg() while True: vote_id = _generate_vote_id() key = htscommon.get_verification_key(vote_id) if not reg.check(key): reg.create_key(key) return vote_id
def purge_otps(): runtime = int(time.time()) AppLog().set_app("purgeotps.py") AppLog().log("Purging expired vote ID's as of %s: START" % \ time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(runtime))) try: reg = election.Election().get_root_reg() timeout = election.Election().get_verification_time() * 60 for otp in reg.list_keys(htscommon.get_verification_key()): otp_key = htscommon.get_verification_key(otp) created = reg.read_integer_value(otp_key, "timestamp").value if created + timeout < runtime: AppLog().log("Purging expired vote ID %s" % otp) purge_otp(otp_key) except: AppLog().log_exception() finally: AppLog().log("Purging expired vote ID's: DONE")
def purge_otp(reg, otp): otp_key = htscommon.get_verification_key(otp) voter = reg.read_string_value(otp_key, "voter").value.rstrip() voter_key = htscommon.get_user_key(voter) elids = reg.read_string_value(otp_key, "elids").value.rstrip().split("\t") for elid in elids: sreg = Election().get_sub_reg(elid) if sreg.check(voter_key + [htscommon.VOTE_VERIFICATION_ID_FILENAME]): sreg.delete_value(voter_key, htscommon.VOTE_VERIFICATION_ID_FILENAME) reg.ensure_no_key(otp_key)
def purge_otps(): # Read the verification timeout value before defining check_otp, so we only # have to read it once. timeout = Election().get_verification_time() * 60 def check_otp(reg, otp, runtime): otp_key = htscommon.get_verification_key(otp) created = reg.read_integer_value(otp_key, "timestamp").value return created + timeout < runtime purger = purge.Purger("expired vote ID", htscommon.get_verification_key()) purger.work(check_otp, purge_otp)
def get_response(self): import binascii # load a random BDOC from the ones available otp_key = htscommon.get_verification_key(self._vote_id) elids = self._rreg.read_string_value(otp_key, "elids")\ .value.rstrip().split("\t") bdoc = self.__load_bdoc(random.choice(elids)) evlog.log("Sending BDOC %s with vote ID %s for verification" %\ (ksum.votehash(bdoc.get_bytes()), self._vote_id)) # check consistency bdoc_set = set([doc.split(".")[0] for doc in bdoc.documents]) elids_set = set(elids) if bdoc_set != elids_set: evlog.log_error("Votes in BDOC for vote ID %s are inconsistent " \ "with registry: %s, %s" % (self._vote_id, bdoc_set, elids_set)) raise HTSVerifyException, evcommon.VERIFY_ERROR # create question objects questions = [] for elid in elids: questions.append(question.Question(\ elid, "hts", Election().get_sub_reg(elid))) # start assembling the response ret = "" # append questions for quest in questions: ret += quest.qname() + ":" + str(quest.get_type()) + "\t" ret += "\n" # append election IDs and votes for votefile in bdoc.documents: elid = votefile.split(".")[0] ret += elid + "\t" + binascii.b2a_hex( bdoc.documents[votefile]) + "\n" ret += "\n" # append choices list for quest in questions: tv = quest.get_voter(self._voter_code) if tv: ret += quest.choices_to_voter(tv) else: evlog.log_error("Voter not found") self.__decrease_count() return ret
def get_response(self): import binascii # load a random BDOC from the ones available otp_key = htscommon.get_verification_key(self._vote_id) elids = self._rreg.read_string_value(otp_key, "elids")\ .value.rstrip().split("\t") bdoc = self.__load_bdoc(random.choice(elids)) evlog.log("Sending BDOC %s with vote ID %s for verification" %\ (ksum.votehash(bdoc.get_bytes()), self._vote_id)) # check consistency bdoc_set = set([doc.split(".")[0] for doc in bdoc.documents]) elids_set = set(elids) if bdoc_set != elids_set: evlog.log_error("Votes in BDOC for vote ID %s are inconsistent " \ "with registry: %s, %s" % (self._vote_id, bdoc_set, elids_set)) raise HTSVerifyException, evcommon.VERIFY_ERROR # create question objects questions = [] for elid in elids: questions.append(question.Question(\ elid, "hts", Election().get_sub_reg(elid))) # start assembling the response ret = "" # append questions for quest in questions: ret += quest.qname() + ":" + str(quest.get_type()) + "\t" ret += "\n" # append election IDs and votes for votefile in bdoc.documents: elid = votefile.split(".")[0] ret += elid + "\t" + binascii.b2a_hex(bdoc.documents[votefile]) + "\n" ret += "\n" # append choices list for quest in questions: tv = quest.get_voter(self._voter_code) if tv: ret += quest.choices_to_voter(tv) else: evlog.log_error("Voter not found") self.__decrease_count() return ret
def issue_vote_id(self): vote_id = self.__create_vote_key() rreg = Election().get_root_reg() key = htscommon.get_verification_key(vote_id) rreg.create_string_value(key, "voter", self.signercode) rreg.create_integer_value(key, "timestamp", int(time.time())) rreg.create_integer_value(key, "count", \ Election().get_verification_count()) # Store the election IDs and include a backreference in the # corresponding questions' subregistries. elids = "" for elid in [quest[0] for quest in self.questions]: elids += elid + "\t" sreg = Election().get_sub_reg(elid) skey = htscommon.get_user_key(self.signercode) sreg.ensure_key(skey) sreg.create_string_value(skey, \ htscommon.VOTE_VERIFICATION_ID_FILENAME, vote_id) rreg.create_string_value(key, "elids", elids) return vote_id
def _delete_vote_id(vote_id): return Election().get_root_reg().ensure_no_key(\ htscommon.get_verification_key(vote_id))
def check_otp(reg, otp, runtime): otp_key = htscommon.get_verification_key(otp) created = reg.read_integer_value(otp_key, "timestamp").value return created + timeout < runtime