diff --git a/msp/msp_test.go b/msp/msp_test.go index 77a5ad12b24..3a7bc3d0a98 100644 --- a/msp/msp_test.go +++ b/msp/msp_test.go @@ -24,6 +24,7 @@ import ( "fmt" "github.com/golang/protobuf/proto" + "github.com/hyperledger/fabric/bccsp" "github.com/hyperledger/fabric/protos/msp" "github.com/stretchr/testify/assert" ) @@ -259,6 +260,24 @@ func TestGetOU(t *testing.T) { assert.Equal(t, "COP", id.GetOrganizationalUnits()[0].OrganizationalUnitIdentifier) } +func TestCertificationIdentifierComputation(t *testing.T) { + id, err := localMsp.GetDefaultSigningIdentity() + assert.NoError(t, err) + + chain, err := localMsp.(*bccspmsp).getCertificationChain(id.GetPublicVersion()) + assert.NoError(t, err) + + // Hash the chain + hf, err := localMsp.(*bccspmsp).bccsp.GetHash(&bccsp.SHA256Opts{}) + assert.NoError(t, err) + for i := 0; i < len(chain); i++ { + hf.Write(chain[i].Raw) + } + sum := hf.Sum(nil) + + assert.Equal(t, sum, id.GetOrganizationalUnits()[0].CertifiersIdentifier) +} + func TestOUPolicyPrincipal(t *testing.T) { id, err := localMsp.GetDefaultSigningIdentity() assert.NoError(t, err) @@ -368,6 +387,39 @@ func TestIdentityPolicyPrincipal(t *testing.T) { assert.NoError(t, err) } +func TestMSPOus(t *testing.T) { + // Set the OUIdentifiers + backup := localMsp.(*bccspmsp).ouIdentifiers + defer func() { localMsp.(*bccspmsp).ouIdentifiers = backup }() + + id, err := localMsp.GetDefaultSigningIdentity() + assert.NoError(t, err) + + localMsp.(*bccspmsp).ouIdentifiers = []*msp.FabricOUIdentifier{ + &msp.FabricOUIdentifier{ + OrganizationalUnitIdentifier: "COP", + CertifiersIdentifier: id.GetOrganizationalUnits()[0].CertifiersIdentifier, + }, + } + assert.NoError(t, localMsp.Validate(id.GetPublicVersion())) + + localMsp.(*bccspmsp).ouIdentifiers = []*msp.FabricOUIdentifier{ + &msp.FabricOUIdentifier{ + OrganizationalUnitIdentifier: "COP2", + CertifiersIdentifier: id.GetOrganizationalUnits()[0].CertifiersIdentifier, + }, + } + assert.Error(t, localMsp.Validate(id.GetPublicVersion())) + + localMsp.(*bccspmsp).ouIdentifiers = []*msp.FabricOUIdentifier{ + &msp.FabricOUIdentifier{ + OrganizationalUnitIdentifier: "COP", + CertifiersIdentifier: []byte{0, 1, 2, 3, 4}, + }, + } + assert.Error(t, localMsp.Validate(id.GetPublicVersion())) +} + const othercert = `-----BEGIN CERTIFICATE----- MIIDAzCCAqigAwIBAgIBAjAKBggqhkjOPQQDAjBsMQswCQYDVQQGEwJHQjEQMA4G A1UECAwHRW5nbGFuZDEOMAwGA1UECgwFQmFyMTkxDjAMBgNVBAsMBUJhcjE5MQ4w diff --git a/msp/mspimpl.go b/msp/mspimpl.go index f1e078ee00b..276e044719f 100644 --- a/msp/mspimpl.go +++ b/msp/mspimpl.go @@ -61,6 +61,9 @@ type bccspmsp struct { // list of certificate revocation lists CRL []*pkix.CertificateList + + // list of OUs + ouIdentifiers []*m.FabricOUIdentifier } // NewBccspMsp returns an MSP instance backed up by a BCCSP @@ -341,6 +344,15 @@ func (msp *bccspmsp) Setup(conf1 *m.MSPConfig) error { msp.CRL[i] = crl } + // setup the OUs + msp.ouIdentifiers = make([]*m.FabricOUIdentifier, len(conf.OrganizationalUnitIdentifiers)) + for i, ou := range conf.OrganizationalUnitIdentifiers { + msp.ouIdentifiers[i] = &m.FabricOUIdentifier{ + CertifiersIdentifier: ou.CertifiersIdentifier, + OrganizationalUnitIdentifier: ou.OrganizationalUnitIdentifier, + } + } + return nil } @@ -448,6 +460,27 @@ func (msp *bccspmsp) Validate(id Identity) error { } } + // Check that the identity's OUs are compatible with those recognized by this MSP, + // meaning that the intersection is not empty. + if len(msp.ouIdentifiers) > 0 { + found := false + for _, ou := range msp.ouIdentifiers { + for _, OU := range id.GetOrganizationalUnits() { + if bytes.Equal(ou.CertifiersIdentifier, OU.CertifiersIdentifier) && + ou.OrganizationalUnitIdentifier == OU.OrganizationalUnitIdentifier { + found = true + break + } + } + if found { + break + } + } + if !found { + return fmt.Errorf("None of the identity's organizational units [%v] are in MSP %s", id.GetOrganizationalUnits(), msp.name) + } + } + return nil default: return fmt.Errorf("Identity type not recognized")