def voter_id_hash(self): if self.voter_login_id: # for backwards compatibility with v3.0, and since it doesn't matter # too much if we hash the email or the unique login ID here. value_to_hash = self.voter_login_id else: value_to_hash = self.voter_id try: return utils.hash_b64(value_to_hash) except: try: return utils.hash_b64(value_to_hash.encode('latin-1')) except: return utils.hash_b64(value_to_hash.encode('utf-8'))
def generate_voters_hash(self): """ look up the list of voters, make a big file, and hash it FIXME: for more than 1000 voters, need to loop multiple times """ if self.openreg: self.voters_hash = None else: voters = Voter.get_by_election(self) voters_json = utils.to_json([v.toJSONDict() for v in voters]) self.voters_hash = utils.hash_b64(voters_json)
def generate_voters_hash(self): """ look up the list of voters, make a big file, and hash it """ # FIXME: for now we don't generate this voters hash: return if self.openreg: self.voters_hash = None else: voters = Voter.get_by_election(self) voters_json = utils.to_json([v.toJSONDict() for v in voters]) self.voters_hash = utils.hash_b64(voters_json)
def set_public_key_from_json(self, public_key_json): """ get the public key and the hash, and add it Args: public_key_json: String, json dump Returns: """ public_key_and_proof = utils.from_json(public_key_json) self.public_key = algs.EGPublicKey.fromJSONDict(public_key_and_proof['public_key']) self.pok = algs.DLogProof.fromJSONDict(public_key_and_proof['pok']) # verify the pok if not self.public_key.verify_sk_proof(self.pok, algs.DLog_challenge_generator): raise Exception("bad pok for this public key") self.public_key_hash = utils.hash_b64(utils.to_json(self.public_key.toJSONDict()))
def generate_trustee(self, params): """ generate a trustee including the secret key, thus a helios-based trustee """ # FIXME: generate the keypair keypair = params.generate_keypair() # create the trustee trustee = Trustee(election=self) trustee.uuid = str(uuid.uuid4()) trustee.name = settings.DEFAULT_FROM_NAME trustee.email = settings.DEFAULT_FROM_EMAIL trustee.public_key = keypair.pk trustee.secret_key = keypair.sk # FIXME: compute it trustee.public_key_hash = utils.hash_b64(utils.to_json(trustee.public_key.toJSONDict())) trustee.pok = trustee.secret_key.prove_sk(algs.DLog_challenge_generator) trustee.save()
def generate_helios_trustee(self, params): """ generate a trustee including the secret key, thus a helios-based trustee """ # FIXME: generate the keypair keypair = params.generate_keypair() # create the trustee trustee = HeliosTrustee() trustee.election = self trustee.public_key = keypair.pk trustee.secret_key = keypair.sk trustee.secret = heliosutils.random_string(12) trustee.public_key_hash = utils.hash_b64(utils.to_json(EGPublicKey(y=trustee.public_key.p, p=trustee.public_key.p, q=trustee.public_key.p, g=trustee.public_key.p).toJSONDict())) trustee.pok = trustee.secret_key.prove_sk(algs.DLog_challenge_generator) return trustee
def encrypted_tally_hash(self): if not self.encrypted_tally: return None return utils.hash_b64(self.encrypted_tally.toJSON())
def one_election_cast_confirm(request, election): user = get_user(request) # if no encrypted vote, the user is reloading this page or otherwise getting here in a bad way if not request.session.has_key('encrypted_vote'): return HttpResponseRedirect(settings.URL_HOST) voter = get_voter(request, user, election) # auto-register this person if the election is openreg if user and not voter and election.openreg: voter = _register_voter(election, user) # tallied election, no vote casting if election.tallied or election.result: return render_template(request, 'election_tallied', {'election': election}) encrypted_vote = request.session['encrypted_vote'] vote_fingerprint = cryptoutils.hash_b64(encrypted_vote) # if this user is a voter, prepare some stuff if voter: vote = datatypes.LDObject.fromDict(utils.from_json(encrypted_vote), type_hint='phoebus/EncryptedVote').wrapped_obj # prepare the vote to cast cast_vote_params = { 'vote' : vote, 'voter' : voter, 'vote_hash': vote_fingerprint, 'cast_at': datetime.datetime.utcnow() } cast_vote = CastVote(**cast_vote_params) else: cast_vote = None if request.method == "GET": if voter: past_votes = CastVote.get_by_voter(voter) if len(past_votes) == 0: past_votes = None else: past_votes = None if cast_vote: # check for issues issues = cast_vote.issues(election) else: issues = None bad_voter_login = (request.GET.get('bad_voter_login', "0") == "1") # status update this vote if voter and voter.user.can_update_status(): status_update_label = voter.user.update_status_template() % "your smart ballot tracker" status_update_message = "I voted in %s - my smart tracker is %s.. #heliosvoting" % (get_election_url(election),cast_vote.vote_hash[:10]) else: status_update_label = None status_update_message = None # do we need to constrain the auth_systems? if election.eligibility: auth_systems = [e['auth_system'] for e in election.eligibility] else: auth_systems = None password_only = False if auth_systems == None or 'password' in auth_systems: show_password = True password_login_form = forms.VoterPasswordForm() if auth_systems == ['password']: password_only = True else: show_password = False password_login_form = None return_url = reverse(one_election_cast_confirm, args=[election.uuid]) login_box = auth_views.login_box_raw(request, return_url=return_url, auth_systems = auth_systems) return render_template(request, 'election_cast_confirm', { 'login_box': login_box, 'election' : election, 'vote_fingerprint': vote_fingerprint, 'past_votes': past_votes, 'issues': issues, 'voter' : voter, 'return_url': return_url, 'status_update_label': status_update_label, 'status_update_message': status_update_message, 'show_password': show_password, 'password_only': password_only, 'password_login_form': password_login_form, 'bad_voter_login': bad_voter_login}) if request.method == "POST": check_csrf(request) # voting has not started or has ended if (not election.voting_has_started()) or election.voting_has_stopped(): return HttpResponseRedirect(settings.URL_HOST) # if user is not logged in # bring back to the confirmation page to let him know if not voter: return HttpResponseRedirect(reverse(one_election_cast_confirm, args=[election.uuid])) # don't store the vote in the voter's data structure until verification cast_vote.save() # status update? if request.POST.get('status_update', False): status_update_message = request.POST.get('status_update_message') else: status_update_message = None # launch the verification task tasks.cast_vote_verify_and_store.delay( cast_vote_id = cast_vote.id, status_update_message = status_update_message) # remove the vote from the store del request.session['encrypted_vote'] return HttpResponseRedirect("%s%s" % (settings.URL_HOST, reverse(one_election_cast_done, args=[election.uuid])))
def voter_id_hash(self): return utils.hash_b64(self.uid)
def get_hash(self): return utils.hash_b64(utils.to_json(self.toJSONDict()))
def one_election_cast_confirm(request, election): user = get_user(request) # if no encrypted vote, the user is reloading this page or otherwise getting here in a bad way if not request.session.has_key('encrypted_vote'): return HttpResponseRedirect("/") if user: voter = Voter.get_by_election_and_user(election, user) else: voter = None # auto-register this person if the election is openreg if user and not voter and election.openreg: voter = _register_voter(election, user) # tallied election, no vote casting if election.encrypted_tally or election.result: return render_template(request, 'election_tallied', {'election': election}) encrypted_vote = request.session['encrypted_vote'] vote_fingerprint = cryptoutils.hash_b64(encrypted_vote) # if this user is a voter, prepare some stuff if voter: # prepare the vote to cast cast_vote_params = { 'vote' : electionalgs.EncryptedVote.fromJSONDict(utils.from_json(encrypted_vote)), 'voter' : voter, 'vote_hash': vote_fingerprint, 'cast_at': datetime.datetime.utcnow(), 'election': election } cast_vote = CastVote(**cast_vote_params) else: cast_vote = None if request.method == "GET": if voter: past_votes = CastVote.get_by_election_and_voter(election, voter) if len(past_votes) == 0: past_votes = None else: past_votes = None if cast_vote: # check for issues issues = cast_vote.issues(election) else: issues = None return_url = reverse(one_election_cast_confirm, args=[election.uuid]) login_box = auth_views.login_box_raw(request, return_url=return_url) return render_template(request, 'election_cast_confirm', {'login_box': login_box, 'election' : election, 'vote_fingerprint': vote_fingerprint, 'past_votes': past_votes, 'issues': issues, 'voter' : voter}) if request.method == "POST": check_csrf(request) # voting has not started or has ended if (not election.voting_has_started()) or election.voting_has_stopped(): return HttpResponseRedirect("/") # if user is not logged in # bring back to the confirmation page to let him know if not user or not voter: return HttpResponseRedirect(reverse(one_election_cast_confirm, args=[election.uuid])) # verify the vote if cast_vote.vote.verify(election): # store it voter.store_vote(cast_vote) else: return HttpResponse("vote does not verify: \n\n" + utils.to_json(cast_vote.vote.toJSONDict())) # remove the vote from the store del request.session['encrypted_vote'] import logging logging.error("about to send signal!!") # send the signal signals.vote_cast.send(sender=election, election=election, user=user, voter=voter, cast_vote=cast_vote) return HttpResponseRedirect(reverse(one_election_cast_done, args=[election.uuid]))
def one_election_cast_confirm(request, election): user = get_user(request) # if no encrypted vote, the user is reloading this page or otherwise getting here in a bad way if (not request.session.has_key('encrypted_vote')) or request.session['encrypted_vote'] == None: return HttpResponseRedirect(settings.URL_HOST) # election not frozen or started if not election.voting_has_started(): return render_template(request, 'election_not_started', {'election': election}) voter = get_voter(request, user, election) # auto-register this person if the election is openreg if user and not voter and election.openreg: voter = _register_voter(election, user) # tallied election, no vote casting if election.encrypted_tally or election.result: return render_template(request, 'election_tallied', {'election': election}) encrypted_vote = request.session['encrypted_vote'] vote_fingerprint = cryptoutils.hash_b64(encrypted_vote) # if this user is a voter, prepare some stuff if voter: vote = datatypes.LDObject.fromDict(utils.from_json(encrypted_vote), type_hint='legacy/EncryptedVote').wrapped_obj if 'HTTP_X_FORWARDED_FOR' in request.META: # HTTP_X_FORWARDED_FOR sometimes have a comma delimited list of IP addresses # Here we want the originating IP address # See http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/x-forwarded-headers.html # and https://en.wikipedia.org/wiki/X-Forwarded-For cast_ip = request.META.get('HTTP_X_FORWARDED_FOR').split(',')[0].strip() or None else: cast_ip = request.META.get('REMOTE_ADDR', None) # prepare the vote to cast cast_vote_params = { 'vote' : vote, 'voter' : voter, 'vote_hash': vote_fingerprint, 'cast_at': datetime.datetime.utcnow(), 'cast_ip': cast_ip } cast_vote = CastVote(**cast_vote_params) else: cast_vote = None if request.method == "GET": if voter: past_votes = CastVote.get_by_voter(voter) if len(past_votes) == 0: past_votes = None else: past_votes = None if cast_vote: # check for issues issues = cast_vote.issues(election) else: issues = None bad_voter_login = (request.GET.get('bad_voter_login', "0") == "1") # status update this vote if voter and voter.user.can_update_status(): status_update_label = voter.user.update_status_template() % "your smart ballot tracker" status_update_message = "I voted in %s - my smart tracker is %s.. #heliosvoting" % (get_election_url(election),cast_vote.vote_hash[:10]) else: status_update_label = None status_update_message = None # do we need to constrain the auth_systems? if election.eligibility: auth_systems = [e['auth_system'] for e in election.eligibility] else: auth_systems = None password_only = False if auth_systems == None or 'password' in auth_systems: show_password = True password_login_form = forms.VoterPasswordForm() if auth_systems == ['password']: password_only = True else: show_password = False password_login_form = None return_url = reverse(one_election_cast_confirm, args=[election.uuid]) login_box = auth_views.login_box_raw(request, return_url=return_url, auth_systems = auth_systems) return render_template(request, 'election_cast_confirm', { 'login_box': login_box, 'election' : election, 'vote_fingerprint': vote_fingerprint, 'past_votes': past_votes, 'issues': issues, 'voter' : voter, 'return_url': return_url, 'status_update_label': status_update_label, 'status_update_message': status_update_message, 'show_password': show_password, 'password_only': password_only, 'password_login_form': password_login_form, 'bad_voter_login': bad_voter_login}) if request.method == "POST": check_csrf(request) # voting has not started or has ended if (not election.voting_has_started()) or election.voting_has_stopped(): return HttpResponseRedirect(settings.URL_HOST) # if user is not logged in # bring back to the confirmation page to let him know if not voter: return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_cast_confirm, args=[election.uuid])) # don't store the vote in the voter's data structure until verification cast_vote.save() # status update? if request.POST.get('status_update', False): status_update_message = request.POST.get('status_update_message') else: status_update_message = None # launch the verification task tasks.cast_vote_verify_and_store.delay( cast_vote_id = cast_vote.id, status_update_message = status_update_message) # remove the vote from the store del request.session['encrypted_vote'] return HttpResponseRedirect("%s%s" % (settings.URL_HOST, reverse(one_election_cast_done, args=[election.uuid])))
def one_election_cast_confirm(request, election): user = get_user(request) # if no encrypted vote, the user is reloading this page or otherwise getting here in a bad way if not request.session.has_key('encrypted_vote'): return HttpResponseRedirect(settings.URL_HOST) # election not frozen or started if not election.voting_has_started(): return render_template(request, 'election_not_started', {'election': election}) voter = get_voter(request, user, election) # auto-register this person if the election is openreg if user and not voter and election.openreg: voter = _register_voter(election, user) # tallied election, no vote casting if election.encrypted_tally or election.result: return render_template(request, 'election_tallied', {'election': election}) encrypted_vote = request.session['encrypted_vote'] vote_fingerprint = cryptoutils.hash_b64(encrypted_vote) # if this user is a voter, prepare some stuff if voter: vote = datatypes.LDObject.fromDict(utils.from_json(encrypted_vote), type_hint='legacy/EncryptedVote').wrapped_obj # prepare the vote to cast cast_vote_params = { 'vote' : vote, 'voter' : voter, 'vote_hash': vote_fingerprint, 'cast_at': datetime.datetime.utcnow() } cast_vote = CastVote(**cast_vote_params) else: cast_vote = None if request.method == "GET": if voter: past_votes = CastVote.get_by_voter(voter) if len(past_votes) == 0: past_votes = None else: past_votes = None if cast_vote: # check for issues issues = cast_vote.issues(election) else: issues = None bad_voter_login = (request.GET.get('bad_voter_login', "0") == "1") # status update this vote if voter and voter.user.can_update_status(): status_update_label = voter.user.update_status_template() % "your smart ballot tracker" status_update_message = "I voted in %s - my smart tracker is %s.. #heliosvoting" % (get_election_url(election),cast_vote.vote_hash[:10]) else: status_update_label = None status_update_message = None # do we need to constrain the auth_systems? if election.eligibility: auth_systems = [e['auth_system'] for e in election.eligibility] else: auth_systems = None password_only = False if auth_systems == None or 'password' in auth_systems: show_password = True password_login_form = forms.VoterPasswordForm() if auth_systems == ['password']: password_only = True else: show_password = False password_login_form = None return_url = reverse(one_election_cast_confirm, args=[election.uuid]) login_box = auth_views.login_box_raw(request, return_url=return_url, auth_systems = auth_systems) return render_template(request, 'election_cast_confirm', { 'login_box': login_box, 'election' : election, 'vote_fingerprint': vote_fingerprint, 'past_votes': past_votes, 'issues': issues, 'voter' : voter, 'return_url': return_url, 'status_update_label': status_update_label, 'status_update_message': status_update_message, 'show_password': show_password, 'password_only': password_only, 'password_login_form': password_login_form, 'bad_voter_login': bad_voter_login}) if request.method == "POST": check_csrf(request) # voting has not started or has ended if (not election.voting_has_started()) or election.voting_has_stopped(): return HttpResponseRedirect(settings.URL_HOST) # if user is not logged in # bring back to the confirmation page to let him know if not voter: return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_cast_confirm, args=[election.uuid])) # don't store the vote in the voter's data structure until verification cast_vote.save() # status update? if request.POST.get('status_update', False): status_update_message = request.POST.get('status_update_message') else: status_update_message = None # launch the verification task tasks.cast_vote_verify_and_store.delay( cast_vote_id = cast_vote.id, status_update_message = status_update_message) # remove the vote from the store del request.session['encrypted_vote'] return HttpResponseRedirect("%s%s" % (settings.URL_HOST, reverse(one_election_cast_done, args=[election.uuid])))