示例#1
0
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")))
}
示例#2
0
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))
}
示例#3
0
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)
}
示例#4
0
// 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
}
示例#5
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)
}
示例#6
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
}
示例#7
0
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)
}
示例#8
0
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))
}
示例#9
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
}
示例#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)
		}
	}
}