Exemplo n.º 1
0
class SessionContext:

    def __init__(self, sessid):
        if not sessid:
            raise ValueError("Missing sessid")
        self.__key = [evcommon.IDSPOOL, sessid]
        self.__reg = Election().get_root_reg()

    def store_session(self, cert):
        self.__reg.ensure_key(self.__key)
        self.__reg.create_value(self.__key, "cert", cert)
        self.__reg.create_integer_value(self.__key, "start", int(time.time()))

    def check_session(self, cert):
        if not self.__reg.check(self.__key):
            return evcommon.EVOTE_ERROR, evmessage.EV_ERRORS.SEANSS_PUUDUB

        start = self.__reg.read_integer_value(self.__key, "start").value
        length = Election().get_session_length() * 60
        if start + length < int(time.time()):
            return evcommon.EVOTE_ERROR, evmessage.EV_ERRORS.SEANSS_PUUDUB

        if self.__reg.read_value(self.__key, "cert").value != cert:
            evlog.log_error('Sertifikaat muutus')
            return evcommon.EVOTE_CERT_ERROR, evmessage.EV_ERRORS.TEHNILINE_VIGA

        return evcommon.EVOTE_OK, None

    def kill(self):
        self.__reg.ensure_no_key(self.__key)
Exemplo n.º 2
0
class MobileIDContext:

    phoneno = None
    lang = None
    challenge = None
    midsess = None
    origvote = None
    votefiles = {}
    __sessid = None
    __reg = None

    def __init__(self, sessid):
        if sessid is None:
            raise Exception('Puuduv sessiooniidentifikaator')
        self.__sessid = sessid
        self.__reg = Election().get_root_reg()
        self.lang = 'EST'

    def sessid(self):
        return self.__sessid

    def kill(self):
        self.__reg.ensure_no_key([evcommon.MIDSPOOL, self.__sessid])

    def set_phone(self, phone):
        self.phoneno = phone

    def set_origvote(self, hv):
        self.origvote = hv

    def get_origvote(self):
        self.origvote = self.__reg.read_value(
            [evcommon.MIDSPOOL, self.__sessid], 'origvote').value
        return self.origvote

    def add_votefile(self, filename, data):
        self.votefiles[filename] = data

    def get_votefiles(self):
        for key in self.__reg.list_keys(
            [evcommon.MIDSPOOL, self.__sessid, 'votefiles']):
            self.votefiles[key] = self.__reg.read_value(
                [evcommon.MIDSPOOL, self.__sessid, 'votefiles'], key).value
        return self.votefiles

    def generate_challenge(self):
        self.challenge = binascii.b2a_hex(os.urandom(10))

    def verify_challenge(self, signature):
        return challenge_ok(self.certificate(), self.mychallenge(),
                            self.ourchallenge(), signature)

    def mychallenge(self):
        return self.__reg.read_value([evcommon.MIDSPOOL, self.__sessid],
                                     'mychallenge').value

    def ourchallenge(self):
        return self.__reg.read_value([evcommon.MIDSPOOL, self.__sessid],
                                     'ourchallenge').value

    def certificate(self):
        return self.__reg.read_value([evcommon.MIDSPOOL, self.__sessid],
                                     'cert').value

    def set_auth_succ(self):
        self.__reg.ensure_key([evcommon.MIDSPOOL, self.__sessid, 'authsucc'])

    def auth_succ(self):
        return self.__reg.check([evcommon.MIDSPOOL, self.__sessid, 'authsucc'])

    def check_session(self):
        if not self.__reg.check([evcommon.MIDSPOOL, self.__sessid]):
            return False
        start = self.__reg.read_integer_value(
            [evcommon.MIDSPOOL, self.__sessid], 'start').value
        length = Election().get_session_length() * 60
        return start + length >= int(time.time()) and self.auth_succ()

    def save_post_auth(self, rsp):

        self.__reg.reset_key([evcommon.MIDSPOOL, self.__sessid])
        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid], 'cert',
                                rsp._CertificateData)

        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid], 'phone',
                                self.phoneno)

        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid], 'midsess',
                                rsp._Sesscode)

        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid],
                                'mychallenge', self.challenge)

        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid],
                                'ourchallenge', rsp._Challenge)

        self.__reg.create_integer_value([evcommon.MIDSPOOL, self.__sessid],
                                        'start', int(time.time()))

    def load_pre_sign(self):
        self.phoneno = self.__reg.read_value(
            [evcommon.MIDSPOOL, self.__sessid], 'phone').value

    def save_post_sign(self, midsess):
        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid], 'midsess',
                                midsess)

        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid], 'origvote',
                                self.origvote)

        self.__reg.ensure_key([evcommon.MIDSPOOL, self.__sessid, 'votefiles'])
        for el in self.votefiles:
            self.__reg.create_value(
                [evcommon.MIDSPOOL, self.__sessid, 'votefiles'], el,
                self.votefiles[el])

    def load_pre_poll(self):
        self.midsess = int(
            self.__reg.read_value([evcommon.MIDSPOOL, self.__sessid],
                                  'midsess').value)
Exemplo n.º 3
0
class HTSVerify:

    def __init__(self):
        self._rreg = Election().get_root_reg()
        self._vote_id = None
        self._voter_code = None
        self._voter = None

    def __revoke_vote_id(self):
        _revoke_vote_id(self._voter_code)

    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 __load_bdoc(self, elid):
        voter_key = htscommon.get_user_key(self._voter_code)
        sreg = Election().get_sub_reg(elid)
        for votefile in sreg.list_keys(voter_key):
            if htscommon.VALID_VOTE_PATTERN.match(votefile):
                bdoc = bdocpythonutils.BDocContainer()
                bdoc.load(sreg.path(voter_key + [votefile]))
                bdoc.validate(bdocpythonutils.ManifestProfile("TM"))

                self._voter = htscommon.get_votefile_voter(votefile)
                break

        if not bdoc:
            evlog.log_error("No valid BDOC found for voter %s using vote ID %s" % \
                    (self._voter, self._vote_id))
            raise HTSVerifyException, evcommon.VERIFY_ERROR

        return bdoc

    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 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 voter
        ret += self._voter["nimi"] + "\t" + self._voter_code + "\n"

        # append choices list
        for quest in questions:
            ret += quest.choices_to_voter(self._voter)

        self.__decrease_count()
        return ret
Exemplo n.º 4
0
class MobileIDContext:

    phoneno = None
    lang = None
    challenge = None
    midsess = None
    origvote = None
    votefiles = {}
    __sessid = None
    __reg = None

    def __init__(self, sessid):
        if sessid is None:
            raise Exception("Puuduv sessiooniidentifikaator")
        self.__sessid = sessid
        self.__reg = Election().get_root_reg()
        self.lang = "EST"

    def sessid(self):
        return self.__sessid

    def kill(self):
        self.__reg.ensure_no_key([evcommon.MIDSPOOL, self.__sessid])

    def set_phone(self, phone):
        self.phoneno = phone

    def set_origvote(self, hv):
        self.origvote = hv

    def get_origvote(self):
        self.origvote = self.__reg.read_value([evcommon.MIDSPOOL, self.__sessid], "origvote").value
        return self.origvote

    def add_votefile(self, filename, data):
        self.votefiles[filename] = data

    def get_votefiles(self):
        for key in self.__reg.list_keys([evcommon.MIDSPOOL, self.__sessid, "votefiles"]):
            self.votefiles[key] = self.__reg.read_value([evcommon.MIDSPOOL, self.__sessid, "votefiles"], key).value
        return self.votefiles

    def generate_challenge(self):
        self.challenge = binascii.b2a_hex(os.urandom(10))

    def verify_challenge(self, signature):
        return challenge_ok(self.certificate(), self.mychallenge(), self.ourchallenge(), signature)

    def mychallenge(self):
        return self.__reg.read_value([evcommon.MIDSPOOL, self.__sessid], "mychallenge").value

    def ourchallenge(self):
        return self.__reg.read_value([evcommon.MIDSPOOL, self.__sessid], "ourchallenge").value

    def certificate(self):
        return self.__reg.read_value([evcommon.MIDSPOOL, self.__sessid], "cert").value

    def set_auth_succ(self):
        self.__reg.ensure_key([evcommon.MIDSPOOL, self.__sessid, "authsucc"])

    def auth_succ(self):
        return self.__reg.check([evcommon.MIDSPOOL, self.__sessid, "authsucc"])

    def check_session(self):
        if not self.__reg.check([evcommon.MIDSPOOL, self.__sessid]):
            return False
        start = self.__reg.read_integer_value([evcommon.MIDSPOOL, self.__sessid], "start").value
        length = Election().get_session_length() * 60
        return start + length >= int(time.time()) and self.auth_succ()

    def save_post_auth(self, rsp):

        self.__reg.reset_key([evcommon.MIDSPOOL, self.__sessid])
        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid], "cert", rsp._CertificateData)

        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid], "phone", self.phoneno)

        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid], "midsess", rsp._Sesscode)

        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid], "mychallenge", self.challenge)

        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid], "ourchallenge", rsp._Challenge)

        self.__reg.create_integer_value([evcommon.MIDSPOOL, self.__sessid], "start", int(time.time()))

    def load_pre_sign(self):
        self.phoneno = self.__reg.read_value([evcommon.MIDSPOOL, self.__sessid], "phone").value

    def save_post_sign(self, midsess):
        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid], "midsess", midsess)

        self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid], "origvote", self.origvote)

        self.__reg.ensure_key([evcommon.MIDSPOOL, self.__sessid, "votefiles"])
        for el in self.votefiles:
            self.__reg.create_value([evcommon.MIDSPOOL, self.__sessid, "votefiles"], el, self.votefiles[el])

    def load_pre_poll(self):
        self.midsess = int(self.__reg.read_value([evcommon.MIDSPOOL, self.__sessid], "midsess").value)