func TestVerify(t *testing.T) { idStore := NewIdentityMapper(msgCryptoService) identity := []byte("yacovm") identity2 := []byte("not-yacovm") pkiID := msgCryptoService.GetPKIidOfCert(api.PeerIdentityType(identity)) pkiID2 := msgCryptoService.GetPKIidOfCert(api.PeerIdentityType(identity2)) idStore.Put(pkiID, api.PeerIdentityType(identity)) signed, err := idStore.Sign([]byte("bla bla")) assert.NoError(t, err) assert.NoError(t, idStore.Verify(pkiID, signed, []byte("bla bla"))) assert.Error(t, idStore.Verify(pkiID2, signed, []byte("bla bla"))) }
func TestPut(t *testing.T) { idStore := NewIdentityMapper(msgCryptoService) identity := []byte("yacovm") identity2 := []byte("not-yacovm") pkiID := msgCryptoService.GetPKIidOfCert(api.PeerIdentityType(identity)) pkiID2 := msgCryptoService.GetPKIidOfCert(api.PeerIdentityType(identity2)) assert.NoError(t, idStore.Put(pkiID, identity)) assert.Error(t, idStore.Put(nil, identity)) assert.Error(t, idStore.Put(pkiID2, nil)) assert.Error(t, idStore.Put(pkiID2, identity)) assert.Error(t, idStore.Put(pkiID, identity2)) }
func TestGet(t *testing.T) { idStore := NewIdentityMapper(msgCryptoService) identity := []byte("yacovm") identity2 := []byte("not-yacovm") pkiID := msgCryptoService.GetPKIidOfCert(api.PeerIdentityType(identity)) pkiID2 := msgCryptoService.GetPKIidOfCert(api.PeerIdentityType(identity2)) assert.NoError(t, idStore.Put(pkiID, identity)) cert, err := idStore.Get(pkiID) assert.NoError(t, err) assert.Equal(t, api.PeerIdentityType(identity), cert) cert, err = idStore.Get(pkiID2) assert.Nil(t, cert) assert.Error(t, err) }
// validateAliveMsg validates that an Alive message is authentic func (sa *discoverySecurityAdapter) ValidateAliveMsg(am *proto.AliveMessage) bool { if am == nil || am.Membership == nil || am.Membership.PkiID == nil || am.Signature == nil { sa.logger.Warning("Invalid alive message:", am) return false } var identity api.PeerIdentityType // If signature is included inside AliveMessage if am.Identity != nil { identity = api.PeerIdentityType(am.Identity) err := sa.mcs.ValidateIdentity(api.PeerIdentityType(identity)) if err != nil { sa.logger.Warning("Failed validating identity of", am, "reason:", err) return false } } else { identity, _ = sa.idMapper.Get(am.Membership.PkiID) if identity != nil { sa.logger.Debug("Fetched identity of", am.Membership.PkiID, "from identity store") } } if identity == nil { sa.logger.Warning("Don't have certificate for", am) return false } // At this point we got the certificate of the peer, proceed to verifying the AliveMessage sig := am.Signature am.Signature = nil amIdentity := am.Identity am.Identity = nil b, err := prot.Marshal(am) am.Signature = sig am.Identity = amIdentity if err != nil { sa.logger.Error("Failed marshalling", am, ":", err) return false } err = sa.mcs.Verify(identity, sig, b) if err != nil { sa.logger.Warning("Failed verifying:", am, ":", err) return false } return true }
func (g *gossipServiceImpl) createCertStorePuller() pull.Mediator { conf := pull.PullConfig{ MsgType: proto.PullMsgType_IdentityMsg, Channel: []byte(""), Id: g.conf.SelfEndpoint, PeerCountToSelect: g.conf.PullPeerNum, PullInterval: g.conf.PullInterval, Tag: proto.GossipMessage_EMPTY, } pkiIDFromMsg := func(msg *proto.GossipMessage) string { identityMsg := msg.GetPeerIdentity() if identityMsg == nil || identityMsg.PkiID == nil { return "" } return fmt.Sprintf("%s", string(identityMsg.PkiID)) } certConsumer := func(msg *proto.GossipMessage) { idMsg := msg.GetPeerIdentity() if idMsg == nil || idMsg.Cert == nil || idMsg.PkiID == nil { g.logger.Warning("Invalid PeerIdentity:", idMsg) return } err := g.idMapper.Put(common.PKIidType(idMsg.PkiID), api.PeerIdentityType(idMsg.Cert)) if err != nil { g.logger.Warning("Failed associating PKI-ID with certificate:", err) } } return pull.NewPullMediator(conf, g.comm, g.disc, pkiIDFromMsg, certConsumer) }
func (g *gossipServiceImpl) validateIdentityMsg(msg *proto.GossipMessage) error { if msg.GetPeerIdentity() == nil { return fmt.Errorf("Identity empty") } idMsg := msg.GetPeerIdentity() pkiID := idMsg.PkiID cert := idMsg.Cert sig := idMsg.Sig if bytes.Equal(g.idMapper.GetPKIidOfCert(api.PeerIdentityType(cert)), common.PKIidType(pkiID)) { return fmt.Errorf("Calculated pkiID doesn't match identity") } idMsg.Sig = nil b, err := prot.Marshal(idMsg) if err != nil { return fmt.Errorf("Failed marshalling: %v", err) } err = g.mcs.Verify(api.PeerIdentityType(cert), sig, b) if err != nil { return fmt.Errorf("Failed verifying message: %v", err) } idMsg.Sig = sig return nil }
func (cs *certStore) handleMessage(msg comm.ReceivedMessage) { if update := msg.GetGossipMessage().GetDataUpdate(); update != nil { for _, m := range update.Data { if !m.IsIdentityMsg() { cs.logger.Warning("Got a non-identity message:", m, "aborting") return } idMsg := m.GetPeerIdentity() if err := cs.mcs.ValidateIdentity(api.PeerIdentityType(idMsg.Cert)); err != nil { cs.logger.Warning("Got invalid certificate:", err) return } } } cs.pull.HandleMessage(msg) }
func newGossipInstanceWithOnlyPull(id int, maxMsgCount int, boot ...int) Gossip { port := id + portPrefix conf := &Config{ BindPort: port, BootstrapPeers: bootPeers(boot...), ID: fmt.Sprintf("p%d", id), MaxMessageCountToStore: maxMsgCount, MaxPropagationBurstLatency: time.Duration(10) * time.Millisecond, MaxPropagationBurstSize: 10, PropagateIterations: 0, PropagatePeerNum: 0, PullInterval: time.Duration(1000) * time.Millisecond, PullPeerNum: 20, SelfEndpoint: fmt.Sprintf("localhost:%d", port), PublishCertPeriod: time.Duration(0) * time.Second, } return NewGossipServiceWithServer(conf, &naiveCryptoService{}, api.PeerIdentityType(conf.SelfEndpoint)) }
func newCertStore(puller pull.Mediator, idMapper identity.Mapper, selfIdentity api.PeerIdentityType, mcs api.MessageCryptoService) *certStore { selfPKIID := idMapper.GetPKIidOfCert(selfIdentity) logger := util.GetLogger("certStore", string(selfPKIID)) if err := idMapper.Put(selfPKIID, selfIdentity); err != nil { logger.Error("Failed associating self PKIID to cert:", err) panic(fmt.Errorf("Failed associating self PKIID to cert: %v", err)) } certStore := &certStore{ mcs: mcs, pull: puller, idMapper: idMapper, selfIdentity: selfIdentity, logger: logger, } certStore.logger = util.GetLogger("certStore", string(selfPKIID)) if err := certStore.idMapper.Put(selfPKIID, selfIdentity); err != nil { certStore.logger.Panic("Failed associating self PKIID to cert:", err) } puller.Add(certStore.createIdentityMessage()) puller.RegisterMsgHook(pull.ResponseMsgType, func(_ []string, msgs []*proto.GossipMessage, _ comm.ReceivedMessage) { for _, msg := range msgs { pkiID := common.PKIidType(msg.GetPeerIdentity().PkiID) cert := api.PeerIdentityType(msg.GetPeerIdentity().Cert) if err := certStore.idMapper.Put(pkiID, cert); err != nil { certStore.logger.Warning("Failed adding identity", cert, ", reason:", err) } } }) puller.Add(certStore.createIdentityMessage()) return certStore }
func (g *gossipServiceImpl) handleMessage(m comm.ReceivedMessage) { if g.toDie() { return } g.logger.Info("Entering,", m) defer g.logger.Info("Exiting") if m == nil || m.GetGossipMessage() == nil { return } msg := m.GetGossipMessage() if msg.IsAliveMsg() || msg.IsDataMsg() { if msg.IsAliveMsg() { if !g.disSecAdap.ValidateAliveMsg(msg.GetAliveMsg()) { g.logger.Warning("AliveMessage", m.GetGossipMessage(), "isn't authentic. Discarding it") return } am := msg.GetAliveMsg() storedIdentity, _ := g.idMapper.Get(common.PKIidType(am.Membership.PkiID)) // If peer's certificate is included inside AliveMessage, and we don't have a mapping between // its PKI-ID and certificate, create a mapping for it now. if identity := am.Identity; identity != nil && storedIdentity == nil { err := g.idMapper.Put(common.PKIidType(am.Membership.PkiID), api.PeerIdentityType(identity)) if err != nil { g.logger.Warning("Failed adding identity of", am, "into identity store:", err) return } g.logger.Info("Learned identity of", am.Membership.PkiID) } } if msg.IsDataMsg() { blockMsg := msg.GetDataMsg() if blockMsg.Payload == nil { g.logger.Warning("Empty block! Discarding it") return } if err := g.mcs.VerifyBlock(blockMsg); err != nil { g.logger.Warning("Could not verify block", blockMsg.Payload.SeqNum, "Discarding it") return } } added := g.msgStore.add(msg) if added { g.emitter.Add(msg) if dataMsg := m.GetGossipMessage().GetDataMsg(); dataMsg != nil { g.blocksPuller.Add(msg) g.DeMultiplex(msg) } } } if selectOnlyDiscoveryMessages(m) { g.forwardDiscoveryMsg(m) } if msg.IsPullMsg() { switch msgType := msg.GetPullMsgType(); msgType { case proto.PullMsgType_BlockMessage: g.blocksPuller.HandleMessage(m) case proto.PullMsgType_IdentityMsg: g.certStore.handleMessage(m) default: g.logger.Warning("Got invalid pull message type:", msgType) } } }