Skip to content

Commit a19279e

Browse files
committed
[FAB-3351] MSP OUIdentifiers config
This change-sets allows an MSP to be configured with a set of OrganizationUnitIdentifiers against which each identiy will be validated. Change-Id: Ie8410c24ab7d579b69e270f18d955d9e66fa7cb9 Signed-off-by: Angelo De Caro <[email protected]>
1 parent c5c4c51 commit a19279e

File tree

23 files changed

+444
-109
lines changed

23 files changed

+444
-109
lines changed

common/cauthdsl/cauthdsl_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func (id *mockIdentity) Validate() error {
5454
return nil
5555
}
5656

57-
func (id *mockIdentity) GetOrganizationalUnits() []mb.FabricOUIdentifier {
57+
func (id *mockIdentity) GetOrganizationalUnits() []*msp.OUIdentifier {
5858
return nil
5959
}
6060

common/mocks/msp/noopmsp.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func (id *noopidentity) Validate() error {
9797
return nil
9898
}
9999

100-
func (id *noopidentity) GetOrganizationalUnits() []msp.FabricOUIdentifier {
100+
func (id *noopidentity) GetOrganizationalUnits() []*m.OUIdentifier {
101101
return nil
102102
}
103103

core/policy/mocks.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ func (id *MockIdentity) Validate() error {
112112
return nil
113113
}
114114

115-
func (id *MockIdentity) GetOrganizationalUnits() []mspproto.FabricOUIdentifier {
115+
func (id *MockIdentity) GetOrganizationalUnits() []*msp.OUIdentifier {
116116
return nil
117117
}
118118

msp/configbuilder.go

+54-3
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,18 @@ import (
3030
"github.com/hyperledger/fabric/bccsp"
3131
"github.com/hyperledger/fabric/bccsp/factory"
3232
"github.com/hyperledger/fabric/protos/msp"
33+
"gopkg.in/yaml.v2"
3334
)
3435

36+
type OrganizationalUnitIdentifiersConfiguration struct {
37+
Certificate string `yaml:"Certificate,omitempty"`
38+
OrganizationalUnitIdentifier string `yaml:"OrganizationalUnitIdentifier,omitempty"`
39+
}
40+
41+
type Configuration struct {
42+
OrganizationalUnitIdentifiers []*OrganizationalUnitIdentifiersConfiguration `yaml:"OrganizationalUnitIdentifiers,omitempty"`
43+
}
44+
3545
func readFile(file string) ([]byte, error) {
3646
fileCont, err := ioutil.ReadFile(file)
3747
if err != nil {
@@ -96,6 +106,7 @@ const (
96106
keystore = "keystore"
97107
intermediatecerts = "intermediatecerts"
98108
crlsfolder = "crls"
109+
configfilename = "config.yaml"
99110
)
100111

101112
func SetupBCCSPKeystoreConfig(bccspConfig *factory.FactoryOpts, keystoreDir string) {
@@ -153,6 +164,7 @@ func getMspConfig(dir string, bccspConfig *factory.FactoryOpts, ID string, sigid
153164
admincertDir := filepath.Join(dir, admincerts)
154165
intermediatecertsDir := filepath.Join(dir, intermediatecerts)
155166
crlsDir := filepath.Join(dir, crlsfolder)
167+
configFile := filepath.Join(dir, configfilename)
156168

157169
cacerts, err := getPemMaterialFromDir(cacertDir)
158170
if err != nil || len(cacerts) == 0 {
@@ -183,7 +195,45 @@ func getMspConfig(dir string, bccspConfig *factory.FactoryOpts, ID string, sigid
183195
return nil, fmt.Errorf("Failed loading crls ca certs at [%s]: [%s]", intermediatecertsDir, err)
184196
}
185197

186-
// Load FabricCryptoConfig
198+
// Load configuration file
199+
// if the configuration file is there then load it
200+
// otherwise skip it
201+
var ouis []*msp.FabricOUIdentifier
202+
_, err = os.Stat(configFile)
203+
if err == nil {
204+
// load the file, if there is a failure in loading it then
205+
// return an error
206+
raw, err := ioutil.ReadFile(configFile)
207+
if err != nil {
208+
return nil, fmt.Errorf("Failed loading configuration file at [%s]: [%s]", configFile, err)
209+
}
210+
211+
configuration := Configuration{}
212+
err = yaml.Unmarshal(raw, &configuration)
213+
if err != nil {
214+
return nil, fmt.Errorf("Failed unmarshalling configuration file at [%s]: [%s]", configFile, err)
215+
}
216+
217+
// Prepare OrganizationalUnitIdentifiers
218+
if len(configuration.OrganizationalUnitIdentifiers) > 0 {
219+
for _, ouID := range configuration.OrganizationalUnitIdentifiers {
220+
f := filepath.Join(dir, ouID.Certificate)
221+
raw, err = ioutil.ReadFile(f)
222+
if err != nil {
223+
return nil, fmt.Errorf("Failed loading OrganizationalUnit certificate at [%s]: [%s]", f, err)
224+
}
225+
oui := &msp.FabricOUIdentifier{
226+
Certificate: raw,
227+
OrganizationalUnitIdentifier: ouID.OrganizationalUnitIdentifier,
228+
}
229+
ouis = append(ouis, oui)
230+
}
231+
}
232+
} else {
233+
mspLogger.Infof("MSP configuration file not found at [%s]: [%s]", configFile, err)
234+
}
235+
236+
// Set FabricCryptoConfig
187237
cryptoConfig := &msp.FabricCryptoConfig{
188238
SignatureHashFamily: bccsp.SHA2,
189239
IdentityIdentifierHashFunction: bccsp.SHA256,
@@ -196,8 +246,9 @@ func getMspConfig(dir string, bccspConfig *factory.FactoryOpts, ID string, sigid
196246
IntermediateCerts: intermediatecert,
197247
SigningIdentity: sigid,
198248
Name: ID,
199-
RevocationList: crls,
200-
CryptoConfig: cryptoConfig}
249+
OrganizationalUnitIdentifiers: ouis,
250+
RevocationList: crls,
251+
CryptoConfig: cryptoConfig}
201252

202253
fmpsjs, _ := proto.Marshal(fmspconf)
203254

msp/identities.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (id *identity) Validate() error {
7171
}
7272

7373
// GetOrganizationalUnits returns the OU for this instance
74-
func (id *identity) GetOrganizationalUnits() []msp.FabricOUIdentifier {
74+
func (id *identity) GetOrganizationalUnits() []*OUIdentifier {
7575
if id.cert == nil {
7676
return nil
7777
}
@@ -83,9 +83,9 @@ func (id *identity) GetOrganizationalUnits() []msp.FabricOUIdentifier {
8383
return nil
8484
}
8585

86-
res := []msp.FabricOUIdentifier{}
86+
res := []*OUIdentifier{}
8787
for _, unit := range id.cert.Subject.OrganizationalUnit {
88-
res = append(res, msp.FabricOUIdentifier{
88+
res = append(res, &OUIdentifier{
8989
OrganizationalUnitIdentifier: unit,
9090
CertifiersIdentifier: cid,
9191
})

msp/msp.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,17 @@ type MSP interface {
102102
SatisfiesPrincipal(id Identity, principal *msp.MSPPrincipal) error
103103
}
104104

105+
// OUIdentifier represents an organizational unit and
106+
// its related chain of trust identifier.
107+
type OUIdentifier struct {
108+
// CertifiersIdentifier is the hash of certificates chain of trust
109+
// related to this organizational unit
110+
CertifiersIdentifier []byte
111+
// OrganizationUnitIdentifier defines the organizational unit under the
112+
// MSP identified with MSPIdentifier
113+
OrganizationalUnitIdentifier string
114+
}
115+
105116
// From this point on, there are interfaces that are shared within the peer and client API
106117
// of the membership service provider.
107118

@@ -137,7 +148,7 @@ type Identity interface {
137148
// TODO: For X.509 based identities, check if we need a dedicated type
138149
// for OU where the Certificate OU is properly namespaced by the
139150
// signer's identity
140-
GetOrganizationalUnits() []msp.FabricOUIdentifier
151+
GetOrganizationalUnits() []*OUIdentifier
141152

142153
// Verify a signature over some message using this identity as reference
143154
Verify(msg []byte, sig []byte) error

msp/msp_test.go

+21-17
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ func TestGetIdentities(t *testing.T) {
4848
}
4949
}
5050

51+
func TestValidateDefaultSigningIdentity(t *testing.T) {
52+
id, err := localMsp.GetDefaultSigningIdentity()
53+
assert.NoError(t, err)
54+
55+
err = localMsp.Validate(id.GetPublicVersion())
56+
assert.NoError(t, err)
57+
}
58+
5159
func TestSerializeIdentities(t *testing.T) {
5260
id, err := localMsp.GetDefaultSigningIdentity()
5361
if err != nil {
@@ -244,9 +252,14 @@ func TestCertificationIdentifierComputation(t *testing.T) {
244252
assert.NoError(t, err)
245253

246254
// Hash the chain
247-
hf, err := localMsp.(*bccspmsp).bccsp.GetHash(&bccsp.SHA256Opts{})
255+
// Use the hash of the identity's certificate as id in the IdentityIdentifier
256+
hashOpt, err := bccsp.GetHashOpt(localMsp.(*bccspmsp).cryptoConfig.IdentityIdentifierHashFunction)
257+
assert.NoError(t, err)
258+
259+
hf, err := localMsp.(*bccspmsp).bccsp.GetHash(hashOpt)
248260
assert.NoError(t, err)
249-
for i := 0; i < len(chain); i++ {
261+
// Skipping first cert because it belongs to the identity
262+
for i := 1; i < len(chain); i++ {
250263
hf.Write(chain[i].Raw)
251264
}
252265
sum := hf.Sum(nil)
@@ -371,27 +384,18 @@ func TestMSPOus(t *testing.T) {
371384
id, err := localMsp.GetDefaultSigningIdentity()
372385
assert.NoError(t, err)
373386

374-
localMsp.(*bccspmsp).ouIdentifiers = []*msp.FabricOUIdentifier{
375-
&msp.FabricOUIdentifier{
376-
OrganizationalUnitIdentifier: "COP",
377-
CertifiersIdentifier: id.GetOrganizationalUnits()[0].CertifiersIdentifier,
378-
},
387+
localMsp.(*bccspmsp).ouIdentifiers = map[string][][]byte{
388+
"COP": {id.GetOrganizationalUnits()[0].CertifiersIdentifier},
379389
}
380390
assert.NoError(t, localMsp.Validate(id.GetPublicVersion()))
381391

382-
localMsp.(*bccspmsp).ouIdentifiers = []*msp.FabricOUIdentifier{
383-
&msp.FabricOUIdentifier{
384-
OrganizationalUnitIdentifier: "COP2",
385-
CertifiersIdentifier: id.GetOrganizationalUnits()[0].CertifiersIdentifier,
386-
},
392+
localMsp.(*bccspmsp).ouIdentifiers = map[string][][]byte{
393+
"COP2": {id.GetOrganizationalUnits()[0].CertifiersIdentifier},
387394
}
388395
assert.Error(t, localMsp.Validate(id.GetPublicVersion()))
389396

390-
localMsp.(*bccspmsp).ouIdentifiers = []*msp.FabricOUIdentifier{
391-
&msp.FabricOUIdentifier{
392-
OrganizationalUnitIdentifier: "COP",
393-
CertifiersIdentifier: []byte{0, 1, 2, 3, 4},
394-
},
397+
localMsp.(*bccspmsp).ouIdentifiers = map[string][][]byte{
398+
"COP": {{0, 1, 2, 3, 4}},
395399
}
396400
assert.Error(t, localMsp.Validate(id.GetPublicVersion()))
397401
}

0 commit comments

Comments
 (0)