function handleTallyReq($voterReq) { switch ($voterReq['cmd']) { // TODO throw an error if cmd is not set case 'getWinners': $winners = array(); foreach ($this->elConfig['questions'] as $question) { $completeElectionId = makeCompleteElectionId($this->elConfig['electionId'], $question['questionID']); $pseudoVoterReq = array('electionId' => $completeElectionId); $allvotesTmp = parent::getAllVotesEvent($pseudoVoterReq); $allVotes = $allvotesTmp['data']['allVotes']; $winners[$question['questionID']] = $this->GetResultMain($allVotes, $question['tallyData'], $question['options']); } $result = array('cmd' => 'showWinners', 'data' => $winners); return $result; break; case 'getStatistic': // get the array of questions from the requested questionId or return all questions if (isset($voterReq['questionID'])) { // return the result statistics for the requested question only if (is_array($voterReq['questionID'])) { $questionIds = $voterReq['questionID']; } else { $questionIds[] = $voterReq['questionID']; } // just a single question requested foreach ($questionIds as $questionId) { if (!(is_int($questionId) || is_string($questionId))) { WrongRequestException::throwException(85657, 'The questionID must be an int, a string or an array of integers resp. strings', print_r($voterReq, true)); } $key = find_in_subarray($this->elConfig['questions'], 'questionID', $questionId); if ($key === false) { WrongRequestException::throwException(85658, 'The questionID you requested does not exist', print_r($questionId, true)); } $questions[] = $this->elConfig['questions'][$key]; } } else { $questions = $this->elConfig['questions']; } // return the result statistics for all questions // generate statistics $resultStat = array(); foreach ($questions as $question) { $completeElectionId = makeCompleteElectionId($this->elConfig['electionId'], $question['questionID']); $pseudoVoterReq = array('electionId' => $completeElectionId); $allvotesTmp = parent::getAllVotesEvent($pseudoVoterReq); $allVotes = $allvotesTmp['data']['allVotes']; $allOptionIDs = $this->getAllOptionIDs($question['options']); $resultStat[$question['questionID']] = $this->GetResultStat($allVotes, $allOptionIDs, $question['tallyData']['scheme']); } $result = array('cmd' => 'showStatistic', 'data' => $resultStat); return $result; break; default: return parent::handleTallyReq($voterReq); break; } }
function verifyBallots($voterReq, $blindedHashesFromDB) { // $voterReq: .ballots[] .electionId .VoteId //.blindedHash[] .serversAlreadySigned[] //contains an array saying the x-th server has to sign y ballots // verify if user is allowed to vote and status of communication (done: pickBallots, next: signBallots) is correct // verify content of the ballot // verify if the correct number of ballots was sent: if (count($voterReq["ballots"]) != $this->numVerifyBallots) { WrongRequestException::throwException('not the correct number of ballots sent'); } $tmpret = array(); if ($voterReq['electionId'] != $this->electionId) { WrongRequestException::throwException(210, 'Error: electionID is wrong', "expected electionID: {$this->electionId}, received electionID in ballot {$i}: " . $voterReq['ballots'][$i]['electionId']); } if (!isset($voterReq['questions']) || !is_array($voterReq['questions'])) { WrongRequestException::throwException(223, "Error: questions must be set and an array", print_r($voterReq, true)); } for ($q = 0; $q < count($voterReq['questions']); $q++) { if (!isset($voterReq["questions"][$q]['questionID']) || !(is_int($voterReq["questions"][$q]['questionID']) || is_string($voterReq["questions"][$q]['questionID']))) { WrongRequestException::throwException(227, 'Error: verifyBallots(): missing questionID or it is not of type int', $q); } $qno = find_in_subarray($voterReq["questions"], 'questionID', $blindedHashesFromDB['blindedHashes']['questions'][$q]['questionID']); if ($qno === false) { WrongRequestException::throwException(237, 'Error: All questions must be disclosed', 'Number in question array for which no questionID was found in voterrequest: ' . $q); } if (!isset($voterReq['questions'][$q]['ballots']) || !is_array($voterReq['questions'][$q]['ballots'])) { WrongRequestException::throwException(224, "/questions[].['ballots']/ must be set and of type array", print_r($voterReq, true)); } foreach ($blindedHashesFromDB['requestedBallots']['questions'][$q]['picked'] as $p) { $i = find_in_subarray($voterReq['questions'][$q]['ballots'], 'ballotno', $p); if ($i === false) { WrongRequestException::throwException(211, "A picked Ballot was not sent", "verifyBallots: not sent ballot: {$p}"); } $curVoterBallot = $voterReq["questions"][$qno]["ballots"][$i]; if (!isset($curVoterBallot['unblindf']) || !is_string($curVoterBallot['unblindf'])) { WrongRequestException::throwException(225, 'Error: /unblindf/ must be set and of type /string/', print_r($curVoterBallot, true)); } // verify if the sent ballot was requested // $kw = array_search($curVoterBallot['ballotno'], $blindedHashesFromDB['requestedBallots']['questions'][$q]['picked']); // if ($kw === false) WrongRequestException::throwException(211, "A Ballot was sent for verification purpose that was not requested", "verifyBallots: not requested ballot: " . $voterReq['ballots'][$i]['ballotno'] . "requested ballots: " . print_r($blindedHashesFromDB['requestedBallots'], true)); // $requestedballots['sent'][$kw] = true; // } // verify hash $str = $this->ballot2strForSig($curVoterBallot, makeCompleteElectionId($this->electionId, $blindedHashesFromDB['blindedHashes']['questions'][$q]['questionID'])); $blindedHashFromDatabase = $blindedHashesFromDB['blindedHashes']['questions'][$q]['ballots'][$curVoterBallot['ballotno']]['blindedHash']; $unblindf = $curVoterBallot['unblindf']; $hashOk = $this->crypt->verifyBlindedHash($str, $unblindf, $blindedHashFromDatabase); if (!($hashOk === true)) { WrongRequestException::throwException(212, "Error: hash wrong", "hash from signature: " . $verifyHash->toHex() . "calculated hash: {$hashByMe}"); } // verify sigs from previous servers .ballots.sigs: .sig(encryptet previous sig or hash if first sig) .sigBy (name of the signing server in order to identify the correct public key) $sigsOk = false; if (isset($curVoterBallot['sigs'])) { $sigsOk = $this->crypt->verifySigs($str, $curVoterBallot['sigs']); } else { $sigsOk = true; } // no sigs there $tmpret[$i] = $hashOk === true && $sigsOk === true; if ($i == 0) { $ret = $tmpret[$i] === true; } else { $ret = $ret === true && $tmpret[$i] === true; } // TODO verify if votingId is unique // load $allvotingno from database // if (array_search($raw['votingno'], $allvotingno) == false) {$e = WrongRequestException::throwException... error("Voting number allocated"); return $e;} // } // verify if all requested ballots were sent /* for ($i=0; $i<count($requestedballots["num"]); $i++) { if (! $requestedballots['sent']) { $e = throwExeption...("Not all requested ballots were sent for verification. Ballots $requestedballots[num][$i] is missing."); } } */ // array($tmpret, $hashByMe, $unblindethashFromDatabaseStr); if ($q == 0) { $retQ = $ret; } else { $retQ = $retQ === true && $ret === true; } } return $retQ; }