区块链-HyperLedger Fabric

HyperLedgerFabric源码解读(3)-certsto

2018-11-20  本文已影响7人  神奇的考拉

关于gossip中证书/身份存储的内容
package gossip

// 传播所有的身份信息
// certStore supports pull dissemination of identity messages
type certStore struct {
    selfIdentity api.PeerIdentityType   // peer自身的身份
    idMapper     identity.Mapper        // 公钥和身份的映射关系:公钥PKIid :身份
    pull         pull.Mediator          // 获取消息中介
    logger       util.Logger
    mcs          api.MessageCryptoService // 信息加密服务
}
// 新建身份存储
func newCertStore(puller pull.Mediator,     // PullEngine的包装类 提供获取同步相关的方法
    idMapper identity.Mapper,               // <PKIid, Certificates/identifies> 公钥ID 与 证书或身份的映射
    selfIdentity api.PeerIdentityType,      // 自身标识
    mcs api.MessageCryptoService) *certStore {  // 信息加密服务
    // 获取对应身份的公钥UD
    selfPKIID := idMapper.GetPKIidOfCert(selfIdentity)
    //
    logger := util.GetLogger(util.LoggingGossipModule, string(selfPKIID))

    certStore := &certStore{
        mcs:          mcs,              // 信息加密服务
        pull:         puller,           // 获取者
        idMapper:     idMapper,         // 本地公钥、身份/证书映射器
        selfIdentity: selfIdentity,     // 自身标识
        logger:       logger,
    }
    // 添加自身公钥ID与身份的关联关系
    if err := certStore.idMapper.Put(selfPKIID, selfIdentity); err != nil {
        certStore.logger.Panicf("Failed associating self PKIID to cert: %+v", errors.WithStack(err))
    }

    // 创建身份信息
    selfIDMsg, err := certStore.createIdentityMessage()
    if err != nil {
        certStore.logger.Panicf("Failed creating self identity message: %+v", errors.WithStack(err))
    }
    // 添加到获取中间代理上 并将注册一个钩子到指定类型的消息(RegisterMsgHook)
    puller.Add(selfIDMsg)
    puller.RegisterMsgHook(pull.RequestMsgType, func(_ []string, msgs []*proto.SignedGossipMessage, _ proto.ReceivedMessage) {
        // 遍历签名的Gossip Message 获取每个消息里面的每个对等节点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的更新数据
    if update := msg.GetGossipMessage().GetDataUpdate(); update != nil {
        // 提取更新的数据 并解码Envelope转为对应的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
            }
            // 转换的签名gossip message是否是身份信息
            if !m.IsIdentityMsg() {
                cs.logger.Warning("Got a non-identity message:", m, "aborting")
                return
            }
            // 检验身份信息的有效性
            if err := cs.validateIdentityMsg(m); err != nil {
                cs.logger.Warningf("Failed validating identity message: %+v", errors.WithStack(err))
                return
            }
        }
    }
    // 通过获取中间代理处理消息
    cs.pull.HandleMessage(msg)
}
// 验证身份消息
func (cs *certStore) validateIdentityMsg(msg *proto.SignedGossipMessage) error {
    // 从签名消息SignedGossipMessage中提取对等节点peer的身份
    idMsg := msg.GetPeerIdentity()
    if idMsg == nil {
        return errors.Errorf("Identity empty: %+v", msg)
    }
    // 提取对等节点peer身份信息中的公钥ID
    pkiID := idMsg.PkiId
    // 提取对等节点peer身份信息中的证书
    cert := idMsg.Cert
    // 根据对等节点peer的身份类型提取对应的证书公钥ID
    calculatedPKIID := cs.mcs.GetPKIidOfCert(api.PeerIdentityType(cert))
    // 声明的公钥ID
    claimedPKIID := common.PKIidType(pkiID)
    // 对比计算的公钥ID  和 声明的公钥id进行比较,判断计算的公钥ID是否与对等节点peer的身份信息的内容匹配
    if !bytes.Equal(calculatedPKIID, claimedPKIID) {
        return errors.Errorf("Calculated pkiID doesn't match identity: calculated: %v, claimedPKI-ID: %v", calculatedPKIID, claimedPKIID)
    }

    // 定义检验函数:通过消息加密服务(Message Crypto Service )
    verifier := func(peerIdentity []byte, signature, message []byte) error {
        return cs.mcs.Verify(api.PeerIdentityType(peerIdentity), signature, message)
    }

    // 检验消息
    err := msg.Verify(cert, verifier)
    if err != nil {
        return errors.Wrap(err, "Failed verifying message")
    }
    // 验证身份
    return cs.mcs.ValidateIdentity(api.PeerIdentityType(idMsg.Cert))
}
// 创建身份消息
func (cs *certStore) createIdentityMessage() (*proto.SignedGossipMessage, error) {
    // 对等节点身份
    pi := &proto.PeerIdentity{
        Cert:     cs.selfIdentity,   // 自身身份(标识)
        Metadata: nil,               // 元数据
        PkiId:    cs.idMapper.GetPKIidOfCert(cs.selfIdentity), // 从映射表中获取公钥ID
    }
    // Gossip消息
    m := &proto.GossipMessage{
        Channel: nil,                       // 通道
        Nonce:   0,                         //
        Tag:     proto.GossipMessage_EMPTY, // gossip message的标记
        Content: &proto.GossipMessage_PeerIdentity{  // 对等节点身份Gossip消息的内容:对等节点身份内容
            PeerIdentity: pi,
        },
    }
    signer := func(msg []byte) ([]byte, error) {  // 消息签名函数
        return cs.idMapper.Sign(msg)
    }
    sMsg := &proto.SignedGossipMessage{          // 签名后的gossip message
        GossipMessage: m,
    }
    _, err := sMsg.Sign(signer)                 // 绑定签名和消息
    return sMsg, errors.WithStack(err)         // 返回签名后的gossip 消息 作为身份消息
}
// 异常节点
func (cs *certStore) suspectPeers(isSuspected api.PeerSuspector) {
    cs.idMapper.SuspectPeers(isSuspected)
}
// 关闭证书存储: 获取中间代理关闭、公钥和身份映射关闭
func (cs *certStore) stop() {
    cs.pull.Stop()
    cs.idMapper.Stop()
}
上一篇下一篇

猜你喜欢

热点阅读