java隨記

          堅持就是勝利!

           

          Fabric 1.1源代碼分析(4) msp初始化過程

           (MSP)是一個提供虛擬成員操作的管理框架的組件。
          MSP抽取出簽發和驗證證書以及用戶認證背后的所有加密機制和協議。 MSP可以定義自己的身份概念,以及這些身份管理的規則(身份驗證)和身份驗證(簽名生成和驗證)。

          1、MSP接口定義
          // MSP is the minimal Membership Service Provider Interface to be implemented
          // to accommodate peer functionality
          //最基本成員服務接口 其實現在mspimp.go文件中
          type MSP interface {
          // IdentityDeserializer interface needs to be implemented by MSP
          IdentityDeserializer
          // Setup the MSP instance according to configuration information
          Setup(config *msp.MSPConfig) error
          // GetVersion returns the version of this MSP
          GetVersion() MSPVersion
          // GetType returns the provider type
          GetType() ProviderType
          // GetIdentifier returns the provider identifier
          GetIdentifier() (string, error)
          // GetSigningIdentity returns a signing identity corresponding to the provided identifier
          GetSigningIdentity(identifier *IdentityIdentifier) (SigningIdentity, error)
          // GetDefaultSigningIdentity returns the default signing identity
          GetDefaultSigningIdentity() (SigningIdentity, error)
          // GetTLSRootCerts returns the TLS root certificates for this MSP
          GetTLSRootCerts() [][]byte
          // GetTLSIntermediateCerts returns the TLS intermediate root certificates for this MSP
          GetTLSIntermediateCerts() [][]byte
          // Validate checks whether the supplied identity is valid
          Validate(id Identity) error
          // SatisfiesPrincipal checks whether the identity matches
          // the description supplied in MSPPrincipal. The check may
          // involve a byte-by-byte comparison (if the principal is
          // a serialized identity) or may require MSP validation
          SatisfiesPrincipal(id Identity, principal *msp.MSPPrincipal) error
          }
          2、 BCCSP接口定義 BCCSP是加、解密及簽名服務。 bccp.go文件中默認實現是sw/impl.go .
          支持ecdsa、rsa以及aes算法 BCCSP的實現包括:
          1,[sw]目錄為the software-based implementation of the BCCSP,即基于軟件的BCCSP實現,通過調用go原生支持的密碼算法實現,并提供keystore來保存密鑰
          2,[pkcs11]目錄,為bccsp的pkcs11實現,通過調用pkcs11接口實現相關加密操作,,密碼保存在pkcs11通過pin口令保護的數據庫或者硬件設備中。
          type BCCSP interface {
              KeyGen(opts KeyGenOpts) (k Key, err error) //生成Key
              KeyDeriv(k Key, opts KeyDerivOpts) (dk Key, err error) //派生Key
              KeyImport(raw interface{}, opts KeyImportOpts) (k Key, err error) //導入Key
              GetKey(ski []byte) (k Key, err error) //獲取Key
              Hash(msg []byte, opts HashOpts) (hash []byte, err error) //哈希msg
              GetHash(opts HashOpts) (h hash.Hash, err error) //獲取哈希實例
              Sign(k Key, digest []byte, opts SignerOpts) (signature []byte, err error) //簽名
              Verify(k Key, signature, digest []byte, opts SignerOpts) (valid bool, err error) //校驗簽名
              Encrypt(k Key, plaintext []byte, opts EncrypterOpts) (ciphertext []byte, err error) //加密
              Decrypt(k Key, ciphertext []byte, opts DecrypterOpts) (plaintext []byte, err error) //解密
          }
          //代碼在bccsp/bccsp.go
          3、KeyStore接口(密鑰存儲)定義如下: 其實現是bccsp/sw/fileks.go
          type KeyStore interface {
              ReadOnly() bool //密鑰庫是否只讀,只讀時StoreKey將失敗
              GetKey(ski []byte) (k Key, err error) //如果SKI通過,返回Key.從相關文件中加載 
            StoreKey(k Key) (err error) //將Key存儲到密鑰庫中 sw實現是寫入相關文件
          }
          //代碼在bccsp/keystore.go
          bccsp/sw/fileks.go中 StoreKey的實現 可見相關key寫入文件
          func (ks *fileBasedKeyStore) StoreKey(k bccsp.Key) (err error) {
          if ks.readOnly {
          return errors.New("Read only KeyStore.")
          }
          if k == nil {
          return errors.New("Invalid key. It must be different from nil.")
          }
          switch k.(type) {
          case *ecdsaPrivateKey:
          kk := k.(*ecdsaPrivateKey)
          err = ks.storePrivateKey(hex.EncodeToString(k.SKI()), kk.privKey)
          if err != nil {
          return fmt.Errorf("Failed storing ECDSA private key [%s]", err)
          }
          case *ecdsaPublicKey:
          kk := k.(*ecdsaPublicKey)
          err = ks.storePublicKey(hex.EncodeToString(k.SKI()), kk.pubKey)
          if err != nil {
          return fmt.Errorf("Failed storing ECDSA public key [%s]", err)
          }
          case *rsaPrivateKey:
          kk := k.(*rsaPrivateKey)
          err = ks.storePrivateKey(hex.EncodeToString(k.SKI()), kk.privKey)
          if err != nil {
          return fmt.Errorf("Failed storing RSA private key [%s]", err)
          }
          case *rsaPublicKey:
          kk := k.(*rsaPublicKey)
          err = ks.storePublicKey(hex.EncodeToString(k.SKI()), kk.pubKey)
          if err != nil {
          return fmt.Errorf("Failed storing RSA public key [%s]", err)
          }
          case *aesPrivateKey:
          kk := k.(*aesPrivateKey)
          err = ks.storeKey(hex.EncodeToString(k.SKI()), kk.privKey)
          if err != nil {
          return fmt.Errorf("Failed storing AES key [%s]", err)
          }
          4、mspconfig的初始化流程圖
          其中getMspConfig方法比較重要.也一目了然,加載相關證書存入byte[].最終串行化成json
          func getMspConfig(dir string, ID string, sigid *msp.SigningIdentityInfo) (*msp.MSPConfig, error) {
          ///data/config/hyperledger/fabric/crypto-config/peerOrganizations/org1.ygsoft.com/peers/peer0.org1.ygsoft.com/msp/cacerts
          cacertDir := filepath.Join(dir, cacerts)
          ///data/config/hyperledger/fabric/crypto-config/peerOrganizations/org1.ygsoft.com/peers/peer0.org1.ygsoft.com/msp/admincerts
          admincertDir := filepath.Join(dir, admincerts)
          // //data/config/hyperledger/fabric/crypto-config/peerOrganizations/org1.ygsoft.com/peers/peer0.org1.ygsoft.com/msp/ntermediatecerts
          intermediatecertsDir := filepath.Join(dir, intermediatecerts)
          ///data/config/hyperledger/fabric/crypto-config/peerOrganizations/org1.ygsoft.com/peers/peer0.org1.ygsoft.com/msp/crls
          crlsDir := filepath.Join(dir, crlsfolder)
          configFile := filepath.Join(dir, configfilename)
          ///data/config/hyperledger/fabric/crypto-config/peerOrganizations/org1.ygsoft.com/peers/peer0.org1.ygsoft.com/msp/tlscacerts
          tlscacertDir := filepath.Join(dir, tlscacerts)
          tlsintermediatecertsDir := filepath.Join(dir, tlsintermediatecerts)
          cacerts, err := getPemMaterialFromDir(cacertDir)
          if err != nil || len(cacerts) == 0 {
          return nil, errors.WithMessage(err, fmt.Sprintf("could not load a valid ca certificate from directory %s", cacertDir))
          }
          admincert, err := getPemMaterialFromDir(admincertDir)
          if err != nil || len(admincert) == 0 {
          return nil, errors.WithMessage(err, fmt.Sprintf("could not load a valid admin certificate from directory %s", admincertDir))
          }
          intermediatecerts, err := getPemMaterialFromDir(intermediatecertsDir)
          if os.IsNotExist(err) {
          mspLogger.Debugf("Intermediate certs folder not found at [%s]. Skipping. [%s]", intermediatecertsDir, err)
          } else if err != nil {
          return nil, errors.WithMessage(err, fmt.Sprintf("failed loading intermediate ca certs at [%s]", intermediatecertsDir))
          }
          tlsCACerts, err := getPemMaterialFromDir(tlscacertDir)
          tlsIntermediateCerts := [][]byte{}
          if os.IsNotExist(err) {
          mspLogger.Debugf("TLS CA certs folder not found at [%s]. Skipping and ignoring TLS intermediate CA folder. [%s]", tlsintermediatecertsDir, err)
          } else if err != nil {
          return nil, errors.WithMessage(err, fmt.Sprintf("failed loading TLS ca certs at [%s]", tlsintermediatecertsDir))
          } else if len(tlsCACerts) != 0 {
          tlsIntermediateCerts, err = getPemMaterialFromDir(tlsintermediatecertsDir)
          if os.IsNotExist(err) {
          mspLogger.Debugf("TLS intermediate certs folder not found at [%s]. Skipping. [%s]", tlsintermediatecertsDir, err)
          } else if err != nil {
          return nil, errors.WithMessage(err, fmt.Sprintf("failed loading TLS intermediate ca certs at [%s]", tlsintermediatecertsDir))
          }
          } else {
          mspLogger.Debugf("TLS CA certs folder at [%s] is empty. Skipping.", tlsintermediatecertsDir)
          }
          crls, err := getPemMaterialFromDir(crlsDir)
          if os.IsNotExist(err) {
          mspLogger.Debugf("crls folder not found at [%s]. Skipping. [%s]", crlsDir, err)
          } else if err != nil {
          return nil, errors.WithMessage(err, fmt.Sprintf("failed loading crls at [%s]", crlsDir))
          }
          // Load configuration file
          // if the configuration file is there then load it
          // otherwise skip it
          //加載配置文件  ../msp/config.yaml 存在就加載,不存在就跳過
          var ouis []*msp.FabricOUIdentifier
          var nodeOUs *msp.FabricNodeOUs
          _, err = os.Stat(configFile)
          if err == nil {
          // load the file, if there is a failure in loading it then
          // return an error
          raw, err := ioutil.ReadFile(configFile)
          if err != nil {
          return nil, errors.Wrapf(err, "failed loading configuration file at [%s]", configFile)
          }
          configuration := Configuration{}
          err = yaml.Unmarshal(raw, &configuration)
          if err != nil {
          return nil, errors.Wrapf(err, "failed unmarshalling configuration file at [%s]", configFile)
          }
          // Prepare OrganizationalUnitIdentifiers
          if len(configuration.OrganizationalUnitIdentifiers) > 0 {
          for _, ouID := range configuration.OrganizationalUnitIdentifiers {
          f := filepath.Join(dir, ouID.Certificate)
          raw, err = readFile(f)
          if err != nil {
          return nil, errors.Wrapf(err, "failed loading OrganizationalUnit certificate at [%s]", f)
          }
          oui := &msp.FabricOUIdentifier{
          Certificate:                  raw,
          OrganizationalUnitIdentifier: ouID.OrganizationalUnitIdentifier,
          }
          ouis = append(ouis, oui)
          }
          }
          // Prepare NodeOUs
          if configuration.NodeOUs != nil && configuration.NodeOUs.Enable {
          mspLogger.Info("Loading NodeOUs")
          if configuration.NodeOUs.ClientOUIdentifier == nil || len(configuration.NodeOUs.ClientOUIdentifier.OrganizationalUnitIdentifier) == 0 {
          return nil, errors.New("Failed loading NodeOUs. ClientOU must be different from nil.")
          }
          if configuration.NodeOUs.PeerOUIdentifier == nil || len(configuration.NodeOUs.PeerOUIdentifier.OrganizationalUnitIdentifier) == 0 {
          return nil, errors.New("Failed loading NodeOUs. PeerOU must be different from nil.")
          }
          nodeOUs = &msp.FabricNodeOUs{
          Enable:             configuration.NodeOUs.Enable,
          ClientOUIdentifier: &msp.FabricOUIdentifier{OrganizationalUnitIdentifier: configuration.NodeOUs.ClientOUIdentifier.OrganizationalUnitIdentifier},
          PeerOUIdentifier:   &msp.FabricOUIdentifier{OrganizationalUnitIdentifier: configuration.NodeOUs.PeerOUIdentifier.OrganizationalUnitIdentifier},
          }
          // Read certificates, if defined
          // ClientOU
          f := filepath.Join(dir, configuration.NodeOUs.ClientOUIdentifier.Certificate)
          raw, err = readFile(f)
          if err != nil {
          mspLogger.Infof("Failed loading ClientOU certificate at [%s]: [%s]", f, err)
          } else {
          nodeOUs.ClientOUIdentifier.Certificate = raw
          }
          // PeerOU
          f = filepath.Join(dir, configuration.NodeOUs.PeerOUIdentifier.Certificate)
          raw, err = readFile(f)
          if err != nil {
          mspLogger.Debugf("Failed loading PeerOU certificate at [%s]: [%s]", f, err)
          } else {
          nodeOUs.PeerOUIdentifier.Certificate = raw
          }
          }
          } else {
          mspLogger.Debugf("MSP configuration file not found at [%s]: [%s]", configFile, err)
          }
          // Set FabricCryptoConfig
          cryptoConfig := &msp.FabricCryptoConfig{
          SignatureHashFamily:            bccsp.SHA2,
          IdentityIdentifierHashFunction: bccsp.SHA256,
          }
          // Compose FabricMSPConfig
          fmspconf := &msp.FabricMSPConfig{
          Admins:            admincert,
          RootCerts:         cacerts,
          IntermediateCerts: intermediatecerts,
          SigningIdentity:   sigid,
          Name:              ID,
          OrganizationalUnitIdentifiers: ouis,
          RevocationList:                crls,
          CryptoConfig:                  cryptoConfig,
          TlsRootCerts:                  tlsCACerts,
          TlsIntermediateCerts:          tlsIntermediateCerts,
          FabricNodeOUs:                 nodeOUs,
          }
              //串行化成json格式的byte[] 
          fmpsjs, _ := proto.Marshal(fmspconf)
           
          //MSPConfig的msp_config.pb.go文件中定義 
              //type MSPConfig struct {
          //Type int32 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"`
          //Config []byte `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"`
              //}
          mspconf := &msp.MSPConfig{Config: fmpsjs, Type: int32(FABRIC)}
          return mspconf, nil
          msp/mspimplsetup.go文件中根據上面生成的mspconf對證書進行了相關設置,結果保存
          在/mspimpl.go中的結體bccspmsp中
          func (msp *bccspmsp) preSetupV1(conf *m.FabricMSPConfig) error {
          // setup crypto config
          if err := msp.setupCrypto(conf); err != nil {
          return err
          }
          // Setup CAs  //設置ca證書,中間證書等,涉及到x509包。并構建相關identity類。
          //根據證書內容加hash后生成identity類
          if err := msp.setupCAs(conf); err != nil {
          return err
          }
          // Setup Admins
          if err := msp.setupAdmins(conf); err != nil {
          return err
          }
          // Setup CRLs
          if err := msp.setupCRLs(conf); err != nil {
          return err
          }
          // Finalize setup of the CAs
          if err := msp.finalizeSetupCAs(conf); err != nil {
          return err
          }
          // setup the signer (if present)
          if err := msp.setupSigningIdentity(conf); err != nil {
          return err
          }
          // setup TLS CAs
          if err := msp.setupTLSCAs(conf); err != nil {
          return err
          }
          // setup the OUs
          if err := msp.setupOUs(conf); err != nil {
          return err
          }
          return nil
          }

          posted on 2018-06-25 09:00 傻 瓜 閱讀(1453) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          導航

          統計

          常用鏈接

          留言簿(7)

          我參與的團隊

          隨筆分類

          隨筆檔案

          文章分類

          友情鏈接

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 濉溪县| 甘谷县| 鄂伦春自治旗| 宝应县| 宜丰县| 拉萨市| 霸州市| 响水县| 扎赉特旗| 五原县| 手游| 雅安市| 云南省| 莲花县| 蚌埠市| 麻阳| 息烽县| 登封市| 涞源县| 贡觉县| 新蔡县| 偏关县| 岑溪市| 海原县| 吉安市| 古蔺县| 读书| 安图县| 商城县| 柳州市| 陇南市| 巍山| 徐水县| 大城县| 福海县| 崇明县| 静安区| 容城县| 噶尔县| 安顺市| 济源市|