package ch.ge.ve.commons.crypto.ballot;
/*-
* #%L
* Common crypto utilities
* %%
* Copyright (C) 2015 - 2016 République et Canton de Genève
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/**
* <p>
* This class holds an encrypted ballot as it is stored in the database.
* </p>
* <h2>Usage</h2>
* <h3>Goal</h3>
* <p>
* This is the second layer of encryption for the ballot. The already encrypted ballot is encrypted a second time, with
* the integrity key (a new one is generated for each test / real operation).
* </p>
* <p>
* An encryption scheme compatible with AEAD is used, so that the ballot index can be associated to the already
* encrypted ballot contents, in order to prevent vote replacement by copying an existing (and known) vote multiple
* times (the unicity and sequence of ballot indices is verified upon opening the ballot box).
* </p>
* <h3>Encryption</h3>
* <p>
* When encrypting a ballot, the instance of AuthenticatedBallot that will be stored in the database must be build as
* follows:
* <ul>
* <li>the {@link #wrappedKey} field is retrieved from the {@link ch.ge.ve.commons.crypto.ballot.EncryptedBallotAndWrappedKey#wrappedKey} field</li>
* <li>the {@link #ballotIndex} field is provided as the number of ballots in the ballot box + 1</li>
* <li>the {@link #authenticatedEncryptedBallot} field is build by encrypting the
* {@link ch.ge.ve.commons.crypto.ballot.EncryptedBallotAndWrappedKey#encryptedBallot} with the integrity key, with
* the ballotIndex as associated data</li>
* <li>the {@link #tag} field contains the tag of the authenticated encryption performed above</li>
* </ul>
* </p>
* <h3>Decryption</h3>
* <p>
* When decrypting a ballot, fields can simply be read from the database.
* </p>
* <p>
* For security purposes, the following actions must be undertaken:
* <ul>
* <li>once all <tt>AuthenticatedBallot</tt>s have been read, the unicity and sequence of ballot indices must be verified</li>
* <li>the number of retrieved ballots matches the expected number of ballots</li>
* <li>upon decrypting this layer of encryption, all authentication tags must match the recorded tags</li>
* <li>before the Electoral Officers' private key is inserted into the system, all references to the
* <tt>AuthenticatedBallot</tt>s must be dropped and garbage collected, in order to prevent linking of a decrypted vote
* to a voter (through the ballot index)</li>
* </ul>
* </p>
*/
public class AuthenticatedBallot {
/**
* the random key k_i, wrapped with the Electoral Officers public key
*/
private final byte[] wrappedKey;
/**
* the doubly encrypted ballot (once with key k_i, once with the integrity key, with the ballot index as associated data)
*/
private final byte[] authenticatedEncryptedBallot;
/**
* the ballot index (by order of insertion)
*/
private final int ballotIndex;
/**
* the tag produced by the second layer of authenticated encryption
*/
private final byte[] tag;
/**
* @param wrappedKey the random key k_i, wrapped with the Electoral Officers public key
* @param authenticatedEncryptedBallot the doubly encrypted ballot (once with key k_i, once with the integrity key, with the ballot index as associated data)
* @param ballotIndex the ballot index (by order of insertion)
* @param tag the tag produced by the second layer of authenticated encryption
*/
public AuthenticatedBallot(byte[] wrappedKey, byte[] authenticatedEncryptedBallot, int ballotIndex, byte[] tag) {
this.wrappedKey = wrappedKey;
this.authenticatedEncryptedBallot = authenticatedEncryptedBallot;
this.ballotIndex = ballotIndex;
this.tag = tag;
}
/** *
* @return the wrappedKey
*/
public byte[] getWrappedKey() {
return wrappedKey;
}
/**
* @return the authenticatedEncryptedBallot
*/
public byte[] getAuthenticatedEncryptedBallot() {
return authenticatedEncryptedBallot;
}
/**
* @return the ballotIndex
*/
public int getBallotIndex() {
return ballotIndex;
}
/**
* @return the authentication tag
*/
public byte[] getTag() {
return tag;
}
}