use of com.github.dedis.popstellar.model.objects.security.PublicKey in project popstellar by dedis.
the class ElectionHandler method handleCastVote.
/**
* Process a CastVote message.
*
* @param context the HandlerContext of the message
* @param castVote the message that was received
*/
public static void handleCastVote(HandlerContext context, CastVote castVote) {
LAORepository laoRepository = context.getLaoRepository();
Channel channel = context.getChannel();
MessageID messageId = context.getMessageId();
PublicKey senderPk = context.getSenderPk();
Log.d(TAG, "handleCastVote: channel " + channel);
Lao lao = laoRepository.getLaoByChannel(channel);
Election election = laoRepository.getElectionByChannel(channel);
// Verify the vote was created before the end of the election or the election is not closed yet
if (election.getEndTimestamp() >= castVote.getCreation() || election.getState() != CLOSED) {
// Retrieve previous cast vote message stored for the given sender
Optional<MessageID> previousMessageIdOption = election.getMessageMap().entrySet().stream().filter(entry -> senderPk.equals(entry.getValue())).map(Map.Entry::getKey).findFirst();
// Retrieve the creation time of the previous cast vote, if doesn't exist replace with min
// value
long previousMessageCreation = previousMessageIdOption.map(s -> laoRepository.getMessageById().get(s)).map(MessageGeneral::getData).map(CastVote.class::cast).map(CastVote::getCreation).orElse(Long.MIN_VALUE);
// Verify the current cast vote message is the last one received
if (previousMessageCreation <= castVote.getCreation()) {
election.putVotesBySender(senderPk, castVote.getVotes());
election.putSenderByMessageId(senderPk, messageId);
lao.updateElection(election.getId(), election);
}
}
}
use of com.github.dedis.popstellar.model.objects.security.PublicKey in project popstellar by dedis.
the class LaoHandler method handleStateLao.
/**
* Process a StateLao message.
*
* @param context the HandlerContext of the message
* @param stateLao the message that was received
*/
public static void handleStateLao(HandlerContext context, StateLao stateLao) throws DataHandlingException {
LAORepository laoRepository = context.getLaoRepository();
Channel channel = context.getChannel();
Log.d(TAG, "Receive State Lao Broadcast msg=" + stateLao);
Lao lao = laoRepository.getLaoByChannel(channel);
Log.d(TAG, "Receive State Lao Broadcast " + stateLao.getName());
if (!laoRepository.getMessageById().containsKey(stateLao.getModificationId())) {
Log.d(TAG, "Can't find modification id : " + stateLao.getModificationId());
// queue it if we haven't received the update message yet
throw new InvalidMessageIdException(stateLao, stateLao.getModificationId());
}
Log.d(TAG, "Verifying signatures");
for (PublicKeySignaturePair pair : stateLao.getModificationSignatures()) {
if (!pair.getWitness().verify(pair.getSignature(), stateLao.getModificationId())) {
throw new InvalidSignatureException(stateLao, pair.getSignature());
}
}
Log.d(TAG, "Success to verify state lao signatures");
// TODO: verify if lao/state_lao is consistent with the lao/update message
lao.setId(stateLao.getId());
lao.setWitnesses(stateLao.getWitnesses());
lao.setName(stateLao.getName());
lao.setLastModified(stateLao.getLastModified());
lao.setModificationId(stateLao.getModificationId());
PublicKey publicKey = context.getKeyManager().getMainPublicKey();
if (lao.getOrganizer().equals(publicKey) || lao.getWitnesses().contains(publicKey)) {
context.getMessageSender().subscribe(lao.getChannel().subChannel("consensus")).subscribe();
}
// Now we're going to remove all pending updates which came prior to this state lao
long targetTime = stateLao.getLastModified();
lao.getPendingUpdates().removeIf(pendingUpdate -> pendingUpdate.getModificationTime() <= targetTime);
laoRepository.updateNodes(channel);
}
use of com.github.dedis.popstellar.model.objects.security.PublicKey in project popstellar by dedis.
the class KeyManager method getPublicKey.
private PublicKey getPublicKey(KeysetHandle keysetHandle) throws GeneralSecurityException, IOException {
// Retrieve the public key from the keyset. This is not an easy task and thanks to this post :
// https://stackoverflow.com/questions/53228475/google-tink-how-use-public-key-to-verify-signature
// A solution was found
ByteArrayOutputStream publicKeysetStream = new ByteArrayOutputStream();
CleartextKeysetHandle.write(keysetHandle.getPublicKeysetHandle(), JsonKeysetWriter.withOutputStream(publicKeysetStream));
// The "publickey" is still a json data. We need to extract the actual key from it
JsonElement publicKeyJson = JsonParser.parseString(publicKeysetStream.toString());
JsonObject root = publicKeyJson.getAsJsonObject();
JsonArray keyArray = root.get("key").getAsJsonArray();
JsonObject keyObject = keyArray.get(0).getAsJsonObject();
JsonObject keyData = keyObject.get("keyData").getAsJsonObject();
byte[] buffer = Base64.getDecoder().decode(keyData.get("value").getAsString());
// Remove the first two bytes of the buffer as they are not part of the key
byte[] publicKey = Arrays.copyOfRange(buffer, 2, buffer.length);
return new PublicKey(publicKey);
}
use of com.github.dedis.popstellar.model.objects.security.PublicKey in project popstellar by dedis.
the class ConsensusHandler method handleElectAccept.
public static void handleElectAccept(HandlerContext context, ConsensusElectAccept consensusElectAccept) throws DataHandlingException {
LAORepository laoRepository = context.getLaoRepository();
Channel channel = context.getChannel();
MessageID messageId = context.getMessageId();
PublicKey senderPk = context.getSenderPk();
Lao lao = laoRepository.getLaoByChannel(channel);
Optional<ElectInstance> electInstanceOpt = lao.getElectInstance(consensusElectAccept.getMessageId());
if (!electInstanceOpt.isPresent()) {
Log.w(TAG, "elect_accept for invalid messageId : " + consensusElectAccept.getMessageId());
throw new InvalidMessageIdException(consensusElectAccept, consensusElectAccept.getMessageId());
}
ElectInstance electInstance = electInstanceOpt.get();
electInstance.addElectAccept(senderPk, messageId, consensusElectAccept);
lao.updateElectInstance(electInstance);
laoRepository.updateNodes(lao.getChannel());
}
use of com.github.dedis.popstellar.model.objects.security.PublicKey in project popstellar by dedis.
the class StateLaoTest method isEqualTest.
@Test
public void isEqualTest() {
assertEquals(stateLao, new StateLao(id, name, creation, lastModified, organizer, modificationId, witnesses, modificationSignatures));
// The modification id isn't taken into account to know if they are equal
assertEquals(stateLao, new StateLao(id, name, creation, lastModified, organizer, Base64DataUtils.generateMessageIDOtherThan(modificationId), witnesses, modificationSignatures));
// same goes for modification signatures
assertEquals(stateLao, new StateLao(id, name, creation, lastModified, organizer, modificationId, witnesses, null));
String random = " random string";
String newId = Lao.generateLaoId(organizer, creation, random);
assertNotEquals(stateLao, new StateLao(newId, random, creation, lastModified, organizer, modificationId, witnesses, modificationSignatures));
PublicKey newKey = Base64DataUtils.generatePublicKeyOtherThan(organizer);
newId = Lao.generateLaoId(newKey, creation, name);
assertNotEquals(stateLao, new StateLao(newId, name, creation, lastModified, newKey, modificationId, witnesses, modificationSignatures));
newId = Lao.generateLaoId(organizer, 99, name);
assertNotEquals(stateLao, new StateLao(newId, name, 99, lastModified, organizer, modificationId, witnesses, modificationSignatures));
assertNotEquals(stateLao, new StateLao(id, name, creation, 1000, organizer, modificationId, witnesses, modificationSignatures));
assertNotEquals(stateLao, new StateLao(id, name, creation, lastModified, organizer, modificationId, Sets.newSet(generatePublicKey()), modificationSignatures));
}
Aggregations