關(guān)于gossip中證書/身份存儲(chǔ)的內(nèi)容
package gossip
// 傳播所有的身份信息
// certStore supports pull dissemination of identity messages
type certStore struct {
selfIdentity api.PeerIdentityType // peer自身的身份
idMapper identity.Mapper // 公鑰和身份的映射關(guān)系:公鑰PKIid :身份
pull pull.Mediator // 獲取消息中介
logger util.Logger
mcs api.MessageCryptoService // 信息加密服務(wù)
}
// 新建身份存儲(chǔ)
func newCertStore(puller pull.Mediator, // PullEngine的包裝類 提供獲取同步相關(guān)的方法
idMapper identity.Mapper, // <PKIid, Certificates/identifies> 公鑰ID 與 證書或身份的映射
selfIdentity api.PeerIdentityType, // 自身標(biāo)識(shí)
mcs api.MessageCryptoService) *certStore { // 信息加密服務(wù)
// 獲取對(duì)應(yīng)身份的公鑰UD
selfPKIID := idMapper.GetPKIidOfCert(selfIdentity)
//
logger := util.GetLogger(util.LoggingGossipModule, string(selfPKIID))
certStore := &certStore{
mcs: mcs, // 信息加密服務(wù)
pull: puller, // 獲取者
idMapper: idMapper, // 本地公鑰驻子、身份/證書映射器
selfIdentity: selfIdentity, // 自身標(biāo)識(shí)
logger: logger,
}
// 添加自身公鑰ID與身份的關(guān)聯(lián)關(guān)系
if err := certStore.idMapper.Put(selfPKIID, selfIdentity); err != nil {
certStore.logger.Panicf("Failed associating self PKIID to cert: %+v", errors.WithStack(err))
}
// 創(chuàng)建身份信息
selfIDMsg, err := certStore.createIdentityMessage()
if err != nil {
certStore.logger.Panicf("Failed creating self identity message: %+v", errors.WithStack(err))
}
// 添加到獲取中間代理上 并將注冊一個(gè)鉤子到指定類型的消息(RegisterMsgHook)
puller.Add(selfIDMsg)
puller.RegisterMsgHook(pull.RequestMsgType, func(_ []string, msgs []*proto.SignedGossipMessage, _ proto.ReceivedMessage) {
// 遍歷簽名的Gossip Message 獲取每個(gè)消息里面的每個(gè)對(duì)等節(jié)點(diǎn)peer的公鑰ID 憔杨、身份證書; 并將公鑰ID 效拭、身份證書放到映射表中
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.Warningf("Failed adding identity %v, reason %+v", cert, errors.WithStack(err))
}
}
})
return certStore
}
// 處理消息
func (cs *certStore) handleMessage(msg proto.ReceivedMessage) {
// 獲取GossipMessage的更新數(shù)據(jù)
if update := msg.GetGossipMessage().GetDataUpdate(); update != nil {
// 提取更新的數(shù)據(jù) 并解碼Envelope轉(zhuǎn)為對(duì)應(yīng)的gossip message簽名消息
for _, env := range update.Data {
m, err := env.ToGossipMessage()
if err != nil {
cs.logger.Warningf("Data update contains an invalid message: %+v", errors.WithStack(err))
return
}
// 轉(zhuǎn)換的簽名gossip message是否是身份信息
if !m.IsIdentityMsg() {
cs.logger.Warning("Got a non-identity message:", m, "aborting")
return
}
// 檢驗(yàn)身份信息的有效性
if err := cs.validateIdentityMsg(m); err != nil {
cs.logger.Warningf("Failed validating identity message: %+v", errors.WithStack(err))
return
}
}
}
// 通過獲取中間代理處理消息
cs.pull.HandleMessage(msg)
}
// 驗(yàn)證身份消息
func (cs *certStore) validateIdentityMsg(msg *proto.SignedGossipMessage) error {
// 從簽名消息SignedGossipMessage中提取對(duì)等節(jié)點(diǎn)peer的身份
idMsg := msg.GetPeerIdentity()
if idMsg == nil {
return errors.Errorf("Identity empty: %+v", msg)
}
// 提取對(duì)等節(jié)點(diǎn)peer身份信息中的公鑰ID
pkiID := idMsg.PkiId
// 提取對(duì)等節(jié)點(diǎn)peer身份信息中的證書
cert := idMsg.Cert
// 根據(jù)對(duì)等節(jié)點(diǎn)peer的身份類型提取對(duì)應(yīng)的證書公鑰ID
calculatedPKIID := cs.mcs.GetPKIidOfCert(api.PeerIdentityType(cert))
// 聲明的公鑰ID
claimedPKIID := common.PKIidType(pkiID)
// 對(duì)比計(jì)算的公鑰ID 和 聲明的公鑰id進(jìn)行比較,判斷計(jì)算的公鑰ID是否與對(duì)等節(jié)點(diǎn)peer的身份信息的內(nèi)容匹配
if !bytes.Equal(calculatedPKIID, claimedPKIID) {
return errors.Errorf("Calculated pkiID doesn't match identity: calculated: %v, claimedPKI-ID: %v", calculatedPKIID, claimedPKIID)
}
// 定義檢驗(yàn)函數(shù):通過消息加密服務(wù)(Message Crypto Service )
verifier := func(peerIdentity []byte, signature, message []byte) error {
return cs.mcs.Verify(api.PeerIdentityType(peerIdentity), signature, message)
}
// 檢驗(yàn)消息
err := msg.Verify(cert, verifier)
if err != nil {
return errors.Wrap(err, "Failed verifying message")
}
// 驗(yàn)證身份
return cs.mcs.ValidateIdentity(api.PeerIdentityType(idMsg.Cert))
}
// 創(chuàng)建身份消息
func (cs *certStore) createIdentityMessage() (*proto.SignedGossipMessage, error) {
// 對(duì)等節(jié)點(diǎn)身份
pi := &proto.PeerIdentity{
Cert: cs.selfIdentity, // 自身身份(標(biāo)識(shí))
Metadata: nil, // 元數(shù)據(jù)
PkiId: cs.idMapper.GetPKIidOfCert(cs.selfIdentity), // 從映射表中獲取公鑰ID
}
// Gossip消息
m := &proto.GossipMessage{
Channel: nil, // 通道
Nonce: 0, //
Tag: proto.GossipMessage_EMPTY, // gossip message的標(biāo)記
Content: &proto.GossipMessage_PeerIdentity{ // 對(duì)等節(jié)點(diǎn)身份Gossip消息的內(nèi)容:對(duì)等節(jié)點(diǎn)身份內(nèi)容
PeerIdentity: pi,
},
}
signer := func(msg []byte) ([]byte, error) { // 消息簽名函數(shù)
return cs.idMapper.Sign(msg)
}
sMsg := &proto.SignedGossipMessage{ // 簽名后的gossip message
GossipMessage: m,
}
_, err := sMsg.Sign(signer) // 綁定簽名和消息
return sMsg, errors.WithStack(err) // 返回簽名后的gossip 消息 作為身份消息
}
// 異常節(jié)點(diǎn)
func (cs *certStore) suspectPeers(isSuspected api.PeerSuspector) {
cs.idMapper.SuspectPeers(isSuspected)
}
// 關(guān)閉證書存儲(chǔ): 獲取中間代理關(guān)閉卦洽、公鑰和身份映射關(guān)閉
func (cs *certStore) stop() {
cs.pull.Stop()
cs.idMapper.Stop()
}