Skip to content

Commit 655190a

Browse files
committed
FAB-2062 - OU-based policy checks
This change set adds support for policy principals specified by the Organizational Unit specified in the Subject Distinguished Name. Change-Id: Ibb8ca6558666e010db92ad69ffb51f3189fe6737 Signed-off-by: Alessandro Sorniotti <[email protected]>
1 parent 2203c24 commit 655190a

File tree

6 files changed

+81
-24
lines changed

6 files changed

+81
-24
lines changed

common/cauthdsl/cauthdsl.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ func (id *mockIdentity) Validate() error {
120120
return nil
121121
}
122122

123-
func (id *mockIdentity) GetOrganizationUnits() string {
124-
return "dunno"
123+
func (id *mockIdentity) GetOrganizationalUnits() []string {
124+
return []string{"dunno"}
125125
}
126126

127127
func (id *mockIdentity) Verify(msg []byte, sig []byte) error {

msp/identities.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,13 @@ func (id *identity) Validate() error {
7070
return id.msp.Validate(id)
7171
}
7272

73-
// GetOrganizationUnits returns the OU for this instance
74-
func (id *identity) GetOrganizationUnits() string {
75-
// TODO
76-
return "dunno"
73+
// GetOrganizationalUnits returns the OU for this instance
74+
func (id *identity) GetOrganizationalUnits() []string {
75+
if id.cert == nil {
76+
return nil
77+
}
78+
79+
return id.cert.Subject.OrganizationalUnit
7780
}
7881

7982
// NewSerializedIdentity returns a serialized identity

msp/msp.go

+13-15
Original file line numberDiff line numberDiff line change
@@ -119,22 +119,20 @@ type Identity interface {
119119
// authority.
120120
Validate() error
121121

122-
// TODO: Fix this comment
123-
// GetOrganizationUnits returns the participant this identity is related to
124-
// as long as this is public information. In certain implementations
125-
// this could be implemented by certain attributes that are publicly
126-
// associated to that identity, or the identifier of the root certificate
127-
// authority that has provided signatures on this certificate.
122+
// GetOrganizationalUnits returns zero or more organization units or
123+
// divisions this identity is related to as long as this is public
124+
// information. Certain MSP implementations may use attributes
125+
// that are publicly associated to this identity, or the identifier of
126+
// the root certificate authority that has provided signatures on this
127+
// certificate.
128128
// Examples:
129-
// - ParticipantID of a fabric-tcert that was signed by TCA under name
130-
// "Organization 1", would be "Organization 1".
131-
// - ParticipantID of an alternative implementation of tcert signed by a public
132-
// CA used by organization "Organization 1", could be provided in the clear
133-
// as part of that tcert structure that this call would be able to return.
134-
// TODO: check if we need a dedicated type for participantID properly namespaced by the associated provider identifier.
135-
GetOrganizationUnits() string
136-
137-
// TODO: Discuss GetOU() further.
129+
// - if the identity is an x.509 certificate, this function returns one
130+
// or more string which is encoded in the Subject's Distinguished Name
131+
// of the type OU
132+
// TODO: For X.509 based identities, check if we need a dedicated type
133+
// for OU where the Certificate OU is properly namespaced by the
134+
// signer's identity
135+
GetOrganizationalUnits() []string
138136

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

msp/msp_test.go

+28
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"fmt"
2525

2626
"github.com/golang/protobuf/proto"
27+
"github.com/hyperledger/fabric/protos/common"
2728
"github.com/hyperledger/fabric/protos/msp"
2829
"github.com/stretchr/testify/assert"
2930
)
@@ -249,6 +250,33 @@ func TestSignAndVerify_longMessage(t *testing.T) {
249250
}
250251
}
251252

253+
func TestGetOU(t *testing.T) {
254+
id, err := localMsp.GetDefaultSigningIdentity()
255+
if err != nil {
256+
t.Fatalf("GetSigningIdentity should have succeeded")
257+
return
258+
}
259+
260+
assert.Equal(t, "COP", id.GetOrganizationalUnits()[0])
261+
}
262+
263+
func TestOUPolicyPrincipal(t *testing.T) {
264+
id, err := localMsp.GetDefaultSigningIdentity()
265+
assert.NoError(t, err)
266+
267+
ou := &common.OrganizationUnit{OrganizationalUnitIdentifier: "COP", MspIdentifier: "DEFAULT"}
268+
bytes, err := proto.Marshal(ou)
269+
assert.NoError(t, err)
270+
271+
principal := &common.MSPPrincipal{
272+
PrincipalClassification: common.MSPPrincipal_ORGANIZATION_UNIT,
273+
Principal: bytes,
274+
}
275+
276+
err = id.SatisfiesPrincipal(principal)
277+
assert.NoError(t, err)
278+
}
279+
252280
var conf *msp.MSPConfig
253281
var localMsp MSP
254282
var mspMgr MSPManager

msp/mspimpl.go

+29-1
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,35 @@ func (msp *bccspmsp) SatisfiesPrincipal(id Identity, principal *common.MSPPrinci
395395
return errors.New("The identities do not match")
396396
}
397397
case common.MSPPrincipal_ORGANIZATION_UNIT:
398-
panic("Not yet implemented")
398+
// Principal contains the OrganizationUnit
399+
OU := &common.OrganizationUnit{}
400+
err := proto.Unmarshal(principal.Principal, OU)
401+
if err != nil {
402+
return fmt.Errorf("Could not unmarshal OrganizationUnit from principal, err %s", err)
403+
}
404+
405+
// at first, we check whether the MSP
406+
// identifier is the same as that of the identity
407+
if OU.MspIdentifier != msp.name {
408+
return fmt.Errorf("The identity is a member of a different MSP (expected %s, got %s)", OU.MspIdentifier, id.GetMSPIdentifier())
409+
}
410+
411+
// we then check if the identity is valid with this MSP
412+
// and fail if it is not
413+
err = msp.Validate(id)
414+
if err != nil {
415+
return err
416+
}
417+
418+
// now we check whether any of this identity's OUs match the requested one
419+
for _, ou := range id.GetOrganizationalUnits() {
420+
if ou == OU.OrganizationalUnitIdentifier {
421+
return nil
422+
}
423+
}
424+
425+
// if we are here, no match was found, return an error
426+
return errors.New("The identities do not match")
399427
default:
400428
return fmt.Errorf("Invalid principal type %d", int32(principal.PrincipalClassification))
401429
}

msp/noopmsp.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ func (id *noopidentity) Validate() error {
9292
return nil
9393
}
9494

95-
func (id *noopidentity) GetOrganizationUnits() string {
96-
return "dunno"
95+
func (id *noopidentity) GetOrganizationalUnits() []string {
96+
return []string{"dunno"}
9797
}
9898

9999
func (id *noopidentity) Verify(msg []byte, sig []byte) error {

0 commit comments

Comments
 (0)