// signStatement signs the contents passed in the io.Reader // (pass an io.File or use an strings.NewReader for strings). It uses // the roster el to create the collective signature. // In case the signature fails, an error is returned. func signStatement(read io.Reader, el *onet.Roster) (*service.SignatureResponse, error) { //publics := entityListToPublics(el) client := service.NewClient() msg, _ := crypto.HashStream(network.Suite.Hash(), read) pchan := make(chan *service.SignatureResponse) var err error go func() { log.Lvl3("Waiting for the response on SignRequest") response, e := client.SignatureRequest(el, msg) if e != nil { err = e close(pchan) return } pchan <- response }() select { case response, ok := <-pchan: log.Lvl5("Response:", response) if !ok || err != nil { return nil, errors.New("received an invalid response") } err = cosi.VerifySignature(network.Suite, el.Publics(), msg, response.Signature) if err != nil { return nil, err } return response, nil case <-time.After(RequestTimeOut): return nil, errors.New("timeout on signing request") } }
// verifySignatureHash verifies if the message b is correctly signed by signature // sig from roster el. // If the signature-check fails for any reason, an error is returned. func verifySignatureHash(b []byte, sig *service.SignatureResponse, el *onet.Roster) error { // We have to hash twice, as the hash in the signature is the hash of the // message sent to be signed //publics := entityListToPublics(el) fHash, _ := crypto.HashBytes(network.Suite.Hash(), b) hashHash, _ := crypto.HashBytes(network.Suite.Hash(), fHash) if !bytes.Equal(hashHash, sig.Hash) { return errors.New("You are trying to verify a signature " + "belonging to another file. (The hash provided by the signature " + "doesn't match with the hash of the file.)") } err := cosi.VerifySignature(network.Suite, el.Publics(), fHash, sig.Signature) if err != nil { return errors.New("Invalid sig:" + err.Error()) } return nil }