/// <summary> /// Load all votings from the database. /// </summary> private void LoadVotings() { this.votings = new Dictionary<Guid, VotingServerEntity>(); MySqlCommand selectCommand = new MySqlCommand("SELECT Id, Parameters, Status FROM voting", DbConnection); MySqlDataReader reader = selectCommand.ExecuteReader(); while (reader.Read()) { Guid id = reader.GetGuid(0); byte[] signedParametersData = reader.GetBlob(1); Signed<VotingParameters> signedParameters = Serializable.FromBinary<Signed<VotingParameters>>(signedParametersData); VotingStatus status = (VotingStatus)reader.GetInt32(2); VotingServerEntity entity = new VotingServerEntity(this, signedParameters, this.CertificateStorage, this.serverCertificate, status); this.votings.Add(id, entity); } reader.Close(); }
/// <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); }
/// <summary> /// Voting entity test. /// </summary> /// <remarks> /// Used only during development. /// </remarks> public void EntityTest() { IRpcConnection connection = new DummyConnection(); DateTime validUntil = DateTime.Now.AddDays(1); var root = new CACertificate(null, "Root"); root.CreateSelfSignature(); var rootCrl = new RevocationList(root.Id, DateTime.Now, validUntil, new List<Guid>()); var sigRootCrl = new Signed<RevocationList>(rootCrl, root); var intermediate = new CACertificate(null, "Intermediate"); intermediate.CreateSelfSignature(); intermediate.AddSignature(root, validUntil); var intCrl = new RevocationList(intermediate.Id, DateTime.Now, validUntil, new List<Guid>()); var sigIntCrl = new Signed<RevocationList>(intCrl, intermediate); var admin = new AdminCertificate(Language.English, null, "Admin"); admin.CreateSelfSignature(); admin.AddSignature(intermediate, DateTime.Now.AddDays(1)); var serverCert = new ServerCertificate("Server"); serverCert.CreateSelfSignature(); serverCert.AddSignature(intermediate, DateTime.Now.AddDays(1)); VotingParameters parameters = new VotingParameters( new MultiLanguageString("Zufrieden"), new MultiLanguageString("Tada"), new MultiLanguageString(string.Empty), DateTime.Now, DateTime.Now.AddDays(1), 0); parameters.GenerateNumbers(Files.TestDataPath); Question question = new Question(new MultiLanguageString("Zufrieden?"), new MultiLanguageString(string.Empty), new MultiLanguageString(string.Empty), 1); question.AddOption(new Option(new MultiLanguageString("Nein"), new MultiLanguageString("Dagegen"), new MultiLanguageString(string.Empty))); question.AddOption(new Option(new MultiLanguageString("Ja"), new MultiLanguageString("Dafür"), new MultiLanguageString(string.Empty))); parameters.AddQuestion(question); Signed<VotingParameters> signedParameters = new Signed<VotingParameters>(parameters, admin); DateTime start = DateTime.Now; Console.WriteLine(); Console.Write("Voting begins..."); CertificateStorage serverCertStorage = new CertificateStorage(); serverCertStorage.AddRoot(root); serverCertStorage.Add(intermediate); serverCertStorage.AddRevocationList(sigRootCrl); serverCertStorage.AddRevocationList(sigIntCrl); VotingServerEntity vs = new VotingServerEntity(null, signedParameters, serverCertStorage, serverCert); var a1c = new AuthorityCertificate(Language.English, "Authority 1", null); a1c.CreateSelfSignature(); a1c.AddSignature(intermediate, validUntil); var a2c = new AuthorityCertificate(Language.English, "Authority 2", null); a2c.CreateSelfSignature(); a2c.AddSignature(intermediate, validUntil); var a3c = new AuthorityCertificate(Language.English, "Authority 3", null); a3c.CreateSelfSignature(); a3c.AddSignature(intermediate, validUntil); var a4c = new AuthorityCertificate(Language.English, "Authority 4", null); a4c.CreateSelfSignature(); a4c.AddSignature(intermediate, validUntil); var a5c = new AuthorityCertificate(Language.English, "Authority 5", null); a5c.CreateSelfSignature(); a5c.AddSignature(intermediate, validUntil); var a1 = new AuthorityEntity(serverCertStorage, a1c); var a2 = new AuthorityEntity(serverCertStorage, a2c); var a3 = new AuthorityEntity(serverCertStorage, a3c); var a4 = new AuthorityEntity(serverCertStorage, a4c); var a5 = new AuthorityEntity(serverCertStorage, a5c); vs.AddAuthority(connection, a1.Certificate); vs.AddAuthority(connection, a2.Certificate); vs.AddAuthority(connection, a3.Certificate); vs.AddAuthority(connection, a4.Certificate); vs.AddAuthority(connection, a5.Certificate); a1.Prepare(1, vs.SignedParameters); a2.Prepare(2, vs.SignedParameters); a3.Prepare(3, vs.SignedParameters); a4.Prepare(4, vs.SignedParameters); a5.Prepare(5, vs.SignedParameters); a1.SetAuthorities(vs.AuthorityList); a2.SetAuthorities(vs.AuthorityList); a3.SetAuthorities(vs.AuthorityList); a4.SetAuthorities(vs.AuthorityList); a5.SetAuthorities(vs.AuthorityList); vs.DepositShares(connection, a1.GetShares()); vs.DepositShares(connection, a2.GetShares()); vs.DepositShares(connection, a3.GetShares()); vs.DepositShares(connection, a4.GetShares()); vs.DepositShares(connection, a5.GetShares()); var r1 = a1.VerifyShares(vs.GetAllShares()); var r2 = a2.VerifyShares(vs.GetAllShares()); var r3 = a3.VerifyShares(vs.GetAllShares()); var r4 = a4.VerifyShares(vs.GetAllShares()); var r5 = a5.VerifyShares(vs.GetAllShares()); vs.DepositShareResponse(connection, r1); vs.DepositShareResponse(connection, r2); vs.DepositShareResponse(connection, r3); vs.DepositShareResponse(connection, r4); vs.DepositShareResponse(connection, r5); var v1c = new VoterCertificate(Language.English, null, 0); v1c.CreateSelfSignature(); v1c.AddSignature(intermediate, validUntil); var cs = new CertificateStorage(); cs.AddRoot(root); var v1 = new VoterEntity(cs); IEnumerable<int> questionVota = new int[] { 0, 1 }; var vote1 = v1.Vote(vs.GetVotingMaterial(), v1c, new IEnumerable<int>[] { questionVota }, null); vs.Vote(connection, vote1); int voters = 10; for (int i = 1000; i < 1000 + voters; i++) { var vc = new VoterCertificate(Language.English, null, 0); vc.CreateSelfSignature(); vc.AddSignature(intermediate, validUntil); var vx = new VoterEntity(cs); IEnumerable<int> questionVota2 = new int[] { 0, 1 }; var votex = vx.Vote(vs.GetVotingMaterial(), vc, new IEnumerable<int>[] { questionVota2 }, null); vs.Vote(connection, votex); } for (int i = 2000; i < 2000 + voters; i++) { var vc = new VoterCertificate(Language.English, null, 0); vc.CreateSelfSignature(); vc.AddSignature(intermediate, validUntil); var vx = new VoterEntity(cs); IEnumerable<int> questionVota3 = new int[] { 1, 0 }; var votex = vx.Vote(vs.GetVotingMaterial(), vc, new IEnumerable<int>[] { questionVota3 }, null); vs.Vote(connection, votex); } vs.EndVote(); a1.TallyBegin(vs.GetVotingMaterial()); a2.TallyBegin(vs.GetVotingMaterial()); a3.TallyBegin(vs.GetVotingMaterial()); a4.TallyBegin(vs.GetVotingMaterial()); a5.TallyBegin(vs.GetVotingMaterial()); for (int envelopeIndex = 0; envelopeIndex < vs.GetEnvelopeCount(); envelopeIndex++) { a1.TallyAdd(envelopeIndex, vs.GetEnvelope(envelopeIndex), new Progress(null)); a2.TallyAdd(envelopeIndex, vs.GetEnvelope(envelopeIndex), new Progress(null)); a3.TallyAdd(envelopeIndex, vs.GetEnvelope(envelopeIndex), new Progress(null)); a4.TallyAdd(envelopeIndex, vs.GetEnvelope(envelopeIndex), new Progress(null)); a5.TallyAdd(envelopeIndex, vs.GetEnvelope(envelopeIndex), new Progress(null)); } var pd1 = a1.PartiallyDecipher(); var pd2 = a2.PartiallyDecipher(); var pd3 = a3.PartiallyDecipher(); var pd4 = a4.PartiallyDecipher(); var pd5 = a5.PartiallyDecipher(); vs.DepositPartialDecipher(connection, pd1); vs.DepositPartialDecipher(connection, pd2); vs.DepositPartialDecipher(connection, pd3); vs.DepositPartialDecipher(connection, pd4); vs.DepositPartialDecipher(connection, pd5); v1.TallyBegin(vs.GetVotingMaterial(), BaseParameters.StandardProofCount); for (int envelopeIndex = 0; envelopeIndex < vs.GetEnvelopeCount(); envelopeIndex++) { v1.TallyAdd(envelopeIndex, vs.GetEnvelope(envelopeIndex), new Progress(null)); } for (int authorityIndex = 1; authorityIndex < vs.Parameters.AuthorityCount + 1; authorityIndex++) { v1.TallyAddPartialDecipher(vs.GetPartialDecipher(authorityIndex)); } var res1 = v1.TallyResult; TimeSpan duration = DateTime.Now.Subtract(start); Console.WriteLine("Succeded {0}", duration.ToString()); }