Beispiel #1
0
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)
}
Beispiel #2
0
func TestMockComm(t *testing.T) {
	first := &socketMock{"first", make(chan interface{})}
	second := &socketMock{"second", make(chan interface{})}
	members := make(map[string]*socketMock)

	members[first.endpoint] = first
	members[second.endpoint] = second

	comm1 := NewCommMock(first.endpoint, members)
	defer comm1.Stop()

	msgCh := comm1.Accept(func(message interface{}) bool {
		return message.(comm.ReceivedMessage).GetGossipMessage().GetStateRequest() != nil ||
			message.(comm.ReceivedMessage).GetGossipMessage().GetStateResponse() != nil
	})

	comm2 := NewCommMock(second.endpoint, members)
	defer comm2.Stop()

	comm2.Send(&proto.GossipMessage{
		Content: &proto.GossipMessage_StateRequest{&proto.RemoteStateRequest{
			SeqNums: []uint64{1, 2, 3},
		}},
	}, &comm.RemotePeer{"first", common.PKIidType("first")})

	msg := <-msgCh

	assert.NotNil(t, msg.GetGossipMessage().GetStateRequest())
}
Beispiel #3
0
func (d *gossipDiscoveryImpl) getKnownPeers() [][]byte {
	d.lock.RLock()
	defer d.lock.RUnlock()

	peers := [][]byte{}
	for id := range d.id2Member {
		peers = append(peers, common.PKIidType(id))
	}
	return peers
}
Beispiel #4
0
func (d *gossipDiscoveryImpl) getDeadMembers() []common.PKIidType {
	d.lock.RLock()
	defer d.lock.RUnlock()

	dead := []common.PKIidType{}
	for id, last := range d.aliveLastTS {
		elapsedNonAliveTime := time.Since(last.lastSeen)
		if elapsedNonAliveTime.Nanoseconds() > aliveExpirationTimeout.Nanoseconds() {
			d.logger.Warning("Haven't heard from", id, "for", elapsedNonAliveTime)
			dead = append(dead, common.PKIidType(id))
		}
	}
	return dead
}
Beispiel #5
0
func TestMockComm_PingPong(t *testing.T) {
	members := make(map[string]*socketMock)

	members["peerA"] = &socketMock{"peerA", make(chan interface{})}
	members["peerB"] = &socketMock{"peerB", make(chan interface{})}

	peerA := NewCommMock("peerA", members)
	peerB := NewCommMock("peerB", members)

	all := func(interface{}) bool {
		return true
	}

	rcvChA := peerA.Accept(all)
	rcvChB := peerB.Accept(all)

	peerA.Send(&proto.GossipMessage{
		Content: &proto.GossipMessage_DataMsg{
			&proto.DataMessage{
				&proto.Payload{1, "", []byte("Ping")},
			}},
	}, &comm.RemotePeer{"peerB", common.PKIidType("peerB")})

	msg := <-rcvChB
	dataMsg := msg.GetGossipMessage().GetDataMsg()
	data := string(dataMsg.Payload.Data)
	assert.Equal(t, "Ping", data)

	msg.Respond(&proto.GossipMessage{
		Content: &proto.GossipMessage_DataMsg{
			&proto.DataMessage{
				&proto.Payload{1, "", []byte("Pong")},
			}},
	})

	msg = <-rcvChA
	dataMsg = msg.GetGossipMessage().GetDataMsg()
	data = string(dataMsg.Payload.Data)
	assert.Equal(t, "Pong", data)

}
Beispiel #6
0
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
}
Beispiel #7
0
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
}
Beispiel #8
0
// GetPKIid returns this instance's PKI id
func (mock *commMock) GetPKIid() common.PKIidType {
	return common.PKIidType(mock.id)
}
Beispiel #9
0
// GetPKIidOfCert returns the PKI-ID of a peer's identity
func (*naiveCryptoService) GetPKIidOfCert(peerIdentity api.PeerIdentityType) common.PKIidType {
	return common.PKIidType(peerIdentity)
}
Beispiel #10
0
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)
		}
	}
}