public void MyTestInitialize() { this.storage = new CertificateStorage(); this.root = new CACertificate(null, "Root"); this.root.CreateSelfSignature(); this.storage.AddRoot(this.root.OnlyPublicPart); var rootCrl = new RevocationList(this.root.Id, DateTime.Now, DateTime.Now.AddDays(1), new Guid[] { }); var signedRootCrl = new Signed<RevocationList>(rootCrl, this.root); this.storage.AddRevocationList(signedRootCrl); this.intermediate = new CACertificate(null, "Intermediate"); this.intermediate.CreateSelfSignature(); this.intermediate.AddSignature(this.root, DateTime.Now.AddDays(1)); this.storage.Add(intermediate.OnlyPublicPart); var intermediateCrl = new RevocationList(this.intermediate.Id, DateTime.Now, DateTime.Now.AddDays(1), new Guid[] { }); var signedIntermediateCrl = new Signed<RevocationList>(intermediateCrl, this.intermediate); this.storage.AddRevocationList(signedIntermediateCrl); this.admin = new AdminCertificate(Language.English, null, "Test"); this.admin.CreateSelfSignature(); this.admin.AddSignature(this.intermediate, DateTime.Now.AddDays(1)); this.eve = new AdminCertificate(Language.English, null, "Eve"); this.eve.CreateSelfSignature(); this.eve.AddSignature(this.intermediate, DateTime.Now.AddDays(1)); }
/// <summary> /// Pushes the enveope containing the vota from this voter. /// </summary> /// <param name="votingId">Id of the voting.</param> /// <param name="signedEnvelope">Signed envelope.</param> /// <returns>Vote receipt signed by the server.</returns> public Signed<VoteReceipt> PushEnvelope(Guid votingId, Signed<Envelope> signedEnvelope) { var request = new PushEnvelopeRequest(Guid.NewGuid(), votingId, signedEnvelope); var response = Execute<PushEnvelopeResponse>(request); return response.VoteReceipt; }
public void ChainTest() { CertificateStorage storage = new CertificateStorage(); CACertificate root = new CACertificate(null, "Root"); root.CreateSelfSignature(); Assert.AreEqual(CertificateValidationResult.NoSignature, root.Validate(storage)); storage.AddRoot(root.OnlyPublicPart); Assert.AreEqual(CertificateValidationResult.Valid, root.Validate(storage)); var rootCrl = new RevocationList(root.Id, DateTime.Now, DateTime.Now.AddDays(1), new Guid[]{}); var signedRootCrl = new Signed<RevocationList>(rootCrl, root); storage.AddRevocationList(signedRootCrl); CACertificate intermediate = new CACertificate(null, "Intermediate"); intermediate.CreateSelfSignature(); Assert.AreEqual(CertificateValidationResult.NoSignature, intermediate.Validate(storage)); intermediate.AddSignature(root, DateTime.Now.AddDays(1)); storage.Add(intermediate.OnlyPublicPart); Assert.AreEqual(CertificateValidationResult.Valid, intermediate.Validate(storage)); var intermediateCrl = new RevocationList(intermediate.Id, DateTime.Now, DateTime.Now.AddDays(1), new Guid[] { }); var signedIntermediateCrl = new Signed<RevocationList>(intermediateCrl, intermediate); storage.AddRevocationList(signedIntermediateCrl); AdminCertificate test = new AdminCertificate(Language.English, null, "Test"); test.CreateSelfSignature(); Assert.AreEqual(CertificateValidationResult.NoSignature, test.Validate(storage)); test.AddSignature(intermediate, DateTime.Now.AddDays(1)); Assert.AreEqual(CertificateValidationResult.Valid, test.Validate(storage)); }
public FetchSignCheckCookieResponse( Guid requestId, Signed<SignCheckCookie> cookie) : base(requestId) { Cookie = cookie; }
public SignatureRequestSignCheck( Certificate certificate, Signed<SignCheckCookie> cookie) { Cookie = cookie; Certificate = certificate; SignDateTime = DateTime.Now; }
public BadShareProof(int complainingAuthorityIndex, CertificateStorage certificateStorage, Signed<VotingParameters> signedParameters, AllShareParts allShareParts, IDictionary<int, TrapDoor> trapDoors, IDictionary<int, Certificate> authorities) { ComplainingAuthorityIndex = complainingAuthorityIndex; CertificateStorage = certificateStorage; SignedParameters = signedParameters; AllShareParts = allShareParts; TrapDoors = new Dictionary<int, TrapDoor>(trapDoors); Authorities = new Dictionary<int, Certificate>(authorities); }
/// <summary> /// Add a vote to the sum of votes. /// </summary> /// <param name="envelopeIndex">Index of the envelope.</param> /// <param name="signedEnvelope">Signed envelope containing the vote.</param> /// <param name="progress">Reports progress of the tallying.</param> public void TallyAdd(int envelopeIndex, Signed<Envelope> signedEnvelope, Progress progress) { if (signedEnvelope == null) throw new ArgumentNullException("signedEnvelope"); if (progress == null) throw new ArgumentNullException("progress"); this.tally.Add(envelopeIndex, signedEnvelope, progress); }
/// <summary> /// Create a new voting procedure. /// </summary> /// <param name="logger">Logs messages to file.</param> /// <param name="DataAccess.DbConnection">Connection to the database.</param> /// <param name="parameters">Voting parameters.</param> /// <param name="rootCertificate">Certificate storage.</param> public VotingServerEntity( VotingRpcServer server, Signed<VotingParameters> signedParameters, ICertificateStorage certificateStorage, ServerCertificate serverCertificate) : this(server, signedParameters, certificateStorage, serverCertificate, VotingStatus.New) { this.lastProcessTime = DateTime.Now; }
/// <summary> /// Create a new response to shares. /// </summary> /// <param name="votingId">Id of the voting procedure.</param> /// <param name="authorityIndex">Index of the issuing authority.</param> /// <param name="acceptShares">Does the authority accept all the shares?</param> /// <param name="publicKeyPart">Public key part from that authority.</param> /// <param name="signedVotingParameters">Signed voting parameters.</param> public ShareResponse(Guid votingId, int authorityIndex, bool acceptShares, BigInt publicKeyPart, Signed<VotingParameters> signedVotingParameters) { if (publicKeyPart == null) throw new ArgumentNullException("publicKeyPart"); VotingId = votingId; AuthorityIndex = authorityIndex; AcceptShares = acceptShares; PublicKeyPart = publicKeyPart; byte[] votingParametersData = signedVotingParameters.ToBinary(); SHA256Managed sha256 = new SHA256Managed(); VotingParametersHash = sha256.ComputeHash(votingParametersData); }
/// <summary> /// Creates a new vote receipt. /// </summary> /// <param name="parameters">Voting parameters.</param> /// <param name="signedEnvelope">Signed envelope.</param> public VoteReceipt(VotingParameters parameters, Signed<Envelope> signedEnvelope) { if (signedEnvelope.Value.VotingId != parameters.VotingId) throw new InvalidOperationException("Wrong parameters for envelope."); if (signedEnvelope.Value.VoterId != signedEnvelope.Certificate.Id) throw new InvalidOperationException("Inconsistent envelope."); VotingId = parameters.VotingId; VotingTitle = parameters.Title; VoterId = signedEnvelope.Certificate.Id; SHA256Managed sha256 = new SHA256Managed(); byte[] signedEnvelopeData = signedEnvelope.ToBinary(); SignedEnvelopeHash = sha256.ComputeHash(signedEnvelopeData); }
/// <summary> /// Createa new voting material. /// </summary> /// <param name="parameters">Voting parameters.</param> /// <param name="publicKeyParts">Parts of the public key form authorities.</param> /// <param name="revocationLists">Certification revocation lists for CAs.</param> /// <param name="certificates">List of intermediate certificates.</param> public VotingMaterial( Signed<VotingParameters> parameters, IEnumerable<Signed<ShareResponse>> publicKeyParts, int castEnvelopeCount) { if (parameters == null) throw new ArgumentNullException("parameters"); if (publicKeyParts == null) throw new ArgumentNullException("publicKeyParts"); Parameters = parameters; PublicKeyParts = new List<Signed<ShareResponse>>(publicKeyParts); CastEnvelopeCount = castEnvelopeCount; }
public void SignedDontVerifyTest() { Option option = new Option(new MultiLanguageString("Test"), new MultiLanguageString(string.Empty), new MultiLanguageString(string.Empty)); Signed<Option> signed = new Signed<Option>(option, this.admin); Assert.IsTrue(signed.VerifySimple()); Assert.IsFalse(signed.Verify(this.storage, DateTime.Now.AddYears(5))); byte[] data = signed.ToBinary(); data[data.Length / 8]++; Signed<Option> badSigned = Serializable.FromBinary<Signed<Option>>(data); Assert.IsFalse(badSigned.VerifySimple()); Assert.IsFalse(badSigned.Verify(this.storage)); }
private void createSaveProofButon_Click(object sender, EventArgs e) { if (DecryptPrivateKeyDialog.TryDecryptIfNessecary(this.certificate, "Sign Certificate Proof")) { var proof = new CertificateProof(this.createProofTextTextBox.Text); var signedProof = new Signed<CertificateProof>(proof, this.certificate); SaveFileDialog dialog = new SaveFileDialog(); dialog.Filter = ProofFileFilter; dialog.Title = "Save Certificate Proof"; if (dialog.ShowDialog() == DialogResult.OK) { signedProof.Save(dialog.FileName); } } }
/// <summary> /// Generates a sign check. /// </summary> /// <param name="signedCookie">Signed sign check cookie.</param> /// <param name="callBack">Callback upon completion.</param> public void GenerateSignCheck(Signed<SignCheckCookie> signedCookie, GenerateSignCheckCallBack callBack) { lock (this.operations) { this.operations.Enqueue(new GenerateSignCheckOperation(signedCookie, callBack)); } }
/// <summary> /// Set a certificate storage on the server. /// </summary> /// <param name="comand">Command to delete a voting.</param> /// <param name="callBack">Callback upon completion.</param> public void DeleteVoting(Signed<DeleteVotingRequest.Command> comand, DeleteVotingCallBack callBack) { lock (this.operations) { this.operations.Enqueue(new DeleteVotingOperation(comand, callBack)); } }
/// <summary> /// Create a voting procedure. /// </summary> /// <param name="votingParameters">Parameters of voting procedure.</param> /// <param name="authorities">Authorities overseeing the voting procedure.</param> /// <param name="callBack">Callback upon completion.</param> public void CreateVoting(Signed<VotingParameters> votingParameters, IEnumerable<AuthorityCertificate> authorities, CreateVotingCallBack callBack) { lock (this.operations) { this.operations.Enqueue(new CreateVotingOperation(votingParameters, authorities, callBack)); } }
/// <summary> /// Creates a new voting. /// </summary> /// <param name="votingParameters">Parameters for the voting.</param> /// <param name="authorities">List of authorities to oversee the voting.</param> public void CreateVoting( IRpcConnection connection, Signed<VotingParameters> signedVotingParameters, IEnumerable<AuthorityCertificate> authorities) { if (signedVotingParameters == null) throw new PiArgumentException(ExceptionCode.ArgumentNull, "Voting parameters cannot be null."); if (authorities == null) throw new PiArgumentException(ExceptionCode.ArgumentNull, "Authority list cannot be null."); VotingParameters votingParameters = signedVotingParameters.Value; if (!signedVotingParameters.Verify(CertificateStorage, votingParameters.VotingBeginDate)) { if (!signedVotingParameters.VerifySimple()) { Logger.Log(LogLevel.Warning, "Connection {0}: Admin {1} (unverified) tried to create voting {2} title {3} but the signature was wrong.", connection.Id, signedVotingParameters.Certificate.Id.ToString(), votingParameters.VotingId.ToString(), votingParameters.Title.Text); } else if (signedVotingParameters.Certificate.Validate(CertificateStorage, votingParameters.VotingBeginDate) != CertificateValidationResult.Valid) { Logger.Log(LogLevel.Warning, "Connection {0}: Admin {1} (unverified) tried to create voting {2} title {3} but his certificate status was {4}.", connection.Id, signedVotingParameters.Certificate.Id.ToString(), votingParameters.VotingId.ToString(), votingParameters.Title.Text, signedVotingParameters.Certificate.Validate(CertificateStorage, votingParameters.VotingBeginDate).ToString()); } else { Logger.Log(LogLevel.Warning, "Connection {0}: Admin {1} (unverified) tried to create voting {2} title {3} but his signature was invalid.", connection.Id, signedVotingParameters.Certificate.Id.ToString(), votingParameters.VotingId.ToString(), votingParameters.Title.Text); } throw new PiSecurityException(ExceptionCode.InvalidSignature, "Invalid signature of voting authority."); } if (!(signedVotingParameters.Certificate is AdminCertificate)) { Logger.Log(LogLevel.Warning, "Connection {0}: Admin {1} (verified) tried to create voting {2} title {3} but he is a {4}.", connection.Id, signedVotingParameters.Certificate.Id.ToString(), votingParameters.VotingId.ToString(), votingParameters.Title.Text, signedVotingParameters.Certificate.TypeText); throw new PiSecurityException(ExceptionCode.NoAuthorizedAdmin, "No authorized admin."); } if (!CertificateStorage.SignedRevocationLists .Any(signedCrl => signedCrl.Verify(CertificateStorage) && votingParameters.VotingBeginDate >= signedCrl.Value.ValidFrom && votingParameters.VotingBeginDate <= signedCrl.Value.ValidUntil)) { Logger.Log(LogLevel.Info, "Connection {0}: Admin id {1} name {2} tried to create voting {3} title {4} but the voting begin date {5} was not covered by any CRL.", connection.Id, signedVotingParameters.Certificate.Id.ToString(), ((AdminCertificate)signedVotingParameters.Certificate).FullName, votingParameters.VotingId.ToString(), votingParameters.Title.Text, votingParameters.VotingBeginDate.ToString()); throw new PiSecurityException(ExceptionCode.InvalidSignature, "Voting begin date not covered by CRL."); } if (votingParameters.P == null) throw new PiArgumentException(ExceptionCode.ArgumentNull, "P cannot be null."); if (votingParameters.Q == null) throw new PiArgumentException(ExceptionCode.ArgumentNull, "Q cannot be null."); if (votingParameters.F == null) throw new PiArgumentException(ExceptionCode.ArgumentNull, "F cannot be null."); if (votingParameters.G == null) throw new PiArgumentException(ExceptionCode.ArgumentNull, "G cannot be null."); if (!Prime.HasSufficientLength(votingParameters.P, BaseParameters.PrimeBits)) throw new PiException(ExceptionCode.ArgumentNull, "P is not long enough"); if (!Prime.HasSufficientLength(votingParameters.Q, BaseParameters.PrimeBits)) throw new PiException(ExceptionCode.ArgumentNull, "Q is not long enough"); if (!Prime.IsPrimeUnsure(votingParameters.P)) throw new PiArgumentException(ExceptionCode.PIsNoPrime, "P is not prime."); if (!Prime.IsPrimeUnsure((votingParameters.P - 1) / 2)) throw new PiArgumentException(ExceptionCode.PIsNoSafePrime, "P is no safe prime."); if (!Prime.IsPrimeUnsure(votingParameters.Q)) throw new PiArgumentException(ExceptionCode.QIsNoPrime, "Q is not prime."); if (!votingParameters.AuthorityCount.InRange(3, 23)) throw new PiArgumentException(ExceptionCode.AuthorityCountOutOfRange, "Authority count out of range."); if (!votingParameters.Thereshold.InRange(1, votingParameters.AuthorityCount - 1)) throw new PiArgumentException(ExceptionCode.TheresholdOutOfRange, "Thereshold out of range."); foreach (Question question in votingParameters.Questions) { if (question.Options.Count() < 2) throw new PiArgumentException(ExceptionCode.OptionCountOutOfRange, "Option count out of range."); if (!question.MaxVota.InRange(1, question.Options.Count())) throw new PiArgumentException(ExceptionCode.MaxVotaOutOfRange, "Maximum vota out of range."); } if (votingParameters.AuthorityCount != authorities.Count()) throw new PiArgumentException(ExceptionCode.AuthorityCountMismatch, "Authority count does not match number of provided authorities."); if (!authorities.All(authority => authority.Validate(CertificateStorage, votingParameters.VotingBeginDate) == CertificateValidationResult.Valid)) throw new PiArgumentException(ExceptionCode.AuthorityInvalid, "Authority certificate invalid or not recognized."); MySqlCommand insertCommand = new MySqlCommand("INSERT INTO voting (Id, Parameters, Status) VALUES (@Id, @Parameters, @Status)", DbConnection); insertCommand.Parameters.AddWithValue("@Id", votingParameters.VotingId.ToByteArray()); insertCommand.Parameters.AddWithValue("@Parameters", signedVotingParameters.ToBinary()); insertCommand.Parameters.AddWithValue("@Status", (int)VotingStatus.New); insertCommand.ExecuteNonQuery(); Logger.Log(LogLevel.Info, "Connection {0}: Voting id {1} title {2} is created.", connection.Id, votingParameters.VotingId.ToString(), votingParameters.Title.Text); VotingServerEntity voting = new VotingServerEntity(this, signedVotingParameters, CertificateStorage, this.serverCertificate); authorities.Foreach(authority => voting.AddAuthority(connection, authority)); this.votings.Add(voting.Id, voting); voting.SendAuthorityActionRequiredMail(MailType.AuthorityCreateSharesGreen); }
public byte[] SetSignCheckCookie( IRpcConnection connection, Signed<SignCheckCookie> signedCookie) { if (!signedCookie.Verify(CertificateStorage)) { if (signedCookie.VerifySimple()) { Logger.Log(LogLevel.Warning, "Connection {0}: Notary id {1} (unverified) tried to set his sign check cookie, but his certificate status was {2}.", connection.Id, signedCookie.Certificate.Id.ToString(), signedCookie.Certificate.Validate(CertificateStorage).Text()); } else { Logger.Log(LogLevel.Warning, "Connection {0}: Notary id {1} (unverified) tried to set his sign check cookie, but the signature was invalid.", connection.Id, signedCookie.Certificate.Id.ToString()); } throw new PiSecurityException(ExceptionCode.InvalidSignature, "Invalid signature."); } if (!(signedCookie.Certificate is AuthorityCertificate || signedCookie.Certificate is NotaryCertificate)) { Logger.Log(LogLevel.Warning, "Connection {0}: Notary id {0} (verified) tried to set his sign check cookie, but he is no authority or notary.", connection.Id, signedCookie.Certificate.Id.ToString()); throw new PiSecurityException(ExceptionCode.SignCheckCookieNotFromNotary, "Not from proper authority or notary."); } this.DbConnection.ExecuteNonQuery( "DELETE FROM signcheckcookie WHERE NotaryId = @NotaryId", "@NotaryId", signedCookie.Certificate.Id.ToByteArray()); var rng = RandomNumberGenerator.Create(); byte[] code = new byte[32]; rng.GetBytes(code); byte[] encryptedCode = signedCookie.Certificate.Encrypt(code); MySqlCommand insertCommand = new MySqlCommand( "INSERT INTO signcheckcookie (NotaryId, Cookie, Code, Expires) VALUES (@NotaryId, @Cookie, @Code, @Expires)", this.DbConnection); insertCommand.Parameters.AddWithValue("@NotaryId", signedCookie.Certificate.Id.ToByteArray()); insertCommand.Parameters.AddWithValue("@Cookie", signedCookie.ToBinary()); insertCommand.Parameters.AddWithValue("@Code", code); insertCommand.Parameters.AddWithValue("@Expires", DateTime.Now.AddMinutes(15).ToString("yyyy-MM-dd HH:mm:ss")); insertCommand.ExecuteNonQuery(); Logger.Log(LogLevel.Info, "Connection {0}: Notary id {1} (verified) has set his sign check cookie with code {2}.", connection.Id, signedCookie.Certificate.Id.ToString(), code.ToHexString()); return encryptedCode; }
public FetchSignatureResponseResponse(Guid requestId, SignatureResponseStatus status, Signed<SignatureResponse> signatureResponse) : base(requestId) { Status = status; SignatureResponse = signatureResponse; }
public PushEnvelopeResponse(Guid requestId, Signed<VoteReceipt> voteReceipt) : base(requestId) { VoteReceipt = voteReceipt; }
/// <summary> /// Add a partial decipher for deciphering the sum of votes. /// </summary> /// <param name="signedPartialDecipherList">List of partial deciphers.</param> public void TallyAddPartialDecipher(Signed<PartialDecipherList> signedPartialDecipherList) { this.tally.AddPartialDecipher(signedPartialDecipherList); }
/// <summary> /// Deposit a ballot. /// </summary> /// <param name="ballot">Ballot in signed envleope.</param> /// <returns>Vote receipt signed by the server.</returns> public Signed<VoteReceipt> Vote( IRpcConnection connection, Signed<Envelope> signedEnvelope) { if (signedEnvelope == null) throw new ArgumentNullException("ballot"); if (Status != VotingStatus.Voting) { Logger.Log(LogLevel.Warning, "Connection {0}: Voter id {1} (unverified) tried to vote, but status was {2}.", connection.Id, signedEnvelope.Certificate.Id.ToString(), Status.ToString()); throw new PiArgumentException(ExceptionCode.WrongStatusForOperation, "Wrong status for operation."); } if (!signedEnvelope.Verify(this.certificateStorage)) { if (signedEnvelope.VerifySimple()) { Logger.Log(LogLevel.Warning, "Connection {0}: Voter id {1} (unverified) tried to vote, but his certificate had state {2}.", connection.Id, signedEnvelope.Certificate.Id.ToString(), signedEnvelope.Certificate.Validate(this.certificateStorage).Text()); } else { Logger.Log(LogLevel.Warning, "Connection {0}: Voter id {1} (unverified) tried to vote, but the signature on envelope was invalid.", connection.Id, signedEnvelope.Certificate.Id.ToString()); } throw new PiArgumentException(ExceptionCode.VoteSignatureNotValid, "Vote signature not valid."); } if (!(signedEnvelope.Certificate is VoterCertificate)) { Logger.Log(LogLevel.Warning, "Connection {0}: Voter id {1} (verified) tried to vote, but his certificate was not a voter certificate.", connection.Id, signedEnvelope.Certificate.Id.ToString()); throw new PiArgumentException(ExceptionCode.NoVoterCertificate, "Not a voter certificate."); } if (Parameters.GroupId != ((VoterCertificate)signedEnvelope.Certificate).GroupId) { Logger.Log(LogLevel.Warning, "Connection {0}: Voter id {1} (verified) tried to vote, but his group id was {2} when it should have been {3}.", connection.Id, signedEnvelope.Certificate.Id.ToString(), ((VoterCertificate)signedEnvelope.Certificate).GroupId, Parameters.GroupId); throw new PiArgumentException(ExceptionCode.BadGroupIdInCertificate, "Wrong group id in certificate."); } var envelope = signedEnvelope.Value; if (envelope.Date.Subtract(DateTime.Now).TotalHours < -1d || envelope.Date.Subtract(DateTime.Now).TotalHours > 1d) { Logger.Log(LogLevel.Warning, "Connection {0}: Voter id {1} (verified) tried to vote, but the envelope was created at {2} and pushed at {3}.", connection.Id, signedEnvelope.Certificate.Id.ToString(), envelope.Date.ToString(), DateTime.Now.ToString()); throw new PiArgumentException(ExceptionCode.InvalidEnvelopeBadDateTime, "Invalid envelope. Date out of range."); } if (envelope.VoterId != signedEnvelope.Certificate.Id) { Logger.Log(LogLevel.Warning, "Connection {0}: Voter id {1} (verified) tried to vote, but the envelope voter id did not match his certificate.", connection.Id, signedEnvelope.Certificate.Id.ToString()); throw new PiArgumentException(ExceptionCode.InvalidEnvelopeBadVoterId, "Invalid envelope. Voter id does not match."); } if (envelope.Ballots.Count != Parameters.Questions.Count()) { Logger.Log(LogLevel.Warning, "Connection {0}: Voter id {1} (verified) tried to vote, but there were {2} ballots in the envelope for {3} questions.", connection.Id, signedEnvelope.Certificate.Id.ToString(), envelope.Ballots.Count, Parameters.Questions.Count()); throw new PiArgumentException(ExceptionCode.InvalidEnvelopeBadBallotCount, "Invalid envelope. Ballot count does not match."); } for (int questionIndex = 0; questionIndex < parameters.Questions.Count(); questionIndex++) { var ballot = envelope.Ballots[questionIndex]; var question = parameters.Questions.ElementAt(questionIndex); if (ballot.SumProves.Count != parameters.ProofCount) { Logger.Log(LogLevel.Warning, "Connection {0}: Voter id {1} (verified) tried to vote, but there were {2} sum proofs present where there sould have been {3}.", connection.Id, signedEnvelope.Certificate.Id.ToString(), ballot.SumProves.Count, parameters.ProofCount); throw new PiArgumentException(ExceptionCode.InvalidEnvelopeBadProofCount, "Invalid envelope. Number of sum prooves does not match."); } if (ballot.Votes.Count != question.Options.Count()) { Logger.Log(LogLevel.Warning, "Connection {0}: Voter id {1} (verified) tried to vote, but there were {2} votes present for {3} options.", connection.Id, signedEnvelope.Certificate.Id.ToString(), ballot.Votes.Count, question.Options.Count()); throw new PiArgumentException(ExceptionCode.InvalidEnvelopeBadVoteCount, "Invalid envelope. Vote count does not match."); } if (ballot.Votes.Any(vote => vote.RangeProves.Count != parameters.ProofCount)) { Logger.Log(LogLevel.Warning, "Connection {0}: Voter id {1} (verified) tried to vote, but there was the wrong number of range proofs on a vote.", connection.Id, signedEnvelope.Certificate.Id.ToString()); throw new PiArgumentException(ExceptionCode.InvalidEnvelopeBadProofCount, "Invalid envelope. Number of range prooves does not match."); } } bool hasVoted = DbConnection.ExecuteHasRows( "SELECT count(*) FROM envelope WHERE VotingId = @VotingId AND VoterId = @VoterId", "@VotingId", Id.ToByteArray(), "@VoterId", signedEnvelope.Certificate.Id.ToByteArray()); if (hasVoted) throw new PiArgumentException(ExceptionCode.AlreadyVoted, "Voter has already voted."); MySqlTransaction transaction = DbConnection.BeginTransaction(); MySqlCommand indexCommand = new MySqlCommand( "SELECT max(EnvelopeIndex) + 1 FROM envelope WHERE VotingId = @VotingId", DbConnection, transaction); indexCommand.Add("@VotingId", Id.ToByteArray()); object indexObject = indexCommand.ExecuteScalar(); int envelopeIndex = indexObject == DBNull.Value ? 1 : Convert.ToInt32(indexObject); MySqlCommand insertCommand = new MySqlCommand( "INSERT INTO envelope (VotingId, EnvelopeIndex, VoterId, Value) VALUES (@VotingId, @EnvelopeIndex, @VoterId, @Value)", DbConnection, transaction); insertCommand.Add("@VotingId", Id.ToByteArray()); insertCommand.Add("@VoterId", signedEnvelope.Certificate.Id.ToByteArray()); insertCommand.Add("@Value", signedEnvelope.ToBinary()); insertCommand.Add("@EnvelopeIndex", envelopeIndex); insertCommand.ExecuteNonQuery(); transaction.Commit(); Logger.Log(LogLevel.Info, "Connection {0}: Envelope for certificate id {1} on voting id {2} stored.", connection.Id, signedEnvelope.Certificate.Id.ToString(), Id.ToString()); VoteReceipt voteReceipt = new VoteReceipt(Parameters, signedEnvelope); return new Signed<VoteReceipt>(voteReceipt, this.serverCertificate); }
/// <summary> /// Deserializes binary data to object. /// </summary> /// <param name="context">Context for deserialization</param> protected override void Deserialize(DeserializeContext context, byte version) { base.Deserialize(context, version); VoteReceipt = context.ReadObject<Signed<VoteReceipt>>(); }
/// <summary> /// Adds a vote to the vote sum. /// </summary> /// <remarks> /// Verfies the correctness of the vote first. /// </remarks> /// <param name="envelopeIndex">Index of the envelope.</param> /// <param name="signedEnvelope">Signed envelope from voter.</param> /// <param name="progress">Report the progress of the tallying.</param> public void Add(int envelopeIndex, Signed<Envelope> signedEnvelope, Progress progress) { if (signedEnvelope == null) throw new ArgumentNullException("signedEnvelope"); if (voteSums == null) throw new InvalidOperationException("Must call TallyBegin first."); CryptoLog.Begin(CryptoLogLevel.Detailed, "Tallying envelope"); CryptoLog.Add(CryptoLogLevel.Detailed, "Envelope index", envelopeIndex); CryptoLog.Add(CryptoLogLevel.Detailed, "Certificate id", signedEnvelope.Certificate.Id); CryptoLog.Add(CryptoLogLevel.Numeric, "Certificate fingerprint", signedEnvelope.Certificate.Fingerprint); CryptoLog.Add(CryptoLogLevel.Detailed, "Certificate type", signedEnvelope.Certificate.TypeText); if (signedEnvelope.Certificate is VoterCertificate) { CryptoLog.Add(CryptoLogLevel.Detailed, "Certificate group id", ((VoterCertificate)signedEnvelope.Certificate).GroupId); } bool acceptVote = true; Envelope envelope = signedEnvelope.Value; //Certificate is of voter and valid for that canton. acceptVote &= signedEnvelope.Certificate is VoterCertificate && ((VoterCertificate)signedEnvelope.Certificate).GroupId == this.parameters.GroupId; //Signature must be valid. acceptVote &= signedEnvelope.Verify(this.certificateStorage, envelope.Date); CryptoLog.Add(CryptoLogLevel.Detailed, "Certificate status", signedEnvelope.Certificate.Validate(this.certificateStorage, envelope.Date).Text()); CryptoLog.Add(CryptoLogLevel.Detailed, "Envelope signature", signedEnvelope.Verify(this.certificateStorage, envelope.Date)); //Voter's vote must not have been counted. acceptVote &= !this.countedVoters.Contains(signedEnvelope.Certificate.Id); CryptoLog.Add(CryptoLogLevel.Detailed, "Already voted", this.countedVoters.Contains(signedEnvelope.Certificate.Id)); //Date must be in voting period. acceptVote &= envelope.Date.Date >= this.parameters.VotingBeginDate; acceptVote &= envelope.Date.Date <= this.parameters.VotingEndDate; CryptoLog.Add(CryptoLogLevel.Detailed, "Envelope date", envelope.Date); //Ballot must verify (prooves). for (int questionIndex = 0; questionIndex < this.parameters.Questions.Count(); questionIndex++) { Question question = this.parameters.Questions.ElementAt(questionIndex); Ballot ballot = envelope.Ballots.ElementAt(questionIndex); progress.Down(1d / (double)this.parameters.Questions.Count()); acceptVote &= ballot.Verify(this.publicKey, this.parameters, question, this.rng, this.proofCheckCount, progress); progress.Up(); } CryptoLog.Add(CryptoLogLevel.Detailed, "Envelope accepted", acceptVote); CryptoLog.EndWrite(); lock (this.envelopeSequencerList) { this.envelopeSequencerList.Add(envelopeIndex, new Tuple<Signed<Envelope>,bool>(signedEnvelope, acceptVote)); } AddInSequence(); }
/// <summary> /// Sets a signature response. /// </summary> /// <param name="signatureRequestId">Id of the corresponding request.</param> /// <param name="signedSignatureResponse">Signed signature response.</param> public void SetSignatureResponse( IRpcConnection connection, Signed<SignatureResponse> signedSignatureResponse) { if (!signedSignatureResponse.Verify(CertificateStorage)) { if (signedSignatureResponse.VerifySimple()) { Logger.Log(LogLevel.Warning, "Connection {0}: CA id {1} (unverified) tried to set a signature response, but his certificate status was {2}.", connection.Id, signedSignatureResponse.Certificate.Id.ToString(), signedSignatureResponse.Certificate.Validate(CertificateStorage).Text()); } else { Logger.Log(LogLevel.Warning, "Connection {0}: CA id {1} (unverified) tried to set a signature response, but the signature was invalid.", connection.Id, signedSignatureResponse.Certificate.Id.ToString()); } throw new PiSecurityException(ExceptionCode.InvalidSignature, "Signature response has invalid signature."); } if (!(signedSignatureResponse.Certificate is CACertificate)) { Logger.Log(LogLevel.Warning, "Connection {0}: CA id {1} (unverified) tried to set a signature response, but it's not a CA.", connection.Id, signedSignatureResponse.Certificate.Id.ToString()); throw new PiSecurityException(ExceptionCode.SignatureResponseNotFromCA, "Signature response not from proper CA."); } SignatureResponse signatureResponse = signedSignatureResponse.Value; MySqlCommand replaceCommand = new MySqlCommand("REPLACE INTO signatureresponse (Id, Value) VALUES (@Id, @Value)", DbConnection); replaceCommand.Parameters.AddWithValue("@Id", signatureResponse.SubjectId.ToByteArray()); replaceCommand.Parameters.AddWithValue("@Value", signedSignatureResponse.ToBinary()); replaceCommand.ExecuteNonQuery(); Logger.Log(LogLevel.Info, "Connection {0}: Signature response for certificate id {1} stored on behalf of CA id {2}.", connection.Id, signatureResponse.SubjectId.ToString(), signedSignatureResponse.Certificate.Id.ToString()); if (signatureResponse.Status == SignatureResponseStatus.Accepted) { if (CertificateStorage.Has(signatureResponse.SubjectId)) { Certificate certificate = CertificateStorage.Get(signatureResponse.SubjectId); certificate.AddSignature(signatureResponse.Signature); CertificateStorage.Add(certificate); } Secure<SignatureRequestInfo> secureSignatureRequestInfo = GetSignatureRequestInfo(signatureResponse.SubjectId); SignatureRequestInfo signatureRequestInfo = secureSignatureRequestInfo.Value.Decrypt(this.serverCertificate); if (!signatureRequestInfo.EmailAddress.IsNullOrEmpty()) { SendMail( signatureRequestInfo.EmailAddress, MailType.VoterRequestApproved, signatureRequestInfo.EmailAddress, secureSignatureRequestInfo.Certificate.Id.ToString(), CertificateTypeText(secureSignatureRequestInfo.Certificate, Language.English), CertificateTypeText(secureSignatureRequestInfo.Certificate, Language.German), CertificateTypeText(secureSignatureRequestInfo.Certificate, Language.French)); } } else { Secure<SignatureRequestInfo> secureSignatureRequestInfo = GetSignatureRequestInfo(signatureResponse.SubjectId); SignatureRequestInfo signatureRequestInfo = secureSignatureRequestInfo.Value.Decrypt(this.serverCertificate); if (!signatureRequestInfo.EmailAddress.IsNullOrEmpty()) { SendMail( signatureRequestInfo.EmailAddress, MailType.VoterRequestDeclined, signatureRequestInfo.EmailAddress, secureSignatureRequestInfo.Certificate.Id.ToString(), CertificateTypeText(secureSignatureRequestInfo.Certificate, Language.English), CertificateTypeText(secureSignatureRequestInfo.Certificate, Language.German), CertificateTypeText(secureSignatureRequestInfo.Certificate, Language.French), signatureResponse.Reason); } } }
/// <summary> /// Add a partial decipher. /// </summary> /// <param name="signedPartialDecipherList">List of partial deciphers.</param> public void AddPartialDecipher(Signed<PartialDecipherList> signedPartialDecipherList) { PartialDecipherList partialDeciphersList = signedPartialDecipherList.Value; CryptoLog.Begin(CryptoLogLevel.Detailed, "Adding partial decipher"); CryptoLog.Add(CryptoLogLevel.Detailed, "Partial dipher date", partialDeciphersList.Date.Date); CryptoLog.Add(CryptoLogLevel.Detailed, "Certificate id", signedPartialDecipherList.Certificate.Id); CryptoLog.Add(CryptoLogLevel.Detailed, "Certificate type", signedPartialDecipherList.Certificate.TypeText); CryptoLog.Add(CryptoLogLevel.Numeric, "Certificate fingerprint", signedPartialDecipherList.Certificate.Fingerprint); CryptoLog.Add(CryptoLogLevel.Detailed, "Certificate full name", signedPartialDecipherList.Certificate.FullName); if (!(signedPartialDecipherList.Verify(this.certificateStorage, this.parameters.VotingBeginDate) && partialDeciphersList.Date.Date >= this.parameters.VotingEndDate && partialDeciphersList.Date.Date <= DateTime.Now.Date) && signedPartialDecipherList.Certificate is AuthorityCertificate) throw new PiSecurityException(ExceptionCode.PartialDecipherBadSignature, "Partial decipher has bad signature."); CryptoLog.Add(CryptoLogLevel.Detailed, "Certificate status", signedPartialDecipherList.Certificate.Validate(this.certificateStorage, this.parameters.VotingBeginDate)); CryptoLog.Add(CryptoLogLevel.Detailed, "Partial dipher valid", signedPartialDecipherList.Verify(this.certificateStorage, this.parameters.VotingBeginDate)); CryptoLog.Add(CryptoLogLevel.Numeric, "Envelope count", partialDeciphersList.EnvelopeCount); CryptoLog.Add(CryptoLogLevel.Numeric, "Envelope hash", partialDeciphersList.EnvelopeHash); if (partialDeciphersList.EnvelopeCount != EnvelopeCount) { CryptoLog.EndWrite(); throw new PiSecurityException(ExceptionCode.PartialDecipherBadEnvelopeCount, "The number of envelopes does not match the partial decipher."); } if (!partialDeciphersList.EnvelopeHash.Equal(EnvelopeHash)) { CryptoLog.EndWrite(); throw new PiSecurityException(ExceptionCode.PartialDecipherBadEnvelopeHash, "The hash over all envelopes does not match the partail decipher."); } partialDeciphers.AddRange(partialDeciphersList.PartialDeciphers); CryptoLog.EndWrite(); }
/// <summary> /// Add a sign check. /// </summary> /// <param name="signedSignCheck">Signed sign check.</param> public void AddSignatureRequestSignCheck( IRpcConnection connection, Signed<SignatureRequestSignCheck> signedSignCheck) { if (!signedSignCheck.Verify(CertificateStorage)) { if (signedSignCheck.VerifySimple()) { Logger.Log(LogLevel.Warning, "Connection {0}: Server id {1} (unverified) tried to add a sign check, but his certificate status was {2}.", connection.Id, signedSignCheck.Certificate.Id.ToString(), signedSignCheck.Certificate.Validate(CertificateStorage).Text()); } else { Logger.Log(LogLevel.Warning, "Connection {0}: Server id {1} (unverified) tried to add a sign check, but the signature was invalid.", connection.Id, signedSignCheck.Certificate.Id.ToString()); } throw new PiSecurityException(ExceptionCode.InvalidSignature, "Signature on sign check invalid."); } if (!(signedSignCheck.Certificate is ServerCertificate)) { Logger.Log(LogLevel.Warning, "Connection {0}: Server id {1} (verified) tried to add a sign check, but he is not a server.", connection.Id, signedSignCheck.Certificate.Id.ToString()); throw new PiSecurityException(ExceptionCode.SignCheckNotFromServer, "Signature on sign check not from server."); } var signCheck = signedSignCheck.Value; Signed<SignatureResponse> signatureResponse = null; var status = GetSignatureResponseStatus(signCheck.Certificate.Id, out signatureResponse); if (status != SignatureResponseStatus.Pending) { Logger.Log(LogLevel.Warning, "Connection {0}: Notary id {1} (unverified) tried to a sign check to id {2}, but its status was {3}.", connection.Id, signCheck.Cookie.Certificate.Id.ToString(), signCheck.Certificate.Id.ToString(), status.ToString()); throw new PiException(ExceptionCode.SignCheckResponseStateMismatch, "Signature response status mismatch."); } if (!signCheck.Cookie.Verify(CertificateStorage)) { if (signCheck.Cookie.VerifySimple()) { Logger.Log(LogLevel.Warning, "Connection {0}: Notary id {1} (unverified) tried to a sign check to id {2}, but his certificate status was {3}.", connection.Id, signCheck.Cookie.Certificate.Id.ToString(), signCheck.Certificate.Id.ToString(), signCheck.Cookie.Certificate.Validate(CertificateStorage).Text()); } else { Logger.Log(LogLevel.Warning, "Connection {0}: Notary id {1} (unverified) tried to a sign check to id {2}, but the signature was invalid.", connection.Id, signCheck.Cookie.Certificate.Id.ToString(), signCheck.Certificate.Id.ToString()); } throw new PiSecurityException(ExceptionCode.SignCheckCookieSignatureInvalid, "Signature on sign check cookie invalid."); } if (!(signCheck.Cookie.Certificate is AuthorityCertificate || signCheck.Cookie.Certificate is NotaryCertificate)) { Logger.Log(LogLevel.Warning, "Connection {0}: Notary id {1} (unverified) tried to a sign check to id {2}, but he is not an authority or notary.", connection.Id, signCheck.Cookie.Certificate.Id.ToString(), signCheck.Certificate.Id.ToString()); throw new PiSecurityException(ExceptionCode.SignCheckCookieNotFromNotary, "Signature on sign check cookie not from notary."); } Signed<SignCheckCookie> dbCookie = null; var reader = DbConnection.ExecuteReader( "SELECT Cookie FROM signcheckcookie WHERE NotaryId = @NotaryId", "@NotaryId", signCheck.Cookie.Certificate.Id.ToByteArray()); if (reader.Read()) { dbCookie = Serializable.FromBinary<Signed<SignCheckCookie>>(reader.GetBlob(0)); reader.Close(); } else { reader.Close(); throw new PiSecurityException(ExceptionCode.SignCheckCookieNotFound, "Sign check cookie not found."); } if (dbCookie.Certificate.Fingerprint != signCheck.Cookie.Certificate.Fingerprint) throw new PiSecurityException(ExceptionCode.SignCheckCookieFingerprintMismatch, "Fingerprint on sign check cookie does not match."); if (!dbCookie.Value.Randomness.Equal(signCheck.Cookie.Value.Randomness)) throw new PiSecurityException(ExceptionCode.SignCheckCookieRandomnessMismatch, "Randomness of sign check cookie does not match."); MySqlCommand insertCommand = new MySqlCommand("INSERT INTO signcheck (CertificateId, Value) VALUES (@CertificateId, @Value)", DbConnection); insertCommand.Parameters.AddWithValue("@CertificateId", signedSignCheck.Value.Certificate.Id.ToByteArray()); insertCommand.Parameters.AddWithValue("@Value", signedSignCheck.ToBinary()); insertCommand.ExecuteNonQuery(); Logger.Log(LogLevel.Info, "Connection {0}: Notary {1}, {2} has signed signature request {3}", connection.Id, signCheck.Cookie.Certificate.Id.ToString(), signCheck.Cookie.Certificate.FullName, signCheck.Certificate.Id.ToString()); }
private void deleteMenu_Click(object sender, EventArgs e) { if (this.votingList.SelectedIndices.Count > 0) { ListViewItem item = this.votingList.SelectedItems[0]; VotingDescriptor voting = (VotingDescriptor)item.Tag; if (MessageForm.Show( string.Format(Resources.AdminDeleteVotingWarning, voting.Id.ToString(), voting.Title.Text), GuiResources.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question, DialogResult.No) == DialogResult.Yes) { if (DecryptPrivateKeyDialog.TryDecryptIfNessecary(Status.Certificate, Resources.AdminDeleteVotingAction)) { var command = new DeleteVotingRequest.Command(voting.Id); var signedCommand = new Signed<DeleteVotingRequest.Command>(command, Status.Certificate); this.run = true; Status.VotingClient.DeleteVoting(signedCommand, DeleteVotingComplete); while (this.run) { Status.UpdateProgress(); Thread.Sleep(10); } Status.UpdateProgress(); if (this.exception == null) { Status.SetMessage(Resources.AdminDeleteVotingDone, MessageType.Success); } else { Status.SetMessage(this.exception.Message, MessageType.Error); } item.Remove(); OnUpdateWizard(); } } } }
/// <summary> /// Get the status and perhaps response regarding as signature request. /// </summary> /// <param name="certificateId">Id of the certificate.</param> /// <param name="signatureResponse">Signed signature response.</param> /// <returns>Status of the signature response.</returns> public SignatureResponseStatus GetSignatureResponseStatus(Guid certificateId, out Signed<SignatureResponse> signatureResponse) { MySqlCommand selectResponseCommand = new MySqlCommand("SELECT Value FROM signatureresponse WHERE Id = @Id", DbConnection); selectResponseCommand.Parameters.AddWithValue("@Id", certificateId.ToByteArray()); MySqlDataReader selectResponseReader = selectResponseCommand.ExecuteReader(); if (selectResponseReader.Read()) { byte[] signatureResponseData = selectResponseReader.GetBlob(0); selectResponseReader.Close(); signatureResponse = Serializable.FromBinary<Signed<SignatureResponse>>(signatureResponseData); return signatureResponse.Value.Status; } else { selectResponseReader.Close(); MySqlCommand selectRequestCommand = new MySqlCommand("SELECT count(*) FROM signaturerequest WHERE Id = @Id", DbConnection); selectRequestCommand.Parameters.AddWithValue("@Id", certificateId.ToByteArray()); if (selectRequestCommand.ExecuteHasRows()) { signatureResponse = null; return SignatureResponseStatus.Pending; } else { signatureResponse = null; return SignatureResponseStatus.Unknown; } } }
/// <summary> /// Create a new vote cast opeation. /// </summary> /// <param name="votingParameters">Parameters of voting procedure.</param> /// <param name="authorities">Authorities oversseeing this voting.</param> /// <param name="callBack">Callback upon completion.</param> public CreateVotingOperation(Signed<VotingParameters> votingParameters, IEnumerable<AuthorityCertificate> authorities, CreateVotingCallBack callBack) { this.votingParameters = votingParameters; this.authorities = authorities; this.callBack = callBack; }