From 3f5b5ab1e427a68e8e93d269acbac338879fff7e Mon Sep 17 00:00:00 2001 From: Hai Brenner Date: Mon, 22 Feb 2016 21:03:27 +0200 Subject: [PATCH] Committing before moving to another new and better branch --- .../src/main/proto/meerkat/voting.proto | 4 +- .../java/meerkat/voting/EncryptionFake.java | 3 +- .../java/meerkat/voting/VotingBoothToy.java | 110 +++- .../voting/VotingBoothToyConsoleUI.java | 594 ++++++++++-------- .../meerkat/voting/VotingBoothToyDemoRun.java | 18 +- 5 files changed, 438 insertions(+), 291 deletions(-) diff --git a/meerkat-common/src/main/proto/meerkat/voting.proto b/meerkat-common/src/main/proto/meerkat/voting.proto index 7766f1e..8764c1d 100644 --- a/meerkat-common/src/main/proto/meerkat/voting.proto +++ b/meerkat-common/src/main/proto/meerkat/voting.proto @@ -78,7 +78,7 @@ message BallotQuestionNew { bool is_mandatory = 1; UIElement question = 2; UIElement description = 3; - repeated UIElement answers = 4; + repeated UIElement answer = 4; } @@ -110,7 +110,7 @@ message ElectionParams { uint32 mixerThreshold = 5; // Candidate list (or other question format) - repeated BallotQuestionNew questions = 6; + repeated BallotQuestionNew question = 6; // Translation table between answers and plaintext encoding //BallotAnswerTranslationTable answerTranslationTable = 7; diff --git a/voting-booth/src/main/java/meerkat/voting/EncryptionFake.java b/voting-booth/src/main/java/meerkat/voting/EncryptionFake.java index 291e786..80278d4 100644 --- a/voting-booth/src/main/java/meerkat/voting/EncryptionFake.java +++ b/voting-booth/src/main/java/meerkat/voting/EncryptionFake.java @@ -11,7 +11,6 @@ import meerkat.crypto.Encryption; import meerkat.protobuf.Crypto.EncryptionPublicKey; import meerkat.protobuf.Crypto.EncryptionRandomness; import meerkat.protobuf.Crypto.RerandomizableEncryptedMessage; -import sun.reflect.generics.reflectiveObjects.NotImplementedException; public class EncryptionFake implements Encryption { @@ -43,7 +42,7 @@ public class EncryptionFake implements Encryption { throws InvalidProtocolBufferException { // TODO Auto-generated method stub System.err.println("rerandomize: not implemented!"); - throw new NotImplementedException(); + throw new UnsupportedOperationException(); } @Override diff --git a/voting-booth/src/main/java/meerkat/voting/VotingBoothToy.java b/voting-booth/src/main/java/meerkat/voting/VotingBoothToy.java index bfd43a6..7e99ef2 100644 --- a/voting-booth/src/main/java/meerkat/voting/VotingBoothToy.java +++ b/voting-booth/src/main/java/meerkat/voting/VotingBoothToy.java @@ -1,18 +1,28 @@ package meerkat.voting; +import meerkat.crypto.concrete.ECElGamalEncryption; +import meerkat.crypto.concrete.GlobalCryptoSetup; +import meerkat.protobuf.ConcreteCrypto; import meerkat.protobuf.Voting.*; import meerkat.crypto.Encryption; import meerkat.protobuf.Crypto.*; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; -import java.util.List; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import com.google.protobuf.ByteString; - +import org.bouncycastle.jce.spec.*; +import org.bouncycastle.math.ec.ECPoint; +import org.factcenter.qilin.primitives.concrete.ECElGamal; +import org.factcenter.qilin.primitives.concrete.ECGroup; +import org.factcenter.qilin.primitives.generic.ElGamal; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class VotingBoothToy implements VotingBooth, Runnable { @@ -29,18 +39,18 @@ public class VotingBoothToy implements VotingBooth, Runnable { private VotingBooth.UI m_ui; //TODO: where do I use these? - SignatureVerificationKey a_signatureKeys[]; + //SignatureVerificationKey a_signatureKeys[]; - Encryption m_encryption; + Encryption m_encryptor; Random m_random; - - - - public VotingBoothToy () { + + Logger logger; + + + public VotingBoothToy () { + logger = LoggerFactory.getLogger(VotingBoothToy.class); a_queue = new ArrayBlockingQueue (m_queueSize, true); - - m_encryption = new EncryptionFake(m_ballotEncryptionKey); - m_random = new Random(); + } public void registerUI (UI ui) { @@ -53,7 +63,7 @@ public class VotingBoothToy implements VotingBooth, Runnable { while (true) { VBMessage msg; try { - msg = a_queue.take(); + msg = a_queue.take(); } catch (InterruptedException e) { System.err.println("VB controller interrupted!!"); @@ -76,11 +86,11 @@ public class VotingBoothToy implements VotingBooth, Runnable { // encrypt RerandomizableEncryptedMessage encMsg; - EncryptionRandomness rnd = m_encryption.generateRandomness(m_random); + EncryptionRandomness rnd = m_encryptor.generateRandomness(m_random); try { // simulate taking a lot of time - Thread.sleep(30000); - encMsg = m_encryption.encrypt(ptb, rnd); + Thread.sleep(5000); + encMsg = m_encryptor.encrypt(ptb, rnd); } catch (InterruptedException e) { System.err.println("debug: VotingBoothToy encrypt interrupted!"); @@ -90,7 +100,7 @@ public class VotingBoothToy implements VotingBooth, Runnable { System.err.println("debug: VotingBoothToy encrypt IOException!"); return; } - + EncryptedBallot encBallot = EncryptedBallot.newBuilder() .setSerialNumber(ptb.getSerialNumber()) .setData(encMsg) @@ -103,7 +113,7 @@ public class VotingBoothToy implements VotingBooth, Runnable { .setEncryptionRandomness(rnd) .setProof(proof) .build(); - + m_ui.commitToEncryptedBallot(encBallot, secrets); } @@ -117,28 +127,64 @@ public class VotingBoothToy implements VotingBooth, Runnable { this.m_ballotEncryptionKey = globalParams.getBallotEncryptionKey(); //this.l_questions = globalParams.getQuestionsList(); - List l_signatureKeys = boothParams.getPscVerificationKeysList(); - a_signatureKeys = new SignatureVerificationKey[l_signatureKeys.size()]; - int i = 0; - for (SignatureVerificationKey q: l_signatureKeys) { - a_signatureKeys[i] = q; - ++i; - } +// List l_signatureKeys = boothParams.getPscVerificationKeysList(); +// a_signatureKeys = new SignatureVerificationKey[l_signatureKeys.size()]; +// int i = 0; +// for (SignatureVerificationKey q: l_signatureKeys) { +// a_signatureKeys[i] = q; +// ++i; +// } + + m_random = new Random(); + ECGroup group = new ECGroup("secp256k1"); + java.math.BigInteger sk = ECElGamal.generateSecretKey(group, m_random); + ElGamal.SK key = new ECElGamal.SK(group, sk); + ConcreteCrypto.ElGamalPublicKey serializedPk = serializePk(group, key); + m_encryptor = new ECElGamalEncryption(); + m_encryptor.init(serializedPk); + + + //TODO: generate my own signature key + System.err.println("Here the controller should create its own signature key"); } - public void registerVBUI (VotingBooth.UI ui) - { - m_ui = ui; - } - /* (non-Javadoc) + + /** + * This method was copied from a test file + * It must be resolved in another way! + * //TODO: where should this method be declared? + */ + public ConcreteCrypto.ElGamalPublicKey serializePk(ECGroup group, ElGamal.PK pk) { + ECPoint pkPoint = pk.getPK(); + ECParameterSpec params = group.getCurveParams(); + + ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(pkPoint, params); + + try { + final String ENCRYPTION_KEY_ALGORITHM = "ECDH"; + + KeyFactory fact = KeyFactory.getInstance(ENCRYPTION_KEY_ALGORITHM, + GlobalCryptoSetup.getBouncyCastleProvider()); + PublicKey javaPk = fact.generatePublic(pubKeySpec); + ConcreteCrypto.ElGamalPublicKey serializedPk = ConcreteCrypto.ElGamalPublicKey.newBuilder() + .setSubjectPublicKeyInfo(ByteString.copyFrom(javaPk.getEncoded())).build(); + + return serializedPk; + } catch (NoSuchAlgorithmException |InvalidKeySpecException e) { + System.err.println("Should never happen!"); + throw new RuntimeException("Error converting public key!", e); + } + } + + /* (non-Javadoc) * @see meerkat.voting.VotingBooth#submitBallot(meerkat.protobuf.Voting.PlaintextBallot) */ @Override public void submitBallot(PlaintextBallot ballot) { VBMessage msg = VBMessage.newEncryptionQuery(ballot); try { - a_queue.put(msg); + a_queue.put(msg); } catch (InterruptedException e) { System.err.println("SubmitBallot interrupted!!"); diff --git a/voting-booth/src/main/java/meerkat/voting/VotingBoothToyConsoleUI.java b/voting-booth/src/main/java/meerkat/voting/VotingBoothToyConsoleUI.java index c3e0a1c..e49d850 100644 --- a/voting-booth/src/main/java/meerkat/voting/VotingBoothToyConsoleUI.java +++ b/voting-booth/src/main/java/meerkat/voting/VotingBoothToyConsoleUI.java @@ -1,120 +1,275 @@ -/** - * - */ package meerkat.voting; +import com.google.protobuf.ByteString; +import meerkat.protobuf.Voting; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import java.util.Date; -import java.util.List; -import java.util.StringTokenizer; -import java.util.Timer; -import java.util.TimerTask; +import java.util.*; import java.util.concurrent.ArrayBlockingQueue; -import com.google.protobuf.ByteString; - -import meerkat.protobuf.Voting.*; -import meerkat.voting.VotingBooth.UI; - -/** - * @author hai - * - */ -public class VotingBoothToyConsoleUI implements UI, Runnable { +public class VotingBoothToyConsoleUI implements VotingBooth.UI, Runnable { private BufferedReader m_in; private VotingBooth m_vbController; - //private SharedPlaintextBallotMessage m_sharedPlaintext; - //private SharedEncryptedBallotMessage m_sharedEncrypted; private ArrayBlockingQueue a_queue; static private int m_queueSize = 5; - private BallotQuestionNew a_questions[]; + private Voting.BallotQuestionNew a_questions[]; private int m_serialNumber; - private PlaintextBallot m_plaintextBallot; - private EncryptedBallot m_encryptedBallot; - private BallotSecrets m_ballotSecrets; - private int m_waitForControllerMillisecTimeout = 10; + private Voting.PlaintextBallot m_plaintextBallot; + private Voting.EncryptedBallot m_encryptedBallot; + private Voting.BallotSecrets m_ballotSecrets; + private final Logger logger; + private String m_channel; + private boolean b_isInitialized; + private boolean b_allowRecastOfAudittedBallot; + private int m_waitForControllerMillisecTimeout = 100; - - public VotingBoothToyConsoleUI () { - a_queue = new ArrayBlockingQueue (m_queueSize, true); - } - - public VotingBoothToyConsoleUI(ElectionParams globalParams) { - m_serialNumber = 0; - - List l_questions = globalParams.getQuestionsList(); - a_questions = new BallotQuestionNew[l_questions.size()]; + /* + * constructor for the Console-UI class + */ + public VotingBoothToyConsoleUI() { + logger = LoggerFactory.getLogger(VotingBoothToyConsoleUI.class); + + a_queue = new ArrayBlockingQueue<>(m_queueSize, true); m_in = new BufferedReader(new InputStreamReader(System.in)); - + + b_isInitialized = false; + b_allowRecastOfAudittedBallot = false; + } + + /* + * a function for setting behavior of the VotingBoothToy. + * If it is set to true, then a ballot which was auditted can be printed again for casting. + * If it is false, then after auditing, the voter has to answer all questions again. + * Default is false (cannot re-cast an auditted ballot) + */ + public void setAllowRecastOfAudittedBallot (boolean b) { + b_allowRecastOfAudittedBallot = b; + } + + /* + * initialize the election params + */ + public void init(Voting.ElectionParams globalParams) { + m_serialNumber = 0; + + List l_questions = globalParams.getQuestionList(); + a_questions = new Voting.BallotQuestionNew[l_questions.size()]; + int i = 0; - for (BallotQuestionNew q: l_questions) { + for (Voting.BallotQuestionNew q: l_questions) { a_questions[i] = q; ++i; } + + b_isInitialized = true; + } + + + public void run() { + logger.debug("run: initializing the magic!"); + + if ((! b_isInitialized) || isHardwareKeyInserted()) + { + runAdminSetupScenario(); + } + + runVoterScenario(); + } + + /* + * checks if someone inserted a hardware key. + * This is used to decided whther to run Voter scenario or Admin-Setup scenario + */ + private boolean isHardwareKeyInserted() { + logger.warn("isHardwareKeyInserted: currently always false -> so running Voter scenario"); + return false; + } + + private void runVoterScenario() { + while (true) { + logger.debug("votingBegin: preparing console UI for a new user."); + // clear history from memory + eraseEncryption(); + erasePlaintext(); + showWelcomeScreen(); + ++m_serialNumber; + runVotingFlow(); + } + } + + private void runAdminSetupScenario() { + if (! isHardwareKeyInserted()) + { + System.out.println ("Waiting For hardware key to be inserted by admin..."); + showNotInitializedScreen(); + } + while (! isHardwareKeyInserted()) + { + try { + Thread.sleep(100); + } + catch (InterruptedException e) + { + logger.error ("runAdminSetupScenario: interrupted while waiting for admin hardware key to be inserted"); + throw new RuntimeException("runAdminSetupScenario: interrupted while waiting for admin hardware key to be inserted"); + } + } + System.out.println ("runAdminSetupScenario: found hardware key"); + throw new UnsupportedOperationException("runAdminSetupScenario: not yet implemented"); + } + + private String readInputLine() { + String s; + try { + s = this.m_in.readLine(); + } catch (IOException e) { + logger.error("readInputLine: some error with reading input. " + e); + return null; + } + + return s; } - /* (non-Javadoc) - * @see meerkat.voting.VotingBooth.UI#votingBegin() - */ + * @see meerkat.voting.VotingBooth.UI#votingBegin() + */ @Override - public void votingBegin() { - System.err.println ("UI debug: preparing console UI for a new user."); - - // clear history from memory - eraseEncryption(); - erasePlaintext(); - - System.out.println ("UI screen: Welcome. Press to start"); - readInputLine(); - - ++ m_serialNumber; - - runVotingFlow (); + public void votingBegin() { + throw new UnsupportedOperationException("votingBegin: this is actually not a good method for the interface. just run() instead"); } - - private void runVotingFlow () { - + + + /* + * This is a welcome screen for the voter + */ + private void showWelcomeScreen() { + System.out.println("UI screen: Welcome. Press to start"); + readInputLine(); + } + + /* + * This is a not-initialized error message screen + */ + private void showNotInitializedScreen() { + System.out.println("UI screen: Election params were not yet initialized"); + System.out.println("UI screen: You must reboot the machine with an admin USB stick plugged in"); + } + + /* + * erase previous encryption from memory + */ + private void eraseEncryption() { + //TODO: should we clean memory 'stronger'? + if (m_encryptedBallot != null) { + m_encryptedBallot = null; + } + if (m_ballotSecrets != null) { + m_ballotSecrets = null; + } + } + + /* + * erase previous plaintext from memory + */ + private void erasePlaintext() { + //TODO: should we clean memory 'stronger'? + if (m_plaintextBallot != null) { + m_plaintextBallot = null; + } + } + + /* + * The voter first needs to choose a channel + */ + + private String chooseChannel() { + System.out.println("UI screen: Choose channel"); + System.out.println("UI screen: currently does nothing. Just type any string you like"); + m_channel = readInputLine(); + return m_channel; + } + + /* + * The voting process itself + */ + private void runVotingFlow() { try { - - boolean votingOccured = listQuestionsToUserAndGetAnswers (); - - if (! votingOccured) - { - // cancel vote; - return; - } - else { + boolean votingOccured = listQuestionsToUserAndGetAnswers(); + if (votingOccured) { printBallotFlow(); } - - } - catch (IOException e) { + } catch (IOException e) { System.err.println("UI debug: IO error"); } } - + private void printBallotFlow () throws IOException{ + logger.warn("UI debug: printBallotFlow currently not multithreaded... will fix it..."); + + boolean ended = false; + while (!ended) { + sendBallotToControllerForEncryptionAndWaitForResponse (); + sendBallotToPrinterAndWaitToEnd(); + ended = castOrAudit(); + eraseEncryption(); + } + erasePlaintext(); + } + + + /* + * This function sends the ballot to the printer + */ private void sendBallotToPrinterAndWaitToEnd () { - System.err.println("UI debug: sendBallotToPrinterAndWaitToEnd: still not multithreaded..."); + logger.warn("UI debug: sendBallotToPrinterAndWaitToEnd: still not multithreaded..."); System.out.println("UI screen: printing ballot wait for printing to end"); System.out.println("UI printer: printing ballot"); } - - // returns true if cast or cancelled + + /* + * This function sends the audit to the printer + */ + private void sendAuditToPrinterAndWaitToEnd () { + logger.warn("UI debug: sendAuditToPrinterAndWaitToEnd: still not multithreaded..."); + System.out.println("UI printer: printing audit"); + } + + private void showPrintingAuditScreen () { + System.out.println("UI screen: printing audit wait for printing to end"); + } + + /* + * checks if the voter wants to cast the ballot or audit + * returns true if done with this ballot (cast or cancelled) + * returns false if still needs the current ballot info + */ private boolean castOrAudit () throws IOException{ System.out.println("UI screen: (c)ast or (a)udit?"); String choice = readInputLine(); + if (null == choice) { + logger.error("castOrAudit: got null as response"); + throw new IOException(); + } if (choice.equals("a") || choice.equals("audit")) { - System.err.println ("UI debug: voter decided to audit"); - System.out.println("UI screen: printing audit wait for printing to end"); - System.out.println("UI printer: printing audit"); + logger.debug ("UI debug: voter decided to audit"); + showPrintingAuditScreen(); + sendAuditToPrinterAndWaitToEnd (); + + if (!b_allowRecastOfAudittedBallot) { + return true; + } System.out.println("Do you still want to keep this vote? Type 'y' for casting/auditing the same vote. Type 'n' tp start from scratch"); String choice2 = readInputLine(); + if (null == choice2) { + logger.error("castOrAudit: got null as response"); + throw new IOException (); + } if (choice2.equals("y") || choice.equals("yes")) { return false; } @@ -127,7 +282,7 @@ public class VotingBoothToyConsoleUI implements UI, Runnable { } else if (choice.equals("c") || choice.equals("cast") || choice.equals("cancel")) { System.err.println ("UI debug: voter decided to cast vote."); - System.out.println("UI screen: wait for printer to finish"); + System.out.println("UI screen: wait for printer to finish"); System.out.println("UI printer: printing empty space till end of page"); return true; } @@ -135,43 +290,119 @@ public class VotingBoothToyConsoleUI implements UI, Runnable { throw new IOException (); } } - - - private void eraseEncryption () { - //TODO: should we clean memory 'stronger'? - if (m_encryptedBallot != null) { - m_encryptedBallot = null; - } - if (m_ballotSecrets != null) { - m_ballotSecrets = null; + + /* + * returns true if voting finished successfully + * false if cancelled in the middle + */ + private boolean listQuestionsToUserAndGetAnswers() throws IOException { + Voting.PlaintextBallot.Builder ptbb = Voting.PlaintextBallot.newBuilder(); + + ptbb.setSerialNumber(m_serialNumber); + + Voting.BallotAnswer answers[] = new Voting.BallotAnswer[a_questions.length]; + int index = 0; + while (index < a_questions.length) { + Voting.BallotQuestionNew q = a_questions[index]; + if (q.getIsMandatory()) { + throw new UnsupportedOperationException("listQuestionsToUserAndGetAnswers: question " + index + " is marked as mandatory"); + } + + showQuestionOnScreen(index, q); + System.out.println("UI screen: Enter your answer. You can also type '(b)ack' or '(c)ancel' or '(s)kip"); + String s = readInputLine(); + if (null == s) { + logger.error("listQuestionsToUserAndGetAnswers: got null as response"); + throw new IOException(""); + } + + if ((s.equals("cancel") || s.equals("c")) || (index == 0 && (s.equals("back") || s.equals("b")))) { + erasePlaintext(); + return false; + } else if (s.equals("back") || s.equals("b")) { + --index; + } else if (s.equals("skip") || s.equals("s")) { + answers[index] = translateStringAnswerToProtoBufMessageAnswer(""); + ++index; + } else { + answers[index] = translateStringAnswerToProtoBufMessageAnswer(s); + ++index; + } } + + ptbb.addAllAnswers(Arrays.asList(answers)); + m_plaintextBallot = ptbb.build(); + return true; } - private void erasePlaintext () { - //TODO: should we clean memory 'stronger'? - if (m_plaintextBallot != null) { - m_plaintextBallot = null; + + private Voting.BallotAnswer translateStringAnswerToProtoBufMessageAnswer(String s) { + Voting.BallotAnswer.Builder bab = Voting.BallotAnswer.newBuilder(); + StringTokenizer st = new StringTokenizer(s); + while (st.hasMoreTokens()) { + bab.addAnswer(Integer.parseInt(st.nextToken())); } + + return bab.build(); } - private void printBallotFlow () throws IOException{ - System.err.println("UI debug: printBallotFlow currently not multithreaded... will fix it..."); - - boolean ended = false; - while (!ended) { - sendBallotToControllerForEncryptionAndWaitForResponse (); - sendBallotToPrinterAndWaitToEnd(); - ended = castOrAudit(); - eraseEncryption(); + /* + * show question on the screen for the voter + */ + private void showQuestionOnScreen(int i, Voting.BallotQuestionNew q) { + + boolean isText = true; + + if (q.getQuestion().getType() != Voting.UIElementDataType.TEXT + || q.getDescription().getType() != Voting.UIElementDataType.TEXT) { + isText = false; } - erasePlaintext(); + + for (Voting.UIElement answer : q.getAnswerList()) { + if (answer.getType() != Voting.UIElementDataType.TEXT) { + isText = false; + } + } + + if (!isText) { + System.err.println("debug: an element in question " + i + " is not of TEXT type"); + throw new UnsupportedOperationException(); + } + + + System.out.println("UI screen: question number " + i); + + System.out.println("Question text: " + bytesToString(q.getQuestion().getData())); + System.out.println("Description: " + bytesToString(q.getDescription().getData())); + int answerIndex = 0; + for (Voting.UIElement answer : q.getAnswerList()) { + ++answerIndex; + System.out.println("Answer " + answerIndex + ": " + bytesToString(answer.getData())); + } + } - + + /* + * Returns the UTF8 decoding of byte-string data + */ + private static String bytesToString(ByteString data) { + return data.toStringUtf8(); + } + + + /* + * Registering the controller, so we have an object to send encryption queries to + */ + public void registerVBController(VotingBooth vb) { + m_vbController = vb; + } + + /* (non-Javadoc) - * @see meerkat.voting.VotingBooth.UI#commitToEncryptedBallot(meerkat.voting.EncryptedBallot) - */ + * @see meerkat.voting.VotingBooth.UI#commitToEncryptedBallot(meerkat.voting.EncryptedBallot) + */ @Override - public void commitToEncryptedBallot(EncryptedBallot encryptedBallot, BallotSecrets secrets) { + public void commitToEncryptedBallot(Voting.EncryptedBallot encryptedBallot, Voting.BallotSecrets secrets) { try { a_queue.put (VBMessage.newControllerResponse(encryptedBallot, secrets)); } @@ -181,165 +412,29 @@ public class VotingBoothToyConsoleUI implements UI, Runnable { } - - public void run () { - System.out.println("UI screen: Initializing the magic"); - - System.out.println("UI screen: press something to start the system"); - readInputLine(); - - while (true) { - votingBegin(); - } - } - - - - public void registerVBController (VotingBooth vb) - { - m_vbController = vb; - //m_sharedPlaintext = sharedPlaintext; - //m_sharedEncrypted = sharedEncrypted; - } - - /* - * returns true if voting finished successfully - * false if cancelled in the middle - */ - private boolean listQuestionsToUserAndGetAnswers() - { - PlaintextBallot.Builder ptbb = PlaintextBallot.newBuilder(); - - ptbb.setSerialNumber(m_serialNumber); - - int index = 0; - while (index < a_questions.length) { - BallotQuestionNew q = a_questions[index]; - if (q.getIsMandatory()) { - throw new UnsupportedOperationException("question " + index + " is marked as mandatory"); - } - - printQuestion(index, q); - System.out.println("UI screen: Enter your answer. You can also type 'back' or 'cancel'"); - String s = readInputLine(); - - if (s.equals("cancel") || (index == 0 && s.equals("back"))) { - erasePlaintext(); - return false; - } - - if (s.equals("back")) { - --index; - continue; - } - - if (s.equals("skip")) { - ++index; - continue; - } - - BallotAnswer answer = translateStringAnswerToProtoBufMessageAnswer (s); - ptbb.setAnswers(index, answer); - } - - m_plaintextBallot = ptbb.build(); - return true; - } - - - private String readInputLine () { - String s; - try { - s = this.m_in.readLine(); - } - catch (IOException e) { - System.err.println("UI debug: VotingBegin(): some error with reading input. " + e); - return null; - } - - return s; - } - - - private void printQuestion (int i, BallotQuestionNew q) { - - boolean isText = true; - - if (q.getQuestion().getType() != UIElementDataType.TEXT - || q.getDescription().getType() != UIElementDataType.TEXT) { - isText = false; - } - - for (UIElement answer : q.getAnswersList()) { - if (answer.getType() != UIElementDataType.TEXT) { - isText = false; - } - } - - if (!isText) { - System.err.println("debug: an element in question " + i + " is not of TEXT type"); - throw new UnsupportedOperationException(); - } - - - System.out.println("UI screen: question number " + i); - - System.out.println("Question text: " + bytesToString(q.getQuestion().getData())); - System.out.println("Description: " + bytesToString(q.getDescription().getData())); - int answerIndex = 0; - for (UIElement answer : q.getAnswersList()) { - ++answerIndex; - System.out.println("Answer " + answerIndex + ": " + bytesToString(answer.getData())); - } - - } - - private static String bytesToString (ByteString data) { - return data.toStringUtf8(); - } - - private BallotAnswer translateStringAnswerToProtoBufMessageAnswer (String s) { - BallotAnswer.Builder bab = BallotAnswer.newBuilder(); - StringTokenizer st = new StringTokenizer(s); - int index = 0; - while (st.hasMoreTokens()) { - ++index; - bab.setAnswer(index, Integer.parseInt(st.nextToken())); - } - - BallotAnswer ba = bab.build(); - return ba; - } - - public void tick () { - // adds a 'tick'. If queue is full, do nothing - a_queue.add (VBMessage.newTick()); - } - - private void sendBallotToControllerForEncryptionAndWaitForResponse () { - + class TickerTask extends TimerTask { private VotingBoothToyConsoleUI m_ui; public TickerTask (VotingBoothToyConsoleUI ui) { m_ui = ui; } - + @Override public void run() { - m_ui.tick(); - } + m_ui.tick(); + } } - + eraseEncryption(); System.out.println("UI screen: Please wait for encryption"); m_vbController.submitBallot(m_plaintextBallot); Timer timer = new Timer(); timer.scheduleAtFixedRate(new TickerTask(this), new Date(), m_waitForControllerMillisecTimeout); - + while (m_encryptedBallot == null) { - VBMessage msg = null; + VBMessage msg; try { msg = a_queue.take(); } @@ -358,10 +453,11 @@ public class VotingBoothToyConsoleUI implements UI, Runnable { } } } - - System.out.println("\nUI debug: Received EncryptedBallot"); + + logger.debug("sendBallotToControllerForEncryptionAndWaitForResponse: Received EncryptedBallot"); timer.cancel(); timer.purge(); - + } + } diff --git a/voting-booth/src/main/java/meerkat/voting/VotingBoothToyDemoRun.java b/voting-booth/src/main/java/meerkat/voting/VotingBoothToyDemoRun.java index d92dc06..6004199 100644 --- a/voting-booth/src/main/java/meerkat/voting/VotingBoothToyDemoRun.java +++ b/voting-booth/src/main/java/meerkat/voting/VotingBoothToyDemoRun.java @@ -5,8 +5,11 @@ import com.google.protobuf.ByteString; import meerkat.protobuf.Crypto.SignatureType; import meerkat.protobuf.Crypto.SignatureVerificationKey; import meerkat.protobuf.Voting.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class VotingBoothToyDemoRun { + final static Logger logger = LoggerFactory.getLogger(VotingBoothToyDemoRun.class); static int N_SIGNATURE_VERIFICATION_KEYS = 3; @@ -15,16 +18,19 @@ public class VotingBoothToyDemoRun { VotingBoothToy vbController = new VotingBoothToy (); VotingBoothToyConsoleUI ui = new VotingBoothToyConsoleUI(); + logger.debug("Running with {} args", args.length); vbController.registerUI (ui); ui.registerVBController(vbController); - + + BoothParams boothParams = generateDemoBoothParams(); ElectionParams electionParams = generateDemoElectionParams(); vbController.init(electionParams, boothParams); + ui.init(electionParams); - Thread controllerThread = new Thread(new VotingBoothToy ()); + Thread controllerThread = new Thread(vbController); Thread uiThread = new Thread(ui); controllerThread.start(); @@ -66,7 +72,7 @@ public class VotingBoothToyDemoRun { .setType(UIElementDataType.TEXT) .setData(stringToBytes(answerStr)) .build(); - bqb.addAnswers(answer); + bqb.addAnswer(answer); } return bqb.build(); @@ -90,9 +96,9 @@ public class VotingBoothToyDemoRun { ElectionParams.Builder epb = ElectionParams.newBuilder(); epb.setTrusteeSignatureThreshold(5); - epb.setQuestions(0, question1); - epb.setQuestions(1, question2); - epb.setQuestions(2, question3); + epb.addQuestion(question1); + epb.addQuestion(question2); + epb.addQuestion(question3); return epb.build(); }