From 2bdf92b075772492376e74436602503831d495c9 Mon Sep 17 00:00:00 2001 From: Hai Brenner Date: Mon, 20 Jun 2016 15:26:53 +0300 Subject: [PATCH] Fixed some stuff according to Arbel's suggestions. Specifically: 1. now handling exceptions in the encryption process (according to voter's choice) 2. handling files in storage manager (now reading election parameters and system messages from files) 3. Controller's init() now already sets all the info and parameters. No need to call extra functions 4. some more changes to the method structure --- .../src/main/proto/meerkat/voting.proto | 17 +- .../voting/controller/SystemMessages.java | 7 - .../controller/VotingBoothController.java | 21 +-- .../voting/controller/VotingBoothImpl.java | 166 +++++++++++------- .../callbacks/CastOrAuditCallback.java | 12 +- .../callbacks/ChannelChoiceCallback.java | 8 +- .../callbacks/EncryptionFailedCallback.java | 43 +++++ .../callbacks/OutputDeviceCommitCallback.java | 9 +- .../OutputDeviceFinalizeCallback.java | 9 +- .../controller/callbacks/VotingCallback.java | 8 +- .../callbacks/WaitForFinishCallback.java | 10 +- .../EncryptAndCommitBallotCommand.java | 8 +- .../RetryEncryptAndCommitBallotCommand.java | 10 ++ .../voting/encryptor/VBCryptoManager.java | 1 + .../voting/encryptor/VBCryptoManagerImpl.java | 2 + .../voting/storage/StorageManager.java | 17 ++ .../voting/storage/StorageManagerMockup.java | 25 ++- 17 files changed, 256 insertions(+), 117 deletions(-) create mode 100644 voting-booth/src/main/java/meerkat/voting/controller/callbacks/EncryptionFailedCallback.java create mode 100644 voting-booth/src/main/java/meerkat/voting/controller/commands/RetryEncryptAndCommitBallotCommand.java diff --git a/meerkat-common/src/main/proto/meerkat/voting.proto b/meerkat-common/src/main/proto/meerkat/voting.proto index 4edc9f5..09c8b21 100644 --- a/meerkat-common/src/main/proto/meerkat/voting.proto +++ b/meerkat-common/src/main/proto/meerkat/voting.proto @@ -88,6 +88,10 @@ message BoothParams { } +message BoothSystemMessages { + map system_message = 1; +} + // A table to translate to and from compactly encoded answers // and their human-understandable counterparts. // This should be parsable by the UI @@ -122,14 +126,17 @@ message ElectionParams { // How many mixers must participate for the mixing to be considered valid uint32 mixerThreshold = 5; - // Candidate list (or other question format) - repeated BallotQuestion questions = 6; + // questions to first indicate the voter's channel + repeated BallotQuestion channel_choice_questions = 6; - // Translation table between answers and plaintext encoding - //BallotAnswerTranslationTable answerTranslationTable = 7; + // translating the channel-choice answers to the voter's channel + SimpleCategoriesSelectionData selection_data = 7; + + // Candidate list (or other question format) + repeated BallotQuestion race_questions = 8; // Data required in order to access the Bulletin Board Servers - BulletinBoardClientParams bulletinBoardClientParams = 8; + BulletinBoardClientParams bulletinBoardClientParams = 9; } message Category { diff --git a/voting-booth/src/main/java/meerkat/voting/controller/SystemMessages.java b/voting-booth/src/main/java/meerkat/voting/controller/SystemMessages.java index ee6b506..4f57809 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/SystemMessages.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/SystemMessages.java @@ -33,13 +33,6 @@ final public class SystemMessages { .build(); } - public static UIElement getFatalForceRestartMessage() { - return UIElement.newBuilder() - .setType(UIElementDataType.TEXT) - .setData(ByteString.copyFromUtf8("Fatal error: Internal controller queue received unrecognized command. Force restarting the voting process.")) - .build(); - } - public static UIElement getRestartVotingButton() { return UIElement.newBuilder() .setType(UIElementDataType.TEXT) diff --git a/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothController.java b/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothController.java index 6b706f3..e8eae93 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothController.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothController.java @@ -7,6 +7,7 @@ import meerkat.voting.ui.VotingBoothUI; import meerkat.voting.output.BallotOutputDevice; import meerkat.voting.storage.StorageManager; +import java.io.IOException; import java.util.List; @@ -25,25 +26,7 @@ public interface VotingBoothController extends Runnable{ public void init (BallotOutputDevice outputDevice, VBCryptoManager vbCrypto, VotingBoothUI vbUI, - StorageManager vbStorageManager); - - /** - * set the voting questions - * @param questions - */ - public void setBallotChannelChoiceQuestions(List questions); - - /** - * Set the channel question-selector (the component which matches the ballot questions to each user) - * @param selector the question selector instance - */ - public void setChannelQuestionSelector (QuestionSelector selector); - - /** - * set the voting race questions - * @param questions - */ - public void setBallotRaceQuestions(List questions); + StorageManager vbStorageManager) throws IOException; /** * an asynchronous call from Admin Console (If there is such one implemented) to shut down the system diff --git a/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothImpl.java b/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothImpl.java index a9221bf..b20a11d 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothImpl.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/VotingBoothImpl.java @@ -1,9 +1,11 @@ package meerkat.voting.controller; +import meerkat.protobuf.Crypto; import meerkat.protobuf.Voting.*; import meerkat.voting.controller.callbacks.*; import meerkat.voting.controller.commands.*; import meerkat.voting.controller.selector.QuestionSelector; +import meerkat.voting.controller.selector.SimpleListCategoriesSelector; import meerkat.voting.encryptor.VBCryptoManager; import meerkat.voting.encryptor.VBCryptoManager.EncryptionAndSecrets; import meerkat.voting.output.BallotOutputDevice; @@ -15,6 +17,7 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.security.SignatureException; import java.util.List; +import java.util.Map; import java.util.concurrent.LinkedBlockingQueue; /** @@ -29,6 +32,7 @@ public class VotingBoothImpl implements VotingBoothController { private List questionsForChoosingChannel; private List questions; private QuestionSelector questionSelector; + private Map systemMessages; private LinkedBlockingQueue queue; @@ -41,6 +45,7 @@ public class VotingBoothImpl implements VotingBoothController { private static int requestCounter = 0; + public VotingBoothImpl () { logger = LoggerFactory.getLogger(VotingBoothImpl.class); logger.info("A VotingBoothImpl is constructed"); @@ -53,30 +58,32 @@ public class VotingBoothImpl implements VotingBoothController { public void init(BallotOutputDevice outputDevice, VBCryptoManager vbCrypto, VotingBoothUI vbUI, - StorageManager vbStorageManager) { + StorageManager vbStorageManager) throws IOException { logger.info("init is called"); this.outputDevice = outputDevice; this.crypto = vbCrypto; this.ui = vbUI; this.storageManager = vbStorageManager; + + ElectionParams electionParams; + try { + logger.info("init: reading election params"); + electionParams = storageManager.readElectionParams(); + logger.info("init: reading system messages"); + systemMessages = storageManager.readSystemMessages(); + } + catch (IOException e) { + logger.error("init could not read info from a file. Exception is: " + e); + throw e; + } + + logger.info("init: setting the election parameters"); + this.questionsForChoosingChannel = electionParams.getChannelChoiceQuestionsList(); + this.questions = electionParams.getRaceQuestionsList(); + this.questionSelector = new SimpleListCategoriesSelector(this.questions, electionParams.getSelectionData()); + logger.info("init: setting finished"); } - @Override - public void setBallotChannelChoiceQuestions(List questions) { - logger.info("setting questions"); - this.questionsForChoosingChannel = questions; - } - - @Override - public void setChannelQuestionSelector(QuestionSelector selector) { - this.questionSelector = selector; - } - - @Override - public void setBallotRaceQuestions(List questions) { - logger.info("setting questions"); - this.questions = questions; - } @Override public void run() { @@ -146,7 +153,7 @@ public class VotingBoothImpl implements VotingBoothController { } else { logger.error("handleSingleTask: unknown type of ControllerCommand received: " + task.getClass().getName()); - doReportErrorAndForceRestart(SystemMessages.getSomethingWrongMessage()); + doReportErrorAndForceRestart(systemMessages.get(storageManager.SOMETHING_WRONG_MESSAGE)); } } @@ -156,18 +163,13 @@ public class VotingBoothImpl implements VotingBoothController { private void doShutDown () { logger.info("running callShutDown"); - state.clearPlaintext(); - state.clearCiphertext(); - state.stateIdentifier = VBState.SHUT_DOWN; + state.clearAndResetState(VBState.SHUT_DOWN); //TODO: add commands to actually shut down the machine } private void doRestartVoting () { queue.clear(); - state.clearPlaintext(); - state.clearCiphertext(); - state.stateIdentifier = VBState.NEW_VOTER; - state.currentBallotSerialNumber += 1; + state.clearAndResetState(VBState.NEW_VOTER); ui.startNewVoterSession(new NewVoterCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); } @@ -178,13 +180,12 @@ public class VotingBoothImpl implements VotingBoothController { private void doReportErrorAndForceRestart(UIElement errorMessage) { queue.clear(); - state.clearPlaintext(); - state.clearCiphertext(); - state.stateIdentifier = VBState.FATAL_ERROR_FORCE_NEW_VOTER; - state.currentBallotSerialNumber += 1; + state.clearAndResetState(VBState.FATAL_ERROR_FORCE_NEW_VOTER); ui.showErrorMessageWithButtons(errorMessage, - new UIElement[]{SystemMessages.getRestartVotingButton()}, - new ErrorMessageRestartCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); + new UIElement[]{systemMessages.get(storageManager.RESTART_VOTING_BUTTON)}, + new ErrorMessageRestartCallback(generateRequestIdentifier(), + state.currentBallotSerialNumber, + this.queue)); } private void doChooseChannel () { @@ -192,7 +193,10 @@ public class VotingBoothImpl implements VotingBoothController { logger.debug("doing chooseChannel"); state.stateIdentifier = VBState.CHOOSE_CHANNEL; ui.chooseChannel(this.questionsForChoosingChannel, - new ChannelChoiceCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); + new ChannelChoiceCallback(generateRequestIdentifier(), + state.currentBallotSerialNumber, + this.queue, + systemMessages.get(storageManager.UNSUCCESSFUL_CHANNEL_CHOICE_MESSAGE))); } else { logger.debug("doChooseChannel: current state is " + state.stateIdentifier); @@ -208,7 +212,10 @@ public class VotingBoothImpl implements VotingBoothController { state.channelIdentifier = questionSelector.getChannelIdentifier(channelChoiceAnswers); state.channelSpecificQuestions = questionSelector.selectQuestionsForVoter(state.channelIdentifier); ui.askVoterQuestions(state.channelSpecificQuestions, - new VotingCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); + new VotingCallback(generateRequestIdentifier(), + state.currentBallotSerialNumber, + this.queue, + systemMessages.get(storageManager.UNSUCCESSFUL_VOTING_MESSAGE))); } else { logger.debug("doSetChannelAndAskQuestions: current state is " + state.stateIdentifier); @@ -223,7 +230,8 @@ public class VotingBoothImpl implements VotingBoothController { state.stateIdentifier = VBState.CAST_OR_AUDIT; ui.castOrAudit(new CastOrAuditCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, - this.queue)); + this.queue, + systemMessages.get(storageManager.UNRECOGNIZED_FINALIZE_RESPONSE_MESSAGE))); } else { logger.debug("doChooseFinalizeOption: current state is " + state.stateIdentifier); @@ -233,15 +241,33 @@ public class VotingBoothImpl implements VotingBoothController { private void doCommit (EncryptAndCommitBallotCommand task) { if (state.stateIdentifier == VBState.ANSWER_QUESTIONS) { logger.debug("doing commit"); - state.stateIdentifier = VBState.COMMITTING_TO_BALLOT; - setBallotData (task); - ui.notifyVoterToWaitForFinish(SystemMessages.getWaitForCommitMessage(), - new WaitForFinishCallback(generateRequestIdentifier(), - state.currentBallotSerialNumber, - this.queue)); - outputDevice.commitToBallot(state.plaintextBallot, - state.signedEncryptedBallot, - new OutputDeviceCommitCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); + try { + setBallotData(task); + ui.notifyVoterToWaitForFinish(systemMessages.get(storageManager.WAIT_FOR_COMMIT_MESSAGE), + new WaitForFinishCallback(generateRequestIdentifier(), + state.currentBallotSerialNumber, + this.queue, + systemMessages.get(storageManager.SOMETHING_WRONG_MESSAGE))); + outputDevice.commitToBallot(state.plaintextBallot, + state.signedEncryptedBallot, + new OutputDeviceCommitCallback(generateRequestIdentifier(), + state.currentBallotSerialNumber, + this.queue, + systemMessages.get(storageManager.OUTPUT_DEVICE_FAILURE_MESSAGE))); + state.stateIdentifier = VBState.COMMITTING_TO_BALLOT; + } + catch (SignatureException | IOException e) { + logger.error("doCommit: encryption failed. exception: " + e); + UIElement errorMessage = systemMessages.get(storageManager.ENCRYPTION_FAILED_MESSAGE); + UIElement[] buttons = new UIElement[]{ + systemMessages.get(storageManager.RETRY_BUTTON), + systemMessages.get(storageManager.CANCEL_VOTE_BUTTON)}; + + EncryptionFailedCallback callback = new EncryptionFailedCallback(generateRequestIdentifier(), + state.currentBallotSerialNumber, + this.queue); + ui.showErrorMessageWithButtons(errorMessage, buttons, callback); + } } else { logger.debug("doCommit: current state is " + state.stateIdentifier); @@ -249,18 +275,16 @@ public class VotingBoothImpl implements VotingBoothController { } } - private void setBallotData (EncryptAndCommitBallotCommand task) { - state.plaintextBallot = PlaintextBallot.newBuilder() - .setSerialNumber(task.getBallotSerialNumber()) - .addAllAnswers(task.getVotingAnswers()) - .build(); - EncryptionAndSecrets encryptionAndSecrets = null; - try { - encryptionAndSecrets = crypto.encrypt(state.plaintextBallot); - } - catch (SignatureException | IOException e) { - // TODO: handle exception + private void setBallotData (EncryptAndCommitBallotCommand task) throws IOException, SignatureException{ + if (! (task instanceof RetryEncryptAndCommitBallotCommand)) { + // this is not a retry attempt, so the plaintext is not set yet + // otherwise, we have the plaintext from the previous encryption attempt + state.plaintextBallot = PlaintextBallot.newBuilder() + .setSerialNumber(task.getBallotSerialNumber()) + .addAllAnswers(task.getVotingAnswers()) + .build(); } + EncryptionAndSecrets encryptionAndSecrets = crypto.encrypt(state.plaintextBallot); state.signedEncryptedBallot = encryptionAndSecrets.getSignedEncryptedBallot(); state.secrets = encryptionAndSecrets.getSecrets(); } @@ -270,16 +294,28 @@ public class VotingBoothImpl implements VotingBoothController { logger.debug("finalizing"); state.stateIdentifier = VBState.FINALIZING; if (auditRequested) { - ui.notifyVoterToWaitForFinish(SystemMessages.getWaitForAuditMessage(), - new WaitForFinishCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); + ui.notifyVoterToWaitForFinish(systemMessages.get(storageManager.WAIT_FOR_AUDIT_MESSAGE), + new WaitForFinishCallback(generateRequestIdentifier(), + state.currentBallotSerialNumber, + this.queue, + systemMessages.get(storageManager.SOMETHING_WRONG_MESSAGE))); outputDevice.audit(state.secrets, - new OutputDeviceFinalizeCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); + new OutputDeviceFinalizeCallback(generateRequestIdentifier(), + state.currentBallotSerialNumber, + this.queue, + systemMessages.get(storageManager.OUTPUT_DEVICE_FAILURE_MESSAGE))); } else { ui.notifyVoterToWaitForFinish(SystemMessages.getWaitForCastMessage(), - new WaitForFinishCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); + new WaitForFinishCallback(generateRequestIdentifier(), + state.currentBallotSerialNumber, + this.queue, + systemMessages.get(storageManager.SOMETHING_WRONG_MESSAGE))); outputDevice.castBallot( - new OutputDeviceFinalizeCallback(generateRequestIdentifier(), state.currentBallotSerialNumber, this.queue)); + new OutputDeviceFinalizeCallback(generateRequestIdentifier(), + state.currentBallotSerialNumber, + this.queue, + systemMessages.get(storageManager.OUTPUT_DEVICE_FAILURE_MESSAGE))); } } else { @@ -325,14 +361,22 @@ public class VotingBoothImpl implements VotingBoothController { } - public void clearPlaintext () { + private void clearPlaintext () { plaintextBallot = null; } - public void clearCiphertext () { + private void clearCiphertext () { signedEncryptedBallot = null; secrets = null; } + + public void clearAndResetState(VBState newStateIdentifier) { + state.clearPlaintext(); + state.clearCiphertext(); + state.stateIdentifier = newStateIdentifier; + state.currentBallotSerialNumber += 1; + } + } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/CastOrAuditCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/CastOrAuditCallback.java index 69d5123..47ecd3b 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/CastOrAuditCallback.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/CastOrAuditCallback.java @@ -1,9 +1,8 @@ package meerkat.voting.controller.callbacks; -import meerkat.voting.controller.SystemMessages; +import meerkat.protobuf.Voting.UIElement; import meerkat.voting.controller.commands.*; import meerkat.voting.controller.commands.ControllerCommand; -import meerkat.voting.controller.commands.RestartVotingCommand; import meerkat.voting.ui.VotingBoothUI.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,11 +11,14 @@ import java.util.concurrent.LinkedBlockingQueue; public class CastOrAuditCallback extends ControllerCallback { protected final static Logger logger = LoggerFactory.getLogger(CastOrAuditCallback.class); + protected final UIElement unrecognizedFinalizeResponseMessage; public CastOrAuditCallback(int requestId, long ballotSerialNumber, - LinkedBlockingQueue controllerQueue) { + LinkedBlockingQueue controllerQueue, + UIElement unrecognizedFinalizeResponseMessage) { super(requestId, ballotSerialNumber, controllerQueue); + this.unrecognizedFinalizeResponseMessage = unrecognizedFinalizeResponseMessage; } @Override @@ -31,7 +33,7 @@ public class CastOrAuditCallback extends ControllerCallback> { protected final static Logger logger = LoggerFactory.getLogger(ChannelChoiceCallback.class); + protected final UIElement unsuccessfulChannelChoiceMessage; public ChannelChoiceCallback(int requestId, long ballotSerialNumber, - LinkedBlockingQueue controllerQueue) { + LinkedBlockingQueue controllerQueue, + UIElement unsuccessfulChannelChoiceMessage) { super(requestId, ballotSerialNumber, controllerQueue); + this.unsuccessfulChannelChoiceMessage = unsuccessfulChannelChoiceMessage; } @Override @@ -37,7 +39,7 @@ public class ChannelChoiceCallback extends ControllerCallback logger.error("channel choice initiated a failure: " + t); enqueueCommand(new ReportErrorCommand(getRequestIdentifier(), getBallotSerialNumber(), - SystemMessages.getUnsuccessfulChannelChoiceMessage())); + unsuccessfulChannelChoiceMessage)); } } } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/EncryptionFailedCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/EncryptionFailedCallback.java new file mode 100644 index 0000000..de7a61e --- /dev/null +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/EncryptionFailedCallback.java @@ -0,0 +1,43 @@ +package meerkat.voting.controller.callbacks; + +import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException; +import meerkat.voting.controller.commands.ControllerCommand; +import meerkat.voting.controller.commands.RestartVotingCommand; +import meerkat.voting.controller.commands.RetryEncryptAndCommitBallotCommand; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.LinkedBlockingQueue; + +public class EncryptionFailedCallback extends ControllerCallback { + protected final static Logger logger = LoggerFactory.getLogger(EncryptionFailedCallback.class); + + public EncryptionFailedCallback(int requestId, + long ballotSerialNumber, + LinkedBlockingQueue controllerQueue) { + super(requestId, ballotSerialNumber, controllerQueue); + } + + @Override + public void onSuccess(Integer result) { + logger.debug("callback for voting returned success"); + int res = result.intValue(); + if (res == 0) { + logger.debug("voter chose to retry encryption"); + enqueueCommand(new RetryEncryptAndCommitBallotCommand(getRequestIdentifier(), getBallotSerialNumber())); + } + else if (res == 1) { + logger.debug("voter chose to cancel the vote"); + enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); + } + else { + onFailure(new ValueException("EncryptionFailedCallback got an unknown result (" + res + ")")); + } + } + + @Override + public void onFailure(Throwable t) { + logger.error("Error message execution initiated a failure: " + t); + enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber())); + } +} diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/OutputDeviceCommitCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/OutputDeviceCommitCallback.java index a6eaadf..a832572 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/OutputDeviceCommitCallback.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/OutputDeviceCommitCallback.java @@ -1,6 +1,6 @@ package meerkat.voting.controller.callbacks; -import meerkat.voting.controller.SystemMessages; +import meerkat.protobuf.Voting.UIElement; import meerkat.voting.controller.commands.ControllerCommand; import meerkat.voting.controller.commands.ChooseFinalizeOptionCommand; import meerkat.voting.controller.commands.ReportErrorCommand; @@ -11,11 +11,14 @@ import java.util.concurrent.LinkedBlockingQueue; public class OutputDeviceCommitCallback extends ControllerCallback { protected final static Logger logger = LoggerFactory.getLogger(OutputDeviceCommitCallback.class); + protected final UIElement outputDeviceFailureMessage; public OutputDeviceCommitCallback(int requestId, long ballotSerialNumber, - LinkedBlockingQueue controllerQueue) { + LinkedBlockingQueue controllerQueue, + UIElement outputDeviceFailureMessage) { super(requestId, ballotSerialNumber, controllerQueue); + this.outputDeviceFailureMessage = outputDeviceFailureMessage; } @Override @@ -29,6 +32,6 @@ public class OutputDeviceCommitCallback extends ControllerCallback { logger.error("OutputDeviceCommitCallback got a failure: " + t); enqueueCommand(new ReportErrorCommand(getRequestIdentifier(), getBallotSerialNumber(), - SystemMessages.getOutputDeviceFailureMessage())); + outputDeviceFailureMessage)); } } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/OutputDeviceFinalizeCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/OutputDeviceFinalizeCallback.java index 74a85e0..414bdb0 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/OutputDeviceFinalizeCallback.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/OutputDeviceFinalizeCallback.java @@ -1,6 +1,6 @@ package meerkat.voting.controller.callbacks; -import meerkat.voting.controller.SystemMessages; +import meerkat.protobuf.Voting.UIElement; import meerkat.voting.controller.commands.ControllerCommand; import meerkat.voting.controller.commands.ReportErrorCommand; import meerkat.voting.controller.commands.RestartVotingCommand; @@ -11,11 +11,14 @@ import java.util.concurrent.LinkedBlockingQueue; public class OutputDeviceFinalizeCallback extends ControllerCallback { protected final static Logger logger = LoggerFactory.getLogger(OutputDeviceFinalizeCallback.class); + protected final UIElement outputDeviceFailureMessage; public OutputDeviceFinalizeCallback(int requestId, long ballotSerialNumber, - LinkedBlockingQueue controllerQueue) { + LinkedBlockingQueue controllerQueue, + UIElement outputDeviceFailureMessage) { super(requestId, ballotSerialNumber, controllerQueue); + this.outputDeviceFailureMessage = outputDeviceFailureMessage; } @Override @@ -29,6 +32,6 @@ public class OutputDeviceFinalizeCallback extends ControllerCallback { logger.error("OutputDeviceFinalizeCallback got a failure: " + t); enqueueCommand(new ReportErrorCommand(getRequestIdentifier(), getBallotSerialNumber(), - SystemMessages.getOutputDeviceFailureMessage())); + outputDeviceFailureMessage)); } } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/VotingCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/VotingCallback.java index 4b6f2f7..173fa82 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/VotingCallback.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/VotingCallback.java @@ -1,7 +1,6 @@ package meerkat.voting.controller.callbacks; import meerkat.protobuf.Voting.*; -import meerkat.voting.controller.SystemMessages; import meerkat.voting.controller.commands.ControllerCommand; import meerkat.voting.controller.commands.EncryptAndCommitBallotCommand; import meerkat.voting.controller.commands.ReportErrorCommand; @@ -14,11 +13,14 @@ import java.util.concurrent.LinkedBlockingQueue; public class VotingCallback extends ControllerCallback> { protected final static Logger logger = LoggerFactory.getLogger(VotingCallback.class); + protected final UIElement unsuccessfulVotingMessage; public VotingCallback(int requestId, long ballotSerialNumber, - LinkedBlockingQueue controllerQueue) { + LinkedBlockingQueue controllerQueue, + UIElement unsuccessfulVotingMessage) { super(requestId, ballotSerialNumber, controllerQueue); + this.unsuccessfulVotingMessage = unsuccessfulVotingMessage; } @Override @@ -37,7 +39,7 @@ public class VotingCallback extends ControllerCallback> { logger.error("voting initiated a failure: " + t); enqueueCommand(new ReportErrorCommand(getRequestIdentifier(), getBallotSerialNumber(), - SystemMessages.getUnsuccessfulVotingMessage())); + unsuccessfulVotingMessage)); } } } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/WaitForFinishCallback.java b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/WaitForFinishCallback.java index 9f7a159..2634e27 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/callbacks/WaitForFinishCallback.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/callbacks/WaitForFinishCallback.java @@ -1,9 +1,8 @@ package meerkat.voting.controller.callbacks; -import meerkat.voting.controller.SystemMessages; +import meerkat.protobuf.Voting.UIElement; import meerkat.voting.controller.commands.ControllerCommand; import meerkat.voting.controller.commands.ReportErrorCommand; -import meerkat.voting.controller.commands.RestartVotingCommand; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,11 +10,14 @@ import java.util.concurrent.LinkedBlockingQueue; public class WaitForFinishCallback extends ControllerCallback { protected final static Logger logger = LoggerFactory.getLogger(WaitForFinishCallback.class); + protected final UIElement somethingWrongMessage; public WaitForFinishCallback(int requestId, long ballotSerialNumber, - LinkedBlockingQueue controllerQueue) { + LinkedBlockingQueue controllerQueue, + UIElement somethingWrongMessage) { super(requestId, ballotSerialNumber, controllerQueue); + this.somethingWrongMessage = somethingWrongMessage; } @Override @@ -27,6 +29,6 @@ public class WaitForFinishCallback extends ControllerCallback { logger.error("WaitForFinishCallback got a failure: " + t); enqueueCommand(new ReportErrorCommand(getRequestIdentifier(), getBallotSerialNumber(), - SystemMessages.getSomethingWrongMessage())); + somethingWrongMessage)); } } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/commands/EncryptAndCommitBallotCommand.java b/voting-booth/src/main/java/meerkat/voting/controller/commands/EncryptAndCommitBallotCommand.java index 074216f..d7e4508 100644 --- a/voting-booth/src/main/java/meerkat/voting/controller/commands/EncryptAndCommitBallotCommand.java +++ b/voting-booth/src/main/java/meerkat/voting/controller/commands/EncryptAndCommitBallotCommand.java @@ -1,13 +1,14 @@ package meerkat.voting.controller.commands; -import meerkat.protobuf.Voting.*; - +import meerkat.protobuf.Voting.BallotAnswer; import java.util.List; public class EncryptAndCommitBallotCommand extends ControllerCommand { private final List votingAnswers; - public EncryptAndCommitBallotCommand(int requestIdentifier, long ballotSerialNumber, List answers) { + public EncryptAndCommitBallotCommand(int requestIdentifier, + long ballotSerialNumber, + List answers) { super(requestIdentifier, ballotSerialNumber); votingAnswers = answers; } @@ -15,4 +16,5 @@ public class EncryptAndCommitBallotCommand extends ControllerCommand { public List getVotingAnswers() { return votingAnswers; } + } diff --git a/voting-booth/src/main/java/meerkat/voting/controller/commands/RetryEncryptAndCommitBallotCommand.java b/voting-booth/src/main/java/meerkat/voting/controller/commands/RetryEncryptAndCommitBallotCommand.java new file mode 100644 index 0000000..66dc992 --- /dev/null +++ b/voting-booth/src/main/java/meerkat/voting/controller/commands/RetryEncryptAndCommitBallotCommand.java @@ -0,0 +1,10 @@ +package meerkat.voting.controller.commands; + +public class RetryEncryptAndCommitBallotCommand extends EncryptAndCommitBallotCommand { + + public RetryEncryptAndCommitBallotCommand(int requestIdentifier, + long ballotSerialNumber) { + super(requestIdentifier, ballotSerialNumber, null); + } + +} diff --git a/voting-booth/src/main/java/meerkat/voting/encryptor/VBCryptoManager.java b/voting-booth/src/main/java/meerkat/voting/encryptor/VBCryptoManager.java index e664607..d5216e4 100644 --- a/voting-booth/src/main/java/meerkat/voting/encryptor/VBCryptoManager.java +++ b/voting-booth/src/main/java/meerkat/voting/encryptor/VBCryptoManager.java @@ -36,6 +36,7 @@ public interface VBCryptoManager { * @param plaintextBallot - all plaintext ballot info of the voter * @return an encryption of the ballot */ + // TODO: do we seed the random here? public EncryptionAndSecrets encrypt (PlaintextBallot plaintextBallot) throws SignatureException, IOException; diff --git a/voting-booth/src/main/java/meerkat/voting/encryptor/VBCryptoManagerImpl.java b/voting-booth/src/main/java/meerkat/voting/encryptor/VBCryptoManagerImpl.java index 722c24e..2bc9729 100644 --- a/voting-booth/src/main/java/meerkat/voting/encryptor/VBCryptoManagerImpl.java +++ b/voting-booth/src/main/java/meerkat/voting/encryptor/VBCryptoManagerImpl.java @@ -52,6 +52,8 @@ public class VBCryptoManagerImpl implements VBCryptoManager { .setSignature(digitalSignature.sign()) .build(); + // TODO: still has to supply RandomnessGenerationProof as well + return new EncryptionAndSecrets(signedEncryptedBallot, secrets); } catch (IOException e) { diff --git a/voting-booth/src/main/java/meerkat/voting/storage/StorageManager.java b/voting-booth/src/main/java/meerkat/voting/storage/StorageManager.java index 9bf7764..b9ccca7 100644 --- a/voting-booth/src/main/java/meerkat/voting/storage/StorageManager.java +++ b/voting-booth/src/main/java/meerkat/voting/storage/StorageManager.java @@ -3,6 +3,7 @@ package meerkat.voting.storage; import meerkat.protobuf.Voting.*; import java.io.IOException; +import java.util.Map; /** * An interface for the storage component of the voting booth @@ -29,4 +30,20 @@ public interface StorageManager { */ public void writeElectionParams(ElectionParams params) throws IOException; + + public Map readSystemMessages() throws IOException; + + + public final static String WAIT_FOR_COMMIT_MESSAGE = "waitForCommit"; + public final static String WAIT_FOR_AUDIT_MESSAGE = "waitForAudit"; + public final static String WAIT_FOR_CAST_MESSAGE = "waitForCast"; + public final static String RESTART_VOTING_BUTTON = "restartVotingButton"; + public final static String UNRECOGNIZED_FINALIZE_RESPONSE_MESSAGE = "unrecognizedFinalizeResponse"; + public final static String UNSUCCESSFUL_CHANNEL_CHOICE_MESSAGE = "unsuccessfulChannelChoice"; + public final static String OUTPUT_DEVICE_FAILURE_MESSAGE = "outputDeviceFailure"; + public final static String UNSUCCESSFUL_VOTING_MESSAGE = "unsuccessfulVoting"; + public final static String SOMETHING_WRONG_MESSAGE = "somethingWrong"; + public final static String ENCRYPTION_FAILED_MESSAGE = "encryptionFailed"; + public final static String RETRY_BUTTON = "retryButton"; + public final static String CANCEL_VOTE_BUTTON = "cancelVoteButton"; } diff --git a/voting-booth/src/main/java/meerkat/voting/storage/StorageManagerMockup.java b/voting-booth/src/main/java/meerkat/voting/storage/StorageManagerMockup.java index 23c89cf..ea9ac08 100644 --- a/voting-booth/src/main/java/meerkat/voting/storage/StorageManagerMockup.java +++ b/voting-booth/src/main/java/meerkat/voting/storage/StorageManagerMockup.java @@ -1,5 +1,6 @@ package meerkat.voting.storage; +import com.google.protobuf.ByteString; import meerkat.protobuf.Voting.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -7,6 +8,8 @@ import org.slf4j.LoggerFactory; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; /** * A mockup for the StorageManager interface @@ -16,7 +19,8 @@ public class StorageManagerMockup implements StorageManager { private boolean adminHardwareKeyInserted; private Logger logger; - private String electionParamFullFilename = "~/meerkat_election_params_tempfile.dat"; + public static final String electionParamFullFilename = "/home/hai/meerkat-java/meerkat_election_params_tempfile.dat"; + public static final String systemMessagesFilename = "/home/hai/meerkat-java/meerkat_booth_system_messages.dat"; public StorageManagerMockup () { logger = LoggerFactory.getLogger(StorageManagerMockup.class); @@ -64,4 +68,23 @@ public class StorageManagerMockup implements StorageManager { } } + + @Override + public Map readSystemMessages() throws IOException { + + logger.info("Entered method readSystemMessages"); + BoothSystemMessages systemMessages; + try { + FileInputStream inputStream = new FileInputStream(systemMessagesFilename); + systemMessages = BoothSystemMessages.parseFrom(inputStream); + inputStream.close(); + logger.info ("Successfully read systemMessages protobuf from a file"); + } + catch (IOException e) { + logger.error("Could not read from the systemMessages file: '" + systemMessagesFilename + "'."); + throw e; + } + return systemMessages.getSystemMessage(); + } + }