func init() { // Load the singing key // TODO: load from election config file voterListKey := keys.UnpackPrivateKey(config.LoadServerKey("voterListKey")) config := config.Load() for _, voter := range config.Voters { voterKey, err := proto.Marshal(voter.Key) if err != nil { panic(err) } sig, err := sign.Sign(voterListKey, voterKey) if err != nil { panic(err) } voterKeys[string(voterKey)] = sig fmt.Printf("Added voter %s.\n", *voter.Name) } }
func HandelSignatureRequest(data []byte, c net.Conn) { var v msgs.Vote err := proto.Unmarshal(data, &v) if err != nil { fmt.Println("server error reading Vote:", err) server.ConnectionError(c) return } err = msg.ValidateVote(ballotKey, &v) if err != nil { fmt.Println(err) return } keyString := stringKey(&v) // TODO: needs a lock id, ok := ballotSet[keyString] if !ok { id = len(votes) votes = append(votes, v) ballotSet[keyString] = id fmt.Printf("Got Vote %d: %s\n", id, v.Ballot) } var response msgs.VoteResponse var ballotEntry msgs.BallotEntry tmp := uint64(id) ballotEntry.Id = &tmp ballotEntry.Ballot = votes[id].Ballot ballotBytes, err := proto.Marshal(&ballotEntry) response.BallotEntry = ballotBytes response.BallotEntrySignature, err = sign.Sign(votePrivateKey, ballotBytes) responseData, err := proto.Marshal(&response) server.SendBlock(msg.VoteResponse, responseData, c) }
// Get signature for the ballot from ballot server func GetBallotSig(voterKey *rsa.PrivateKey, keySig, ballot []byte) ([]byte, error) { conn, err := net.Dial("tcp", "localhost"+msg.Service) if err != nil { panic(err) } var r msgs.SignatureRequest // TODO real values r.VoterPublicKey = keys.PackKey(&voterKey.PublicKey) blindedBallot, unblinder := sign.Blind(ballotKey, ballot) r.BlindedBallot = blindedBallot r.KeySignature = keySig voterSignature, err := sign.Sign(voterKey, blindedBallot) if err != nil { fmt.Println(err) panic(err) } r.VoterSignature = voterSignature data, err := proto.Marshal(&r) if err != nil { panic(err) } err = msg.WriteBlock(conn, msg.SignatureRequest, data) if err != nil { panic(err) } t, err := msg.ReadType(conn) if err != nil { panic(err) } if t != msg.SignatureResponse { return nil, fmt.Errorf("SignatureResponse: invalid response type %d. Expected: %d", t, msg.SignatureResponse) } data, err = msg.ReadBlock(conn, maxLength) conn.Close() if err != nil { panic(err) } var response msgs.SignatureResponse err = proto.Unmarshal(data, &response) if err != nil { fmt.Println("error reading SignatureResponse:", err) panic(err) } if !KeysEqual(r.VoterPublicKey, response.Request.VoterPublicKey) { fmt.Println("illegal response from server. Voter keys must match:") fmt.Println(r.VoterPublicKey) fmt.Println(response.Request.VoterPublicKey) panic(err) } err = msg.ValidateSignatureRequest(response.Request) if err != nil { panic(err) } newBlindedBallot := response.Request.BlindedBallot if !bytes.Equal(r.BlindedBallot, newBlindedBallot) { fmt.Println("Server has proof you voted before!") // TODO should store ballots (and blinding factors?) from all attempts // so can try and cast old ballot panic(err) } if !sign.CheckBlindSig(ballotKey, newBlindedBallot, response.BlindedBallotSignature) { fmt.Println("illegal response from server. Signature in response is invalid:", ballotKey, newBlindedBallot, response.BlindedBallotSignature) panic(err) } sig := sign.Unblind(ballotKey, response.BlindedBallotSignature, unblinder) return sig, nil }