func (msp *bccspmsp) getCertificationChain(id Identity) ([]*sm2.Certificate, error) {
	mspLogger.Debugf("MSP %s getting certification chain", msp.name)
	switch id := id.(type) {
	case *identity:
		return msp.getCertificationChainForBCCSPIdentity(id)
	default:
		return nil, errors.New("identity type not recognized")
	}
}
getCertificationChain returns the certification chain of the passed identity within this msp
package msp
import (
	"bytes"
	"crypto/x509/pkix"
	"encoding/hex"
	"encoding/pem"
	"fmt"
	"github.com/golang/protobuf/proto"
	"github.com/hyperledger/fabric-sdk-go/api/apicryptosuite"
	factory "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/sdkpatch/cryptosuitebridge"
	m "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/msp"
	"github.com/pkg/errors"
	"github.com/hyperledger/fabric-sdk-go/internal/github.com/tjfoc/gmsm/sm2"
)
type mspSetupFuncType func(config *m.FabricMSPConfig) error
type validateIdentityOUsFuncType func(id *identity) error
type bccspmsp struct {
	version MSPVersion
	internalSetupFunc mspSetupFuncType
	internalValidateIdentityOusFunc validateIdentityOUsFuncType
	rootCerts []Identity
	intermediateCerts []Identity
	tlsRootCerts [][]byte
	tlsIntermediateCerts [][]byte
	certificationTreeInternalNodesMap map[string]bool
	signer SigningIdentity
	admins []Identity
	bccsp apicryptosuite.CryptoSuite
	name string
	opts *sm2.VerifyOptions
	CRL []*pkix.CertificateList
	ouIdentifiers map[string][][]byte
	cryptoConfig *m.FabricCryptoConfig
	ouEnforcement bool
	clientOU, peerOU, ordererOU *OUIdentifier
}
func NewBccspMsp(version MSPVersion, cryptoSuite apicryptosuite.CryptoSuite) (MSP, error) {
	mspLogger.Debugf("Creating BCCSP-based MSP instance")
	theMsp := &bccspmsp{}
	theMsp.version = version
	theMsp.bccsp = cryptoSuite
	switch version {
	case MSPv1_0:
		theMsp.internalSetupFunc = theMsp.setupV1
		theMsp.internalValidateIdentityOusFunc = theMsp.validateIdentityOUsV1
	case MSPv1_1:
		theMsp.internalSetupFunc = theMsp.setupV11
		theMsp.internalValidateIdentityOusFunc = theMsp.validateIdentityOUsV11
	default:
		return nil, errors.Errorf("Invalid MSP version [%v]", version)
	}
	return theMsp, nil
}
func (msp *bccspmsp) getCertFromPem(idBytes []byte) (*sm2.Certificate, error) {
	if idBytes == nil {
		return nil, errors.New("getCertFromPem error: nil idBytes")
	}
	pemCert, _ := pem.Decode(idBytes)
	if pemCert == nil {
		return nil, errors.Errorf("getCertFromPem error: could not decode pem bytes [%v]", idBytes)
	}
	var cert *sm2.Certificate
	cert, err := sm2.ParseCertificate(pemCert.Bytes)
	if err != nil {
		return nil, errors.Wrap(err, "getCertFromPem error: failed to parse sm2 cert")
	}
	return cert, nil
}
func (msp *bccspmsp) getIdentityFromConf(idBytes []byte) (Identity, apicryptosuite.Key, error) {
	cert, err := msp.getCertFromPem(idBytes)
	if err != nil {
		return nil, nil, err
	}
	certPubK, err := msp.bccsp.KeyImport(cert, factory.GetX509PublicKeyImportOpts(true))
	mspId, err := newIdentity(cert, certPubK, msp)
	if err != nil {
		return nil, nil, err
	}
	return mspId, certPubK, nil
}
func (msp *bccspmsp) getSigningIdentityFromConf(sidInfo *m.SigningIdentityInfo) (SigningIdentity, error) {
	if sidInfo == nil {
		return nil, errors.New("getIdentityFromBytes error: nil sidInfo")
	}
	idPub, pubKey, err := msp.getIdentityFromConf(sidInfo.PublicSigner)
	if err != nil {
		return nil, err
	}
	privKey, err := msp.bccsp.GetKey(pubKey.SKI())
	if err != nil {
		mspLogger.Debugf("Could not find SKI [%s], trying KeyMaterial field: %+v\n", hex.EncodeToString(pubKey.SKI()), err)
		if sidInfo.PrivateSigner == nil || sidInfo.PrivateSigner.KeyMaterial == nil {
			return nil, errors.New("KeyMaterial not found in SigningIdentityInfo")
		}
		pemKey, _ := pem.Decode(sidInfo.PrivateSigner.KeyMaterial)
		privKey, err = msp.bccsp.KeyImport(pemKey.Bytes, factory.GetECDSAPrivateKeyImportOpts(true))
		if err != nil {
			return nil, errors.WithMessage(err, "getIdentityFromBytes error: Failed to import EC private key")
		}
	}
	peerSigner, err := factory.NewCspSigner(msp.bccsp, privKey)
	if err != nil {
		return nil, errors.WithMessage(err, "getIdentityFromBytes error: Failed initializing bccspCryptoSigner")
	}
	return newSigningIdentity(idPub.(*identity).cert, idPub.(*identity).pk, peerSigner, msp)
}
func (msp *bccspmsp) Setup(conf1 *m.MSPConfig) error {
	if conf1 == nil {
		return errors.New("Setup error: nil conf reference")
	}
	conf := &m.FabricMSPConfig{}
	err := proto.Unmarshal(conf1.Config, conf)
	if err != nil {
		return errors.Wrap(err, "failed unmarshalling fabric msp config")
	}
	msp.name = conf.Name
	mspLogger.Debugf("Setting up MSP instance %s", msp.name)
	return msp.internalSetupFunc(conf)
}
func (msp *bccspmsp) GetVersion() MSPVersion {
	return msp.version
}
func (msp *bccspmsp) GetType() ProviderType {
	return FABRIC
}
func (msp *bccspmsp) GetIdentifier() (string, error) {
	return msp.name, nil
}
func (msp *bccspmsp) GetTLSRootCerts() [][]byte {
	return msp.tlsRootCerts
}
func (msp *bccspmsp) GetTLSIntermediateCerts() [][]byte {
	return msp.tlsIntermediateCerts
}
func (msp *bccspmsp) GetDefaultSigningIdentity() (SigningIdentity, error) {
	mspLogger.Debugf("Obtaining default signing identity")
	if msp.signer == nil {
		return nil, errors.New("this MSP does not possess a valid default signing identity")
	}
	return msp.signer, nil
}
func (msp *bccspmsp) GetSigningIdentity(identifier *IdentityIdentifier) (SigningIdentity, error) {
	return nil, errors.Errorf("no signing identity for %#v", identifier)
}
func (msp *bccspmsp) Validate(id Identity) error {
	mspLogger.Debugf("MSP %s validating identity", msp.name)
	switch id := id.(type) {
	case *identity:
		return msp.validateIdentity(id)
	default:
		return errors.New("identity type not recognized")
	}
}
func (msp *bccspmsp) hasOURole(id Identity, mspRole m.MSPRole_MSPRoleType) error {
	if !msp.ouEnforcement {
		return errors.New("NodeOUs not activated. Cannot tell apart identities.")
	}
	mspLogger.Debugf("MSP %s checking if the identity is a client", msp.name)
	switch id := id.(type) {
	case *identity:
		return msp.hasOURoleInternal(id, mspRole)
	default:
		return errors.New("Identity type not recognized")
	}
}
func (msp *bccspmsp) hasOURoleInternal(id *identity, mspRole m.MSPRole_MSPRoleType) error {
	var nodeOUValue string
	switch mspRole {
	case m.MSPRole_CLIENT:
		nodeOUValue = msp.clientOU.OrganizationalUnitIdentifier
	case m.MSPRole_PEER:
		nodeOUValue = msp.peerOU.OrganizationalUnitIdentifier
	case m.MSPRole_ORDERER:
		nodeOUValue = msp.ordererOU.OrganizationalUnitIdentifier
	default:
		return fmt.Errorf("Invalid MSPRoleType. It must be CLIENT, PEER or ORDERER")
	}
	for _, OU := range id.GetOrganizationalUnits() {
		if OU.OrganizationalUnitIdentifier == nodeOUValue {
			return nil
		}
	}
	return fmt.Errorf("The identity does not contain OU [%s], MSP: [%s]", mspRole, msp.name)
}
func (msp *bccspmsp) DeserializeIdentity(serializedID []byte) (Identity, error) {
	mspLogger.Infof("Obtaining identity")
	sId := &m.SerializedIdentity{}
	err := proto.Unmarshal(serializedID, sId)
	if err != nil {
		return nil, errors.Wrap(err, "could not deserialize a SerializedIdentity")
	}
	if sId.Mspid != msp.name {
		return nil, errors.Errorf("expected MSP ID %s, received %s", msp.name, sId.Mspid)
	}
	return msp.deserializeIdentityInternal(sId.IdBytes)
}
func (msp *bccspmsp) deserializeIdentityInternal(serializedIdentity []byte) (Identity, error) {
	bl, _ := pem.Decode(serializedIdentity)
	if bl == nil {
		return nil, errors.New("could not decode the PEM structure")
	}
	cert, err := sm2.ParseCertificate(bl.Bytes)
	if err != nil {
		return nil, errors.Wrap(err, "parseCertificate failed")
	}
	pub, err := msp.bccsp.KeyImport(cert, factory.GetX509PublicKeyImportOpts(true))
	if err != nil {
		return nil, errors.WithMessage(err, "failed to import certificate's public key")
	}
	return newIdentity(cert, pub, msp)
}
func (msp *bccspmsp) SatisfiesPrincipal(id Identity, principal *m.MSPPrincipal) error {
	switch principal.PrincipalClassification {
	case m.MSPPrincipal_ROLE:
		mspRole := &m.MSPRole{}
		err := proto.Unmarshal(principal.Principal, mspRole)
		if err != nil {
			return errors.Wrap(err, "could not unmarshal MSPRole from principal")
		}
		if mspRole.MspIdentifier != msp.name {
			return errors.Errorf("the identity is a member of a different MSP (expected %s, got %s)", mspRole.MspIdentifier, id.GetMSPIdentifier())
		}
		switch mspRole.Role {
		case m.MSPRole_MEMBER:
			mspLogger.Debugf("Checking if identity satisfies MEMBER role for %s", msp.name)
			return msp.Validate(id)
		case m.MSPRole_ADMIN:
			mspLogger.Debugf("Checking if identity satisfies ADMIN role for %s", msp.name)
			for _, admincert := range msp.admins {
				if bytes.Equal(id.(*identity).cert.Raw, admincert.(*identity).cert.Raw) {
					return nil
				}
			}
			return errors.New("This identity is not an admin")
		case m.MSPRole_CLIENT:
			fallthrough
		case m.MSPRole_PEER:
			fallthrough
		case m.MSPRole_ORDERER:
			mspLogger.Debugf("Checking if identity satisfies role [%s] for %s", m.MSPRole_MSPRoleType_name[int32(mspRole.Role)], msp.name)
			if err := msp.Validate(id); err != nil {
				return errors.Wrapf(err, "The identity is not valid under this MSP [%s]", msp.name)
			}
			if err := msp.hasOURole(id, mspRole.Role); err != nil {
				return errors.Wrapf(err, "The identity is not a [%s] under this MSP [%s]", m.MSPRole_MSPRoleType_name[int32(mspRole.Role)], msp.name)
			}
			return nil
		default:
			return errors.Errorf("invalid MSP role type %d", int32(mspRole.Role))
		}
	case m.MSPPrincipal_IDENTITY:
		principalId, err := msp.DeserializeIdentity(principal.Principal)
		if err != nil {
			return errors.WithMessage(err, "invalid identity principal, not a certificate")
		}
		if bytes.Equal(id.(*identity).cert.Raw, principalId.(*identity).cert.Raw) {
			return principalId.Validate()
		}
		return errors.New("The identities do not match")
	case m.MSPPrincipal_ORGANIZATION_UNIT:
		OU := &m.OrganizationUnit{}
		err := proto.Unmarshal(principal.Principal, OU)
		if err != nil {
			return errors.Wrap(err, "could not unmarshal OrganizationUnit from principal")
		}
		if OU.MspIdentifier != msp.name {
			return errors.Errorf("the identity is a member of a different MSP (expected %s, got %s)", OU.MspIdentifier, id.GetMSPIdentifier())
		}
		err = msp.Validate(id)
		if err != nil {
			return err
		}
		for _, ou := range id.GetOrganizationalUnits() {
			if ou.OrganizationalUnitIdentifier == OU.OrganizationalUnitIdentifier &&
				bytes.Equal(ou.CertifiersIdentifier, OU.CertifiersIdentifier) {
				return nil
			}
		}
		return errors.New("The identities do not match")
	default:
		return errors.Errorf("invalid principal type %d", int32(principal.PrincipalClassification))
	}
}