// 从SignatureHeader交易客户端的签名 // validate the signature err = checkSignatureFromCreator(shdr.Creator, signedProp.Signature, signedProp.ProposalBytes, chdr.ChannelId) if err != nil { // log the exact message on the peer but return a generic error message to // avoid malicious users scanning for channels putilsLogger.Warningf("channel [%s]: %s", chdr.ChannelId, err) sId := &msp.SerializedIdentity{} err := proto.Unmarshal(shdr.Creator, sId) if err != nil { // log the error here as well but still only return the generic error err = errors.Wrap(err, "could not deserialize a SerializedIdentity") putilsLogger.Warningf("channel [%s]: %s", chdr.ChannelId, err) } returnnil, nil, nil, errors.Errorf("access denied: channel [%s] creator org [%s]", chdr.ChannelId, sId.Mspid) } }
// ValidateTransaction checks that the transaction envelope is properly formed funcValidateTransaction(e *common.Envelope, c channelconfig.ApplicationCapabilities)(*common.Payload, pb.TxValidationCode) { putilsLogger.Debugf("ValidateTransactionEnvelope starts for envelope %p", e)
// validate the signature in the envelope err = checkSignatureFromCreator(shdr.Creator, e.Signature, e.Payload, chdr.ChannelId) if err != nil { putilsLogger.Errorf("checkSignatureFromCreator returns err %s", err) returnnil, pb.TxValidationCode_BAD_CREATOR_SIGNATURE }
// continue the validation in a way that depends on the type specified in the header switch common.HeaderType(chdr.Type) { case common.HeaderType_ENDORSER_TRANSACTION: // Verify that the transaction ID has been computed properly. // This check is needed to ensure that the lookup into the ledger // for the same TxID catches duplicates. err = utils.CheckTxID( chdr.TxId, shdr.Nonce, shdr.Creator)
// given a creator, a message and a signature, // this function returns nil if the creator // is a valid cert and the signature is valid funccheckSignatureFromCreator(creatorBytes []byte, sig []byte, msg []byte, ChainID string)error { putilsLogger.Debugf("begin")
// check for nil argument if creatorBytes == nil || sig == nil || msg == nil { return errors.New("nil arguments") }
// 每个链有各自的msp mspObj := mspmgmt.GetIdentityDeserializer(ChainID) if mspObj == nil { return errors.Errorf("could not get msp for channel [%s]", ChainID) }
putilsLogger.Debugf("creator is %s", creator.GetIdentifier())
// 验证证书是否有效 // ensure that creator is a valid certificate err = creator.Validate() if err != nil { return errors.WithMessage(err, "creator certificate is not valid") }
putilsLogger.Debugf("creator is valid")
// validate the signature // 验证签名 err = creator.Verify(msg, sig) if err != nil { return errors.WithMessage(err, "creator's signature over the proposal is not valid") }
// GetIdentityDeserializer returns the IdentityDeserializer for the given chain funcGetIdentityDeserializer(chainID string)msp.IdentityDeserializer { if chainID == "" { return GetLocalMSP() }
return GetManagerForChain(chainID) }
// GetManagerForChain returns the msp manager for the supplied // chain; if no such manager exists, one is created funcGetManagerForChain(chainID string)msp.MSPManager { m.Lock() defer m.Unlock()
// 先从缓存查找 mspMgr, ok := mspMap[chainID] if !ok { // 找不到则新建立当前通道Msp manager mspLogger.Debugf("Created new msp manager for channel `%s`", chainID) mspMgmtMgr := &mspMgmtMgr{msp.NewMSPManager(), false} mspMap[chainID] = mspMgmtMgr mspMgr = mspMgmtMgr } else { // check for internal mspManagerImpl and mspMgmtMgr types. if a different // type is found, it's because a developer has added a new type that // implements the MSPManager interface and should add a case to the logic // above to handle it. if !(reflect.TypeOf(mspMgr).Elem().Name() == "mspManagerImpl" || reflect.TypeOf(mspMgr).Elem().Name() == "mspMgmtMgr") { panic("Found unexpected MSPManager type.") } mspLogger.Debugf("Returning existing manager for channel '%s'", chainID) } return mspMgr }
// MSPManager has been setup for a channel, which indicates whether the channel // exists or not type mspMgmtMgr struct { msp.MSPManager // track whether this MSPManager has been setup successfully up bool }
// DeserializeIdentity returns an identity given its serialized version supplied as argument func(mgr *mspManagerImpl)DeserializeIdentity(serializedID []byte)(Identity, error) { // We first deserialize to a SerializedIdentity to get the MSP ID sId := &msp.SerializedIdentity{} err := proto.Unmarshal(serializedID, sId) if err != nil { returnnil, errors.Wrap(err, "could not deserialize a SerializedIdentity") }
// 获取发送方的msp实例 // we can now attempt to obtain the MSP msp := mgr.mspsMap[sId.Mspid] if msp == nil { returnnil, errors.Errorf("MSP %s is unknown", sId.Mspid) }
switch t := msp.(type) { case *bccspmsp: return t.deserializeIdentityInternal(sId.IdBytes) case *idemixmsp: return t.deserializeIdentityInternal(sId.IdBytes) default: return t.DeserializeIdentity(serializedID) } }
// 反序列化二进制,得到证书,然后用证书获取公钥,使用证书、公钥和msp,创建Identity // deserializeIdentityInternal returns an identity given its byte-level representation func(msp *bccspmsp)deserializeIdentityInternal(serializedIdentity []byte)(Identity, error) { // This MSP will always deserialize certs this way bl, _ := pem.Decode(serializedIdentity) if bl == nil { returnnil, errors.New("could not decode the PEM structure") } cert, err := x509.ParseCertificate(bl.Bytes) if err != nil { returnnil, errors.Wrap(err, "parseCertificate failed") }
// Now we have the certificate; make sure that its fields // (e.g. the Issuer.OU or the Subject.OU) match with the // MSP id that this MSP has; otherwise it might be an attack // TODO! // We can't do it yet because there is no standardized way // (yet) to encode the MSP ID into the x.509 body of a cert
// 从证书中提取公钥,封装一下,满足bccsp.Key接口 pub, err := msp.bccsp.KeyImport(cert, &bccsp.X509PublicKeyImportOpts{Temporary: true}) if err != nil { returnnil, errors.WithMessage(err, "failed to import certificate's public key") }
type identity struct { // id contains the identifier (MSPID and identity identifier) for this instance id *IdentityIdentifier
// cert contains the x.509 certificate that signs the public key of this instance cert *x509.Certificate
// this is the public key of this instance pk bccsp.Key
// reference to the MSP that "owns" this identity msp *bccspmsp }
funcnewIdentity(cert *x509.Certificate, pk bccsp.Key, msp *bccspmsp)(Identity, error) { if mspIdentityLogger.IsEnabledFor(zapcore.DebugLevel) { mspIdentityLogger.Debugf("Creating identity instance for cert %s", certToPEM(cert)) }
// 检查证书 // Sanitize first the certificate cert, err := msp.sanitizeCert(cert) if err != nil { returnnil, err }
// Compute identity identifier
// Use the hash of the identity's certificate as id in the IdentityIdentifier hashOpt, err := bccsp.GetHashOpt(msp.cryptoConfig.IdentityIdentifierHashFunction) if err != nil { returnnil, errors.WithMessage(err, "failed getting hash function options") }
digest, err := msp.bccsp.Hash(cert.Raw, hashOpt) if err != nil { returnnil, errors.WithMessage(err, "failed hashing raw certificate to compute the id of the IdentityIdentifier") }
id := &IdentityIdentifier{ Mspid: msp.name, Id: hex.EncodeToString(digest)}
// Verify checks against a signature and a message // to determine whether this identity produced the // signature; it returns nil if so or an error otherwise func(id *identity)Verify(msg []byte, sig []byte)error { // mspIdentityLogger.Infof("Verifying signature")
// Compute Hash hashOpt, err := id.getHashOpt(id.msp.cryptoConfig.SignatureHashFamily) if err != nil { return errors.WithMessage(err, "failed getting hash function options") }
// SignatureHeaderMaker creates a new SignatureHeader type SignatureHeaderMaker interface { // NewSignatureHeader creates a SignatureHeader with the correct signing identity and a valid nonce NewSignatureHeader() (*cb.SignatureHeader, error) }