github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-config/configtx/msp.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package configtx
     8  
     9  import (
    10  	"crypto"
    11  	"crypto/rand"
    12  	"encoding/asn1"
    13  	"encoding/pem"
    14  	"fmt"
    15  	"github.com/hellobchain/newcryptosm/x509"
    16  	"github.com/hellobchain/newcryptosm/x509/pkix"
    17  	"github.com/hellobchain/third_party/algo"
    18  	"github.com/hellobchain/third_party/hyperledger/fabric-config/configtx/membership"
    19  	"github.com/hellobchain/third_party/hyperledger/fabric/bccsp"
    20  	"reflect"
    21  	"time"
    22  
    23  	"github.com/golang/protobuf/proto"
    24  	cb "github.com/hyperledger/fabric-protos-go/common"
    25  	mb "github.com/hyperledger/fabric-protos-go/msp"
    26  )
    27  
    28  // MSP is the configuration information for a Fabric MSP.
    29  // Here we assume a default certificate validation policy, where
    30  // any certificate signed by any of the listed rootCA certs would
    31  // be considered as valid under this MSP.
    32  // This MSP may or may not come with a signing identity. If it does,
    33  // it can also issue signing identities. If it does not, it can only
    34  // be used to validate and verify certificates.
    35  type MSP struct {
    36  	// Name holds the identifier of the MSP; MSP identifier
    37  	// is chosen by the application that governs this MSP.
    38  	// For example, and assuming the default implementation of MSP,
    39  	// that is X.509-based and considers a single Issuer,
    40  	// this can refer to the Subject OU field or the Issuer OU field.
    41  	Name string
    42  	// List of root certificates trusted by this MSP
    43  	// they are used upon certificate validation (see
    44  	// comment for IntermediateCerts below).
    45  	RootCerts []*x509.Certificate
    46  	// List of intermediate certificates trusted by this MSP;
    47  	// they are used upon certificate validation as follows:
    48  	// validation attempts to build a path from the certificate
    49  	// to be validated (which is at one end of the path) and
    50  	// one of the certs in the RootCerts field (which is at
    51  	// the other end of the path). If the path is longer than
    52  	// 2, certificates in the middle are searched within the
    53  	// IntermediateCerts pool.
    54  	IntermediateCerts []*x509.Certificate
    55  	// Identity denoting the administrator of this MSP.
    56  	Admins []*x509.Certificate
    57  	// Identity revocation list.
    58  	RevocationList []*pkix.CertificateList
    59  	// OrganizationalUnitIdentifiers holds one or more
    60  	// fabric organizational unit identifiers that belong to
    61  	// this MSP configuration.
    62  	OrganizationalUnitIdentifiers []membership.OUIdentifier
    63  	// CryptoConfig contains the configuration parameters
    64  	// for the cryptographic algorithms used by this MSP.
    65  	CryptoConfig membership.CryptoConfig
    66  	// List of TLS root certificates trusted by this MSP.
    67  	// They are returned by GetTLSRootCerts.
    68  	TLSRootCerts []*x509.Certificate
    69  	// List of TLS intermediate certificates trusted by this MSP;
    70  	// They are returned by GetTLSIntermediateCerts.
    71  	TLSIntermediateCerts []*x509.Certificate
    72  	// Contains the configuration to distinguish clients
    73  	// from peers from orderers based on the OUs.
    74  	NodeOUs membership.NodeOUs
    75  }
    76  
    77  // YEAR is a time duration for a standard 365 day year.
    78  const YEAR = 365 * 24 * time.Hour
    79  
    80  // OrganizationMSP encapsulates the configuration functions used to modify an organization MSP.
    81  type OrganizationMSP struct {
    82  	configGroup *cb.ConfigGroup
    83  }
    84  
    85  // Configuration returns the MSP value for a organization in the updated config.
    86  func (m *OrganizationMSP) Configuration() (MSP, error) {
    87  	return getMSPConfig(m.configGroup)
    88  }
    89  
    90  // AddAdminCert adds an administator identity to the organization MSP.
    91  func (m *OrganizationMSP) AddAdminCert(cert *x509.Certificate) error {
    92  	msp, err := getMSPConfig(m.configGroup)
    93  	if err != nil {
    94  		return err
    95  	}
    96  
    97  	for _, c := range msp.Admins {
    98  		if c.Equal(cert) {
    99  			return nil
   100  		}
   101  	}
   102  
   103  	msp.Admins = append(msp.Admins, cert)
   104  
   105  	return msp.setConfig(m.configGroup)
   106  }
   107  
   108  // RemoveAdminCert removes an administator identity from the organization MSP.
   109  func (m *OrganizationMSP) RemoveAdminCert(cert *x509.Certificate) error {
   110  	msp, err := getMSPConfig(m.configGroup)
   111  	if err != nil {
   112  		return err
   113  	}
   114  
   115  	certs := msp.Admins[:]
   116  	for i, c := range msp.Admins {
   117  		if c.Equal(cert) {
   118  			certs = append(certs[:i], certs[i+1:]...)
   119  			break
   120  		}
   121  	}
   122  
   123  	msp.Admins = certs
   124  
   125  	return msp.setConfig(m.configGroup)
   126  }
   127  
   128  // AddRootCert adds a root certificate trusted by the organization MSP.
   129  func (m *OrganizationMSP) AddRootCert(cert *x509.Certificate) error {
   130  	msp, err := getMSPConfig(m.configGroup)
   131  	if err != nil {
   132  		return err
   133  	}
   134  
   135  	for _, c := range msp.RootCerts {
   136  		if c.Equal(cert) {
   137  			return nil
   138  		}
   139  	}
   140  
   141  	msp.RootCerts = append(msp.RootCerts, cert)
   142  
   143  	err = msp.validateCACerts()
   144  	if err != nil {
   145  		return err
   146  	}
   147  
   148  	return msp.setConfig(m.configGroup)
   149  }
   150  
   151  // RemoveRootCert removes a trusted root certificate from the organization MSP.
   152  func (m *OrganizationMSP) RemoveRootCert(cert *x509.Certificate) error {
   153  	msp, err := getMSPConfig(m.configGroup)
   154  	if err != nil {
   155  		return err
   156  	}
   157  
   158  	certs := msp.RootCerts[:]
   159  	for i, c := range msp.RootCerts {
   160  		if c.Equal(cert) {
   161  			certs = append(certs[:i], certs[i+1:]...)
   162  			break
   163  		}
   164  	}
   165  
   166  	msp.RootCerts = certs
   167  
   168  	err = msp.validateCACerts()
   169  	if err != nil {
   170  		return err
   171  	}
   172  
   173  	return msp.setConfig(m.configGroup)
   174  }
   175  
   176  // AddIntermediateCert adds an intermediate certificate trusted by the organization MSP.
   177  func (m *OrganizationMSP) AddIntermediateCert(cert *x509.Certificate) error {
   178  	msp, err := getMSPConfig(m.configGroup)
   179  	if err != nil {
   180  		return err
   181  	}
   182  
   183  	for _, c := range msp.IntermediateCerts {
   184  		if c.Equal(cert) {
   185  			return nil
   186  		}
   187  	}
   188  
   189  	msp.IntermediateCerts = append(msp.IntermediateCerts, cert)
   190  
   191  	err = msp.validateCACerts()
   192  	if err != nil {
   193  		return err
   194  	}
   195  
   196  	return msp.setConfig(m.configGroup)
   197  }
   198  
   199  // RemoveIntermediateCert removes a trusted intermediate certificate from the organization MSP.
   200  func (m *OrganizationMSP) RemoveIntermediateCert(cert *x509.Certificate) error {
   201  	msp, err := getMSPConfig(m.configGroup)
   202  	if err != nil {
   203  		return err
   204  	}
   205  
   206  	certs := msp.IntermediateCerts[:]
   207  	for i, c := range msp.IntermediateCerts {
   208  		if c.Equal(cert) {
   209  			certs = append(certs[:i], certs[i+1:]...)
   210  			break
   211  		}
   212  	}
   213  
   214  	msp.IntermediateCerts = certs
   215  
   216  	err = msp.validateCACerts()
   217  	if err != nil {
   218  		return err
   219  	}
   220  
   221  	return msp.setConfig(m.configGroup)
   222  }
   223  
   224  // AddOUIdentifier adds a custom organizational unit identifier to the organization MSP.
   225  func (m *OrganizationMSP) AddOUIdentifier(ou membership.OUIdentifier) error {
   226  	msp, err := getMSPConfig(m.configGroup)
   227  	if err != nil {
   228  		return err
   229  	}
   230  
   231  	for _, o := range msp.OrganizationalUnitIdentifiers {
   232  		if reflect.DeepEqual(o, ou) {
   233  			return nil
   234  		}
   235  	}
   236  
   237  	msp.OrganizationalUnitIdentifiers = append(msp.OrganizationalUnitIdentifiers, ou)
   238  
   239  	return msp.setConfig(m.configGroup)
   240  }
   241  
   242  // RemoveOUIdentifier removes an existing organizational unit identifier from the organization MSP.
   243  func (m *OrganizationMSP) RemoveOUIdentifier(ou membership.OUIdentifier) error {
   244  	msp, err := getMSPConfig(m.configGroup)
   245  	if err != nil {
   246  		return err
   247  	}
   248  
   249  	ous := msp.OrganizationalUnitIdentifiers[:]
   250  	for i, o := range msp.OrganizationalUnitIdentifiers {
   251  		if reflect.DeepEqual(o, ou) {
   252  			ous = append(ous[:i], ous[i+1:]...)
   253  			break
   254  		}
   255  	}
   256  
   257  	msp.OrganizationalUnitIdentifiers = ous
   258  
   259  	return msp.setConfig(m.configGroup)
   260  }
   261  
   262  // SetCryptoConfig sets the configuration for the cryptographic algorithms for the organization MSP.
   263  func (m *OrganizationMSP) SetCryptoConfig(cryptoConfig membership.CryptoConfig) error {
   264  	msp, err := getMSPConfig(m.configGroup)
   265  	if err != nil {
   266  		return err
   267  	}
   268  
   269  	msp.CryptoConfig = cryptoConfig
   270  
   271  	return msp.setConfig(m.configGroup)
   272  }
   273  
   274  // AddTLSRootCert adds a TLS root certificate trusted by the organization MSP.
   275  func (m *OrganizationMSP) AddTLSRootCert(cert *x509.Certificate) error {
   276  	msp, err := getMSPConfig(m.configGroup)
   277  	if err != nil {
   278  		return err
   279  	}
   280  
   281  	for _, c := range msp.TLSRootCerts {
   282  		if c.Equal(cert) {
   283  			return nil
   284  		}
   285  	}
   286  
   287  	msp.TLSRootCerts = append(msp.TLSRootCerts, cert)
   288  
   289  	err = msp.validateCACerts()
   290  	if err != nil {
   291  		return err
   292  	}
   293  
   294  	return msp.setConfig(m.configGroup)
   295  }
   296  
   297  // RemoveTLSRootCert removes a trusted TLS root certificate from the organization MSP.
   298  func (m *OrganizationMSP) RemoveTLSRootCert(cert *x509.Certificate) error {
   299  	msp, err := getMSPConfig(m.configGroup)
   300  	if err != nil {
   301  		return err
   302  	}
   303  
   304  	certs := msp.TLSRootCerts[:]
   305  	for i, c := range msp.TLSRootCerts {
   306  		if c.Equal(cert) {
   307  			certs = append(certs[:i], certs[i+1:]...)
   308  			break
   309  		}
   310  	}
   311  
   312  	msp.TLSRootCerts = certs
   313  
   314  	err = msp.validateCACerts()
   315  	if err != nil {
   316  		return err
   317  	}
   318  
   319  	return msp.setConfig(m.configGroup)
   320  }
   321  
   322  // AddTLSIntermediateCert adds a TLS intermediate cert trusted by the organization MSP.
   323  func (m *OrganizationMSP) AddTLSIntermediateCert(cert *x509.Certificate) error {
   324  	msp, err := getMSPConfig(m.configGroup)
   325  	if err != nil {
   326  		return err
   327  	}
   328  
   329  	for _, c := range msp.TLSIntermediateCerts {
   330  		if c.Equal(cert) {
   331  			return nil
   332  		}
   333  	}
   334  
   335  	msp.TLSIntermediateCerts = append(msp.TLSIntermediateCerts, cert)
   336  
   337  	err = msp.validateCACerts()
   338  	if err != nil {
   339  		return err
   340  	}
   341  
   342  	return msp.setConfig(m.configGroup)
   343  }
   344  
   345  // RemoveTLSIntermediateCert removes a trusted TLS intermediate cert from the organization MSP.
   346  func (m *OrganizationMSP) RemoveTLSIntermediateCert(cert *x509.Certificate) error {
   347  	msp, err := getMSPConfig(m.configGroup)
   348  	if err != nil {
   349  		return err
   350  	}
   351  
   352  	certs := msp.TLSIntermediateCerts[:]
   353  	for i, c := range msp.TLSIntermediateCerts {
   354  		if c.Equal(cert) {
   355  			certs = append(certs[:i], certs[i+1:]...)
   356  			break
   357  		}
   358  	}
   359  
   360  	msp.TLSIntermediateCerts = certs
   361  
   362  	err = msp.validateCACerts()
   363  	if err != nil {
   364  		return err
   365  	}
   366  
   367  	return msp.setConfig(m.configGroup)
   368  }
   369  
   370  // SetClientOUIdentifier sets the NodeOUs client ou identifier for the organization MSP.
   371  func (m *OrganizationMSP) SetClientOUIdentifier(clientOU membership.OUIdentifier) error {
   372  	msp, err := getMSPConfig(m.configGroup)
   373  	if err != nil {
   374  		return err
   375  	}
   376  
   377  	msp.NodeOUs.ClientOUIdentifier = clientOU
   378  
   379  	return msp.setConfig(m.configGroup)
   380  }
   381  
   382  // SetPeerOUIdentifier sets the NodeOUs peer ou identifier for the organization MSP.
   383  func (m *OrganizationMSP) SetPeerOUIdentifier(peerOU membership.OUIdentifier) error {
   384  	msp, err := getMSPConfig(m.configGroup)
   385  	if err != nil {
   386  		return err
   387  	}
   388  
   389  	msp.NodeOUs.PeerOUIdentifier = peerOU
   390  
   391  	return msp.setConfig(m.configGroup)
   392  }
   393  
   394  // SetAdminOUIdentifier sets the NodeOUs admin ou identifier for the organization MSP.
   395  func (m *OrganizationMSP) SetAdminOUIdentifier(adminOU membership.OUIdentifier) error {
   396  	msp, err := getMSPConfig(m.configGroup)
   397  	if err != nil {
   398  		return err
   399  	}
   400  
   401  	msp.NodeOUs.AdminOUIdentifier = adminOU
   402  
   403  	return msp.setConfig(m.configGroup)
   404  }
   405  
   406  // SetOrdererOUIdentifier sets the NodeOUs orderer ou identifier for the organization MSP.
   407  func (m *OrganizationMSP) SetOrdererOUIdentifier(ordererOU membership.OUIdentifier) error {
   408  	msp, err := getMSPConfig(m.configGroup)
   409  	if err != nil {
   410  		return err
   411  	}
   412  
   413  	msp.NodeOUs.OrdererOUIdentifier = ordererOU
   414  
   415  	return msp.setConfig(m.configGroup)
   416  }
   417  
   418  // SetEnableNodeOUs sets the NodeOUs recognition, if NodeOUs recognition is enabled then an msp identity
   419  // that does not contain exactly one of the fabric Node OU Identifiers will be considered invalid.
   420  func (m *OrganizationMSP) SetEnableNodeOUs(isEnabled bool) error {
   421  	msp, err := getMSPConfig(m.configGroup)
   422  	if err != nil {
   423  		return err
   424  	}
   425  
   426  	msp.NodeOUs.Enable = isEnabled
   427  
   428  	return msp.setConfig(m.configGroup)
   429  }
   430  
   431  // AddCRL adds a CRL to the identity revocation list for the organization MSP.
   432  func (m *OrganizationMSP) AddCRL(crl *pkix.CertificateList) error {
   433  	msp, err := getMSPConfig(m.configGroup)
   434  	if err != nil {
   435  		return err
   436  	}
   437  
   438  	msp.RevocationList = append(msp.RevocationList, crl)
   439  
   440  	return msp.setConfig(m.configGroup)
   441  }
   442  
   443  // AddCRLFromSigningIdentity creates a CRL from the provided signing identity and associated certs and then adds the CRL to
   444  // the identity revocation list for the organization MSP.
   445  func (m *OrganizationMSP) AddCRLFromSigningIdentity(signingIdentity *SigningIdentity, certs ...*x509.Certificate) error {
   446  	msp, err := getMSPConfig(m.configGroup)
   447  	if err != nil {
   448  		return err
   449  	}
   450  
   451  	crl, err := msp.CreateMSPCRL(signingIdentity, certs...)
   452  	if err != nil {
   453  		return err
   454  	}
   455  	msp.RevocationList = append(msp.RevocationList, crl)
   456  
   457  	return msp.setConfig(m.configGroup)
   458  }
   459  
   460  // CreateMSPCRL creates a CRL that revokes the provided certificates
   461  // for the specified organization's msp signed by the provided SigningIdentity.
   462  func (m *MSP) CreateMSPCRL(signingIdentity *SigningIdentity, certs ...*x509.Certificate) (*pkix.CertificateList, error) {
   463  	return m.newMSPCRL(signingIdentity, certs...)
   464  }
   465  
   466  // newMSPCRL creates a CRL that revokes the provided certificates for the specified org
   467  // signed by the provided SigningIdentity. If any of the provided certs were
   468  // not signed by any of the root/intermediate CA cets in the MSP configuration,
   469  // it will return an error.
   470  func (m *MSP) newMSPCRL(signingIdentity *SigningIdentity, certs ...*x509.Certificate) (*pkix.CertificateList, error) {
   471  	if err := m.validateCertificates(signingIdentity.Certificate, certs...); err != nil {
   472  		return nil, err
   473  	}
   474  
   475  	revokeTime := time.Now().UTC()
   476  
   477  	revokedCertificates := make([]pkix.RevokedCertificate, len(certs))
   478  	for i, cert := range certs {
   479  		revokedCertificates[i] = pkix.RevokedCertificate{
   480  			SerialNumber:   cert.SerialNumber,
   481  			RevocationTime: revokeTime,
   482  		}
   483  	}
   484  
   485  	crlBytes, err := signingIdentity.Certificate.CreateCRL(rand.Reader, signingIdentity.PrivateKey, revokedCertificates, revokeTime, revokeTime.Add(YEAR))
   486  	if err != nil {
   487  		return nil, err
   488  	}
   489  
   490  	crl, err := x509.ParseCRL(crlBytes)
   491  	if err != nil {
   492  		return nil, err
   493  	}
   494  
   495  	return crl, nil
   496  }
   497  
   498  // validateCertificates first validates that the signing certificate is either
   499  // a root or intermediate CA certificate for the specified application org. It
   500  // then validates that the certificates to add to the CRL were signed by that
   501  // signing certificate.
   502  func (m *MSP) validateCertificates(signingCert *x509.Certificate, certs ...*x509.Certificate) error {
   503  	err := m.isCACert(signingCert)
   504  	if err != nil {
   505  		return err
   506  	}
   507  	for _, cert := range certs {
   508  		if err := cert.CheckSignatureFrom(signingCert); err != nil {
   509  			return fmt.Errorf("certificate not issued by this MSP. serial number: %d", cert.SerialNumber)
   510  		}
   511  	}
   512  
   513  	return nil
   514  }
   515  
   516  func (m *MSP) isCACert(signingCert *x509.Certificate) error {
   517  	for _, rootCert := range m.RootCerts {
   518  		if signingCert.Equal(rootCert) {
   519  			return nil
   520  		}
   521  	}
   522  
   523  	for _, intermediateCert := range m.IntermediateCerts {
   524  		if signingCert.Equal(intermediateCert) {
   525  			return nil
   526  		}
   527  	}
   528  	return fmt.Errorf("signing cert is not a root/intermediate cert for this MSP: %s", m.Name)
   529  }
   530  
   531  func (m *MSP) setConfig(configGroup *cb.ConfigGroup) error {
   532  	mspConfig, err := newMSPConfig(*m)
   533  	if err != nil {
   534  		return fmt.Errorf("new msp config: %v", err)
   535  	}
   536  
   537  	err = setValue(configGroup, mspValue(mspConfig), AdminsPolicyKey)
   538  	if err != nil {
   539  		return err
   540  	}
   541  
   542  	return nil
   543  }
   544  
   545  // getMSPConfig parses the MSP value in a config group returns
   546  // the configuration as an MSP type.
   547  func getMSPConfig(configGroup *cb.ConfigGroup) (MSP, error) {
   548  	mspValueProto := &mb.MSPConfig{}
   549  
   550  	err := unmarshalConfigValueAtKey(configGroup, MSPKey, mspValueProto)
   551  	if err != nil {
   552  		return MSP{}, err
   553  	}
   554  
   555  	fabricMSPConfig := &mb.FabricMSPConfig{}
   556  
   557  	err = proto.Unmarshal(mspValueProto.Config, fabricMSPConfig)
   558  	if err != nil {
   559  		return MSP{}, fmt.Errorf("unmarshaling fabric msp config: %v", err)
   560  	}
   561  
   562  	if algo.GetGMFlag() {
   563  		cryptoConfig := &mb.FabricCryptoConfig{
   564  			SignatureHashFamily:            bccsp.SM,
   565  			IdentityIdentifierHashFunction: bccsp.SM3,
   566  		}
   567  		fabricMSPConfig.CryptoConfig = cryptoConfig
   568  	}
   569  
   570  	// ROOT CERTS
   571  	rootCerts, err := parseCertificateListFromBytes(fabricMSPConfig.RootCerts)
   572  	if err != nil {
   573  		return MSP{}, fmt.Errorf("parsing root certs: %v", err)
   574  	}
   575  
   576  	// INTERMEDIATE CERTS
   577  	intermediateCerts, err := parseCertificateListFromBytes(fabricMSPConfig.IntermediateCerts)
   578  	if err != nil {
   579  		return MSP{}, fmt.Errorf("parsing intermediate certs: %v", err)
   580  	}
   581  
   582  	// ADMIN CERTS
   583  	adminCerts, err := parseCertificateListFromBytes(fabricMSPConfig.Admins)
   584  	if err != nil {
   585  		return MSP{}, fmt.Errorf("parsing admin certs: %v", err)
   586  	}
   587  
   588  	// REVOCATION LIST
   589  	revocationList, err := parseCRL(fabricMSPConfig.RevocationList)
   590  	if err != nil {
   591  		return MSP{}, err
   592  	}
   593  
   594  	// OU IDENTIFIERS
   595  	ouIdentifiers, err := parseOUIdentifiers(fabricMSPConfig.OrganizationalUnitIdentifiers)
   596  	if err != nil {
   597  		return MSP{}, fmt.Errorf("parsing ou identifiers: %v", err)
   598  	}
   599  
   600  	// TLS ROOT CERTS
   601  	tlsRootCerts, err := parseCertificateListFromBytes(fabricMSPConfig.TlsRootCerts)
   602  	if err != nil {
   603  		return MSP{}, fmt.Errorf("parsing tls root certs: %v", err)
   604  	}
   605  
   606  	// TLS INTERMEDIATE CERTS
   607  	tlsIntermediateCerts, err := parseCertificateListFromBytes(fabricMSPConfig.TlsIntermediateCerts)
   608  	if err != nil {
   609  		return MSP{}, fmt.Errorf("parsing tls intermediate certs: %v", err)
   610  	}
   611  
   612  	// NODE OUS
   613  	nodeOUs := membership.NodeOUs{}
   614  	if fabricMSPConfig.FabricNodeOus != nil {
   615  		clientOUIdentifierCert, err := parseCertificateFromBytes(fabricMSPConfig.FabricNodeOus.ClientOuIdentifier.Certificate)
   616  		if err != nil {
   617  			return MSP{}, fmt.Errorf("parsing client ou identifier cert: %v", err)
   618  		}
   619  
   620  		peerOUIdentifierCert, err := parseCertificateFromBytes(fabricMSPConfig.FabricNodeOus.PeerOuIdentifier.Certificate)
   621  		if err != nil {
   622  			return MSP{}, fmt.Errorf("parsing peer ou identifier cert: %v", err)
   623  		}
   624  
   625  		adminOUIdentifierCert, err := parseCertificateFromBytes(fabricMSPConfig.FabricNodeOus.AdminOuIdentifier.Certificate)
   626  		if err != nil {
   627  			return MSP{}, fmt.Errorf("parsing admin ou identifier cert: %v", err)
   628  		}
   629  
   630  		ordererOUIdentifierCert, err := parseCertificateFromBytes(fabricMSPConfig.FabricNodeOus.OrdererOuIdentifier.Certificate)
   631  		if err != nil {
   632  			return MSP{}, fmt.Errorf("parsing orderer ou identifier cert: %v", err)
   633  		}
   634  
   635  		nodeOUs = membership.NodeOUs{
   636  			Enable: fabricMSPConfig.FabricNodeOus.Enable,
   637  			ClientOUIdentifier: membership.OUIdentifier{
   638  				Certificate:                  clientOUIdentifierCert,
   639  				OrganizationalUnitIdentifier: fabricMSPConfig.FabricNodeOus.ClientOuIdentifier.OrganizationalUnitIdentifier,
   640  			},
   641  			PeerOUIdentifier: membership.OUIdentifier{
   642  				Certificate:                  peerOUIdentifierCert,
   643  				OrganizationalUnitIdentifier: fabricMSPConfig.FabricNodeOus.PeerOuIdentifier.OrganizationalUnitIdentifier,
   644  			},
   645  			AdminOUIdentifier: membership.OUIdentifier{
   646  				Certificate:                  adminOUIdentifierCert,
   647  				OrganizationalUnitIdentifier: fabricMSPConfig.FabricNodeOus.AdminOuIdentifier.OrganizationalUnitIdentifier,
   648  			},
   649  			OrdererOUIdentifier: membership.OUIdentifier{
   650  				Certificate:                  ordererOUIdentifierCert,
   651  				OrganizationalUnitIdentifier: fabricMSPConfig.FabricNodeOus.OrdererOuIdentifier.OrganizationalUnitIdentifier,
   652  			},
   653  		}
   654  	}
   655  
   656  	return MSP{
   657  		Name:                          fabricMSPConfig.Name,
   658  		RootCerts:                     rootCerts,
   659  		IntermediateCerts:             intermediateCerts,
   660  		Admins:                        adminCerts,
   661  		RevocationList:                revocationList,
   662  		OrganizationalUnitIdentifiers: ouIdentifiers,
   663  		CryptoConfig: membership.CryptoConfig{
   664  			SignatureHashFamily:            fabricMSPConfig.CryptoConfig.SignatureHashFamily,
   665  			IdentityIdentifierHashFunction: fabricMSPConfig.CryptoConfig.IdentityIdentifierHashFunction,
   666  		},
   667  		TLSRootCerts:         tlsRootCerts,
   668  		TLSIntermediateCerts: tlsIntermediateCerts,
   669  		NodeOUs:              nodeOUs,
   670  	}, nil
   671  }
   672  
   673  func parseCertificateListFromBytes(certs [][]byte) ([]*x509.Certificate, error) {
   674  	certificateList := []*x509.Certificate{}
   675  
   676  	for _, cert := range certs {
   677  		certificate, err := parseCertificateFromBytes(cert)
   678  		if err != nil {
   679  			return certificateList, err
   680  		}
   681  
   682  		certificateList = append(certificateList, certificate)
   683  	}
   684  
   685  	return certificateList, nil
   686  }
   687  
   688  func parseCertificateFromBytes(cert []byte) (*x509.Certificate, error) {
   689  	pemBlock, _ := pem.Decode(cert)
   690  	if pemBlock == nil {
   691  		return &x509.Certificate{}, fmt.Errorf("no PEM data found in cert[% x]", cert)
   692  	}
   693  
   694  	certificate, err := x509.ParseCertificate(pemBlock.Bytes)
   695  	if err != nil {
   696  		return &x509.Certificate{}, err
   697  	}
   698  
   699  	return certificate, nil
   700  }
   701  
   702  func parseCRL(crls [][]byte) ([]*pkix.CertificateList, error) {
   703  	certificateLists := []*pkix.CertificateList{}
   704  
   705  	for _, crl := range crls {
   706  		pemBlock, _ := pem.Decode(crl)
   707  		if pemBlock == nil {
   708  			return certificateLists, fmt.Errorf("no PEM data found in CRL[% x]", crl)
   709  		}
   710  
   711  		certificateList, err := x509.ParseCRL(pemBlock.Bytes)
   712  		if err != nil {
   713  			return certificateLists, fmt.Errorf("parsing crl: %v", err)
   714  		}
   715  
   716  		certificateLists = append(certificateLists, certificateList)
   717  	}
   718  
   719  	return certificateLists, nil
   720  }
   721  
   722  func parsePrivateKeyFromBytes(priv []byte) (crypto.PrivateKey, error) {
   723  	if len(priv) == 0 {
   724  		return nil, nil
   725  	}
   726  
   727  	pemBlock, _ := pem.Decode(priv)
   728  	if pemBlock == nil {
   729  		return nil, fmt.Errorf("no PEM data found in private key[% x]", priv)
   730  	}
   731  
   732  	privateKey, err := x509.ParsePKCS8PrivateKey(pemBlock.Bytes)
   733  	if err != nil {
   734  		return nil, fmt.Errorf("failed parsing PKCS#8 private key: %v", err)
   735  	}
   736  
   737  	return privateKey, nil
   738  }
   739  
   740  func parseOUIdentifiers(identifiers []*mb.FabricOUIdentifier) ([]membership.OUIdentifier, error) {
   741  	fabricIdentifiers := []membership.OUIdentifier{}
   742  
   743  	for _, identifier := range identifiers {
   744  		cert, err := parseCertificateFromBytes(identifier.Certificate)
   745  		if err != nil {
   746  			return fabricIdentifiers, err
   747  		}
   748  
   749  		fabricOUIdentifier := membership.OUIdentifier{
   750  			Certificate:                  cert,
   751  			OrganizationalUnitIdentifier: identifier.OrganizationalUnitIdentifier,
   752  		}
   753  
   754  		fabricIdentifiers = append(fabricIdentifiers, fabricOUIdentifier)
   755  	}
   756  
   757  	return fabricIdentifiers, nil
   758  }
   759  
   760  // toProto converts an MSP configuration to an mb.FabricMSPConfig proto.
   761  // It pem encodes x509 certificates and ECDSA private keys to byte slices.
   762  func (m *MSP) toProto() (*mb.FabricMSPConfig, error) {
   763  	revocationList, err := buildPemEncodedRevocationList(m.RevocationList)
   764  	if err != nil {
   765  		return nil, fmt.Errorf("building pem encoded revocation list: %v", err)
   766  	}
   767  
   768  	ouIdentifiers := buildOUIdentifiers(m.OrganizationalUnitIdentifiers)
   769  
   770  	var fabricNodeOUs *mb.FabricNodeOUs
   771  	if m.NodeOUs != (membership.NodeOUs{}) {
   772  		fabricNodeOUs = &mb.FabricNodeOUs{
   773  			Enable: m.NodeOUs.Enable,
   774  			ClientOuIdentifier: &mb.FabricOUIdentifier{
   775  				Certificate:                  pemEncodeX509Certificate(m.NodeOUs.ClientOUIdentifier.Certificate),
   776  				OrganizationalUnitIdentifier: m.NodeOUs.ClientOUIdentifier.OrganizationalUnitIdentifier,
   777  			},
   778  			PeerOuIdentifier: &mb.FabricOUIdentifier{
   779  				Certificate:                  pemEncodeX509Certificate(m.NodeOUs.PeerOUIdentifier.Certificate),
   780  				OrganizationalUnitIdentifier: m.NodeOUs.PeerOUIdentifier.OrganizationalUnitIdentifier,
   781  			},
   782  			AdminOuIdentifier: &mb.FabricOUIdentifier{
   783  				Certificate:                  pemEncodeX509Certificate(m.NodeOUs.AdminOUIdentifier.Certificate),
   784  				OrganizationalUnitIdentifier: m.NodeOUs.AdminOUIdentifier.OrganizationalUnitIdentifier,
   785  			},
   786  			OrdererOuIdentifier: &mb.FabricOUIdentifier{
   787  				Certificate:                  pemEncodeX509Certificate(m.NodeOUs.OrdererOUIdentifier.Certificate),
   788  				OrganizationalUnitIdentifier: m.NodeOUs.OrdererOUIdentifier.OrganizationalUnitIdentifier,
   789  			},
   790  		}
   791  	}
   792  	fmspConf := &mb.FabricMSPConfig{
   793  		Name:                          m.Name,
   794  		RootCerts:                     buildPemEncodedCertListFromX509(m.RootCerts),
   795  		IntermediateCerts:             buildPemEncodedCertListFromX509(m.IntermediateCerts),
   796  		Admins:                        buildPemEncodedCertListFromX509(m.Admins),
   797  		RevocationList:                revocationList,
   798  		OrganizationalUnitIdentifiers: ouIdentifiers,
   799  		CryptoConfig: &mb.FabricCryptoConfig{
   800  			SignatureHashFamily:            m.CryptoConfig.SignatureHashFamily,
   801  			IdentityIdentifierHashFunction: m.CryptoConfig.IdentityIdentifierHashFunction,
   802  		},
   803  		TlsRootCerts:         buildPemEncodedCertListFromX509(m.TLSRootCerts),
   804  		TlsIntermediateCerts: buildPemEncodedCertListFromX509(m.TLSIntermediateCerts),
   805  		FabricNodeOus:        fabricNodeOUs,
   806  	}
   807  	if algo.GetGMFlag() {
   808  		cryptoConfig := &mb.FabricCryptoConfig{
   809  			SignatureHashFamily:            bccsp.SM,
   810  			IdentityIdentifierHashFunction: bccsp.SM3,
   811  		}
   812  		fmspConf.CryptoConfig = cryptoConfig
   813  	}
   814  	return fmspConf, nil
   815  }
   816  
   817  func buildOUIdentifiers(identifiers []membership.OUIdentifier) []*mb.FabricOUIdentifier {
   818  	fabricIdentifiers := []*mb.FabricOUIdentifier{}
   819  
   820  	for _, identifier := range identifiers {
   821  		fabricOUIdentifier := &mb.FabricOUIdentifier{
   822  			Certificate:                  pemEncodeX509Certificate(identifier.Certificate),
   823  			OrganizationalUnitIdentifier: identifier.OrganizationalUnitIdentifier,
   824  		}
   825  
   826  		fabricIdentifiers = append(fabricIdentifiers, fabricOUIdentifier)
   827  	}
   828  
   829  	return fabricIdentifiers
   830  }
   831  
   832  // buildPemEncodedRevocationList returns a byte slice of the pem-encoded
   833  // CRLs for a revocation list.
   834  func buildPemEncodedRevocationList(crls []*pkix.CertificateList) ([][]byte, error) {
   835  	pemEncodedRevocationList := [][]byte{}
   836  
   837  	for _, crl := range crls {
   838  		// asn1MarshalledBytes, err := asn1.Marshal(*crl)
   839  		pemCRL, err := pemEncodeCRL(crl)
   840  		if err != nil {
   841  			return nil, err
   842  		}
   843  
   844  		pemEncodedRevocationList = append(pemEncodedRevocationList, pemCRL)
   845  	}
   846  
   847  	return pemEncodedRevocationList, nil
   848  }
   849  
   850  func pemEncodeCRL(crl *pkix.CertificateList) ([]byte, error) {
   851  	asn1MarshalledBytes, err := asn1.Marshal(*crl)
   852  	if err != nil {
   853  		return nil, err
   854  	}
   855  	return pem.EncodeToMemory(&pem.Block{Type: "X509 CRL", Bytes: asn1MarshalledBytes}), nil
   856  }
   857  
   858  func buildPemEncodedCertListFromX509(certList []*x509.Certificate) [][]byte {
   859  	certs := [][]byte{}
   860  	for _, cert := range certList {
   861  		certs = append(certs, pemEncodeX509Certificate(cert))
   862  	}
   863  
   864  	return certs
   865  }
   866  
   867  func pemEncodeX509Certificate(cert *x509.Certificate) []byte {
   868  	return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})
   869  }
   870  
   871  func pemEncodePKCS8PrivateKey(priv crypto.PrivateKey) ([]byte, error) {
   872  	privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
   873  	if err != nil {
   874  		return nil, fmt.Errorf("marshaling PKCS#8 private key: %v", err)
   875  	}
   876  
   877  	return pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}), nil
   878  }
   879  
   880  // newMSPConfig returns an config for a msp.
   881  func newMSPConfig(updatedMSP MSP) (*mb.MSPConfig, error) {
   882  	fabricMSPConfig, err := updatedMSP.toProto()
   883  	if err != nil {
   884  		return nil, err
   885  	}
   886  
   887  	conf, err := proto.Marshal(fabricMSPConfig)
   888  	if err != nil {
   889  		return nil, fmt.Errorf("marshaling msp config: %v", err)
   890  	}
   891  
   892  	mspConfig := &mb.MSPConfig{
   893  		Config: conf,
   894  	}
   895  
   896  	return mspConfig, nil
   897  }
   898  
   899  func (m *MSP) validateCACerts() error {
   900  	err := validateCACerts(m.RootCerts)
   901  	if err != nil {
   902  		return fmt.Errorf("invalid root cert: %v", err)
   903  	}
   904  
   905  	err = validateCACerts(m.IntermediateCerts)
   906  	if err != nil {
   907  		return fmt.Errorf("invalid intermediate cert: %v", err)
   908  	}
   909  
   910  	// TODO: follow the workaround that msp code use to incorporate cert.Verify()
   911  	for _, ic := range m.IntermediateCerts {
   912  		validIntermediateCert := false
   913  		for _, rc := range m.RootCerts {
   914  			err := ic.CheckSignatureFrom(rc)
   915  			if err == nil {
   916  				validIntermediateCert = true
   917  				break
   918  			}
   919  		}
   920  		if !validIntermediateCert {
   921  			return fmt.Errorf("intermediate cert not signed by any root certs of this MSP. serial number: %d", ic.SerialNumber)
   922  		}
   923  	}
   924  
   925  	err = validateCACerts(m.TLSRootCerts)
   926  	if err != nil {
   927  		return fmt.Errorf("invalid tls root cert: %v", err)
   928  	}
   929  
   930  	err = validateCACerts(m.TLSIntermediateCerts)
   931  	if err != nil {
   932  		return fmt.Errorf("invalid tls intermediate cert: %v", err)
   933  	}
   934  
   935  	tlsRootPool := x509.NewCertPool()
   936  	for _, rootCert := range m.TLSRootCerts {
   937  		tlsRootPool.AddCert(rootCert)
   938  	}
   939  
   940  	for _, ic := range m.TLSIntermediateCerts {
   941  		_, err := ic.Verify(x509.VerifyOptions{
   942  			Roots: tlsRootPool,
   943  		})
   944  		if err != nil {
   945  			return err
   946  		}
   947  	}
   948  
   949  	return nil
   950  }
   951  
   952  func validateCACerts(caCerts []*x509.Certificate) error {
   953  	for _, caCert := range caCerts {
   954  		if (caCert.KeyUsage & x509.KeyUsageCertSign) == 0 {
   955  			return fmt.Errorf("KeyUsage must be x509.KeyUsageCertSign. serial number: %d", caCert.SerialNumber)
   956  		}
   957  
   958  		if !caCert.IsCA {
   959  			return fmt.Errorf("must be a CA certificate. serial number: %d", caCert.SerialNumber)
   960  		}
   961  	}
   962  
   963  	return nil
   964  }