Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

Commit 6c6666b

Browse files
Rafa TorresMaria Dubovitskaya
authored andcommitted
FIX [FAB-11993] idemix role from boolean to int
Replacing boolean type of idemix role with integer to support more role types. Provides "idemix roles" to map multiple MSP Roles to only one bitsmak integer value. Change-Id: I942dab4168f8da83551c646e0d4245f31e73120a Signed-off-by: Rafa Torres <rtm@zurich.ibm.com> Signed-off-by: Keith Smith <bksmith@us.ibm.com> Signed-off-by: Maria Dubovitskaya <mdu@zurich.ibm.com>
1 parent ef604d1 commit 6c6666b

39 files changed

+242
-90
lines changed

src/main/java/org/hyperledger/fabric/sdk/identity/IdemixEnrollment.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@ public class IdemixEnrollment implements Enrollment {
2323
protected final IdemixCredential cred;
2424
protected final CredentialRevocationInformation cri;
2525
protected final String ou;
26-
protected final boolean role;
26+
protected final int roleMask;
2727

28-
public IdemixEnrollment(IdemixIssuerPublicKey ipk, PublicKey revocationPk, String mspId, BIG sk, IdemixCredential cred, CredentialRevocationInformation cri, String ou, boolean role) {
28+
public IdemixEnrollment(IdemixIssuerPublicKey ipk, PublicKey revocationPk, String mspId, BIG sk, IdemixCredential cred, CredentialRevocationInformation cri, String ou, int roleMask) {
2929
this.ipk = ipk;
3030
this.revocationPk = revocationPk;
3131
this.mspId = mspId;
3232
this.sk = sk;
3333
this.cred = cred;
3434
this.cri = cri;
3535
this.ou = ou;
36-
this.role = role;
36+
this.roleMask = roleMask;
3737
}
3838

3939
public PrivateKey getKey() {
@@ -72,7 +72,7 @@ public String getOu() {
7272
return this.ou;
7373
}
7474

75-
public boolean getRole() {
76-
return this.role;
75+
public int getRoleMask() {
76+
return this.roleMask;
7777
}
78-
}
78+
}

src/main/java/org/hyperledger/fabric/sdk/identity/IdemixIdentity.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ public class IdemixIdentity implements Identity {
5454
// Organization Unit attribute
5555
private final String ou;
5656

57-
// Role attribute
58-
private final boolean role;
57+
// Role mask its a bitmask that represent all the roles attached to this identity
58+
private final int roleMask;
5959

6060
// Proof of possession of Idemix credential
6161
// with respect to the pseudonym (nym)
62-
// and the corresponding attributes (ou, role)
62+
// and the corresponding attributes (ou, roleMask)
6363
private final IdemixSignature associationProof;
6464

6565
/**
@@ -89,7 +89,7 @@ public IdemixIdentity(Identities.SerializedIdentity proto) throws CryptoExceptio
8989
MspPrincipal.MSPRole role = MspPrincipal.MSPRole.parseFrom(idemixProto.getRole());
9090

9191
this.ou = ou.getOrganizationalUnitIdentifier();
92-
this.role = role.getRole().getNumber() == 1;
92+
this.roleMask = IdemixRoles.getRoleMask(role);
9393
this.ipkHash = ou.getCertifiersIdentifier().toByteArray();
9494

9595
logger.trace("Deserializing Proof");
@@ -106,10 +106,10 @@ public IdemixIdentity(Identities.SerializedIdentity proto) throws CryptoExceptio
106106
* @param mspId is MSP ID sting
107107
* @param nym is Identity Mixer Pseudonym
108108
* @param ou is OU attribute
109-
* @param role is Role attribute
109+
* @param roleMask is a bitmask that represent all the roles attached to this identity
110110
* @param proof is Proof
111111
*/
112-
public IdemixIdentity(String mspId, IdemixIssuerPublicKey ipk, ECP nym, String ou, boolean role, IdemixSignature proof)
112+
public IdemixIdentity(String mspId, IdemixIssuerPublicKey ipk, ECP nym, String ou, int roleMask, IdemixSignature proof)
113113
throws InvalidArgumentException {
114114

115115
if (mspId == null) {
@@ -145,7 +145,7 @@ public IdemixIdentity(String mspId, IdemixIssuerPublicKey ipk, ECP nym, String o
145145
this.ipkHash = ipk.getHash();
146146
this.pseudonym = nym;
147147
this.ou = ou;
148-
this.role = role;
148+
this.roleMask = roleMask;
149149
this.associationProof = proof;
150150
}
151151

@@ -160,8 +160,10 @@ public Identities.SerializedIdentity createSerializedIdentity() {
160160
.setOrganizationalUnitIdentifier(this.ou)
161161
.build();
162162

163+
//Warning, this does not support multi-roleMask.
164+
//Serialize the bitmask is the correct way to support multi-roleMask in the future
163165
MspPrincipal.MSPRole role = MspPrincipal.MSPRole.newBuilder()
164-
.setRole(this.role ? MspPrincipal.MSPRole.MSPRoleType.ADMIN : MspPrincipal.MSPRole.MSPRoleType.MEMBER)
166+
.setRole(IdemixRoles.getMSPRoleFromIdemixRole(this.roleMask))
165167
.setMspIdentifier(this.mspId)
166168
.build();
167169

@@ -183,8 +185,8 @@ public String getOuValue() {
183185
return this.ou;
184186
}
185187

186-
public boolean getRoleValue() {
187-
return this.role;
188+
public int getRoleMask() {
189+
return this.roleMask;
188190
}
189191

190192
@Override
@@ -194,7 +196,7 @@ public String toString() {
194196
" Issuer Public Key Hash: " + Arrays.toString(this.ipkHash) +
195197
" Pseudonym: " + this.pseudonym.toRawString() +
196198
" OU: " + this.ou +
197-
" Role: " + this.role +
199+
" Role mask: " + this.roleMask +
198200
" Association Proof: " + this.associationProof.toProto().toString() +
199201
" ]";
200202
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package org.hyperledger.fabric.sdk.identity;
2+
3+
import org.hyperledger.fabric.protos.common.MspPrincipal;
4+
5+
/**
6+
* IdemixRoles is ENUM type that represent a Idemix Role and provide some functionality to operate with Bitmasks
7+
* and to operate between MSPRoles and IdemixRoles.
8+
*/
9+
public enum IdemixRoles {
10+
MEMBER(1),
11+
ADMIN(2),
12+
CLIENT(4),
13+
PEER(8);
14+
// Next roles values: 8, 16, 32 ..
15+
16+
private int value;
17+
18+
IdemixRoles(int value) {
19+
this.value = value;
20+
}
21+
22+
int getValue() {
23+
return this.value;
24+
}
25+
26+
/**
27+
* Receives an array of IdemixRoles and returns the bitmask combination of all
28+
* @param roles that we want to combine
29+
* @return bitmask
30+
*/
31+
static int getRoleMask(IdemixRoles[] roles) {
32+
int mask = 0;
33+
for (IdemixRoles role: roles) {
34+
mask = mask | role.value;
35+
}
36+
return mask;
37+
}
38+
39+
/**
40+
* Receives an array of MspPrincipal.MSPRole and returns the bitmask combination of all
41+
* @param roles that we want to combine
42+
* @return bitmask
43+
*/
44+
static int getRoleMask(MspPrincipal.MSPRole [] roles) {
45+
int mask = 0;
46+
for (MspPrincipal.MSPRole role: roles) {
47+
mask = mask | getIdemixRoleFromMSPRole(role);
48+
}
49+
return mask;
50+
}
51+
52+
/**
53+
* Receives a MspPrincipal.MSPRole and returns the bitmask
54+
* @param role that we want to combine
55+
* @return bitmask
56+
*/
57+
static int getRoleMask(MspPrincipal.MSPRole role) {
58+
return getRoleMask(new MspPrincipal.MSPRole[]{role});
59+
}
60+
61+
/**
62+
* Receives a bitmask and a roleMask to test. If the roleMask is contained in the bit mask returns true.
63+
* @param bitmask where to test the roleMask
64+
* @param searchRole roleMask to test
65+
* @return true if roleMask contained
66+
*/
67+
static boolean checkRole(int bitmask, IdemixRoles searchRole) {
68+
return (bitmask & searchRole.value) == searchRole.value;
69+
}
70+
71+
/**
72+
* Receives a MSPRole and returns the correspondent IdemixRole value
73+
* @param role to transform to int
74+
* @return IdemixRole value
75+
*/
76+
static int getIdemixRoleFromMSPRole(MspPrincipal.MSPRole role) {
77+
return getIdemixRoleFromMSPRole(role.getRole());
78+
}
79+
80+
/**
81+
* Receives a MSPRole Type and returns the correspondent IdemixRole value
82+
* @param type to transform to int
83+
* @return IdemixRole value
84+
*/
85+
static int getIdemixRoleFromMSPRole(MspPrincipal.MSPRole.MSPRoleType type) {
86+
return getIdemixRoleFromMSPRole(type.getNumber());
87+
}
88+
89+
/**
90+
* Receives a MSPRole int value and returns the correspondent IdemixRole value
91+
* @param type to transform to int
92+
* @return IdemixRole value
93+
*/
94+
static int getIdemixRoleFromMSPRole(int type) {
95+
switch (type) {
96+
case MspPrincipal.MSPRole.MSPRoleType.ADMIN_VALUE:
97+
return ADMIN.getValue();
98+
case MspPrincipal.MSPRole.MSPRoleType.MEMBER_VALUE:
99+
return MEMBER.getValue();
100+
case MspPrincipal.MSPRole.MSPRoleType.PEER_VALUE:
101+
return PEER.getValue();
102+
case MspPrincipal.MSPRole.MSPRoleType.CLIENT_VALUE:
103+
return CLIENT.getValue();
104+
default:
105+
throw new IllegalArgumentException("The provided role is not valid: " + type);
106+
}
107+
}
108+
109+
/**
110+
* Receives an integer that represents a roleMask and return the correspondent MSPRole value
111+
* @param role to transform to MSProle
112+
* @return MSPRole
113+
*/
114+
static MspPrincipal.MSPRole.MSPRoleType getMSPRoleFromIdemixRole(int role) {
115+
if (role == ADMIN.getValue()) {
116+
return MspPrincipal.MSPRole.MSPRoleType.ADMIN;
117+
}
118+
119+
if (role == MEMBER.getValue()) {
120+
return MspPrincipal.MSPRole.MSPRoleType.MEMBER;
121+
}
122+
123+
if (role == CLIENT.getValue()) {
124+
return MspPrincipal.MSPRole.MSPRoleType.CLIENT;
125+
}
126+
127+
if (role == PEER.getValue()) {
128+
return MspPrincipal.MSPRole.MSPRoleType.PEER;
129+
}
130+
131+
throw new IllegalArgumentException("The provided role value is not valid: " + role);
132+
}
133+
}

src/main/java/org/hyperledger/fabric/sdk/identity/IdemixSigningIdentity.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public class IdemixSigningIdentity implements SigningIdentity {
8282

8383
public IdemixSigningIdentity(IdemixEnrollment enrollment) throws CryptoException, InvalidArgumentException {
8484
this(enrollment.ipk, enrollment.revocationPk, enrollment.mspId, enrollment.sk, enrollment.cred,
85-
enrollment.cri, enrollment.ou, enrollment.role);
85+
enrollment.cri, enrollment.ou, enrollment.roleMask);
8686
}
8787

8888
/**
@@ -99,7 +99,7 @@ public IdemixSigningIdentity(IdemixEnrollment enrollment) throws CryptoException
9999
* @throws CryptoException
100100
* @throws InvalidArgumentException
101101
*/
102-
public IdemixSigningIdentity(IdemixIssuerPublicKey ipk, PublicKey revocationPk, String mspId, BIG sk, IdemixCredential cred, Idemix.CredentialRevocationInformation cri, String ou, boolean role)
102+
public IdemixSigningIdentity(IdemixIssuerPublicKey ipk, PublicKey revocationPk, String mspId, BIG sk, IdemixCredential cred, Idemix.CredentialRevocationInformation cri, String ou, int role)
103103
throws CryptoException, InvalidArgumentException {
104104

105105
// input checks
@@ -174,14 +174,7 @@ public IdemixSigningIdentity(IdemixIssuerPublicKey ipk, PublicKey revocationPk,
174174
throw new CryptoException("Error: There are " + cred.getAttrs().length + " attributes and the expected are 4");
175175
}
176176
byte[] ouBytes = cred.getAttrs()[0];
177-
byte[] ouProtoBytes = MspPrincipal.OrganizationUnit.newBuilder()
178-
.setMspIdentifier(mspId)
179-
.setOrganizationalUnitIdentifier(new String(ouBytes))
180-
.build().toByteArray();
181177
byte[] roleBytes = cred.getAttrs()[1];
182-
byte[] roleProtoBytes = MspPrincipal.MSPRole.newBuilder()
183-
.setRoleValue(ByteBuffer.wrap(roleBytes).getInt())
184-
.build().toByteArray();
185178
byte[] eIdBytes = cred.getAttrs()[2];
186179
byte[] rHBytes = cred.getAttrs()[3];
187180

@@ -197,7 +190,7 @@ public IdemixSigningIdentity(IdemixIssuerPublicKey ipk, PublicKey revocationPk,
197190
}
198191

199192
// check that the role matches the credential's attribute value
200-
if (!Arrays.equals(IdemixUtils.bigToBytes(new BIG(role ? 1 : 0)), roleBytes)) {
193+
if (!Arrays.equals(IdemixUtils.bigToBytes(new BIG(role)), roleBytes)) {
201194
throw new IllegalArgumentException("the role does not match the credential");
202195
}
203196

src/main/java/org/hyperledger/fabric/sdk/user/IdemixUser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public String getOu() {
7777
return this.enrollment.getOu();
7878
}
7979

80-
public boolean getRole() {
81-
return this.enrollment.getRole();
80+
public int getRoleMask() {
81+
return this.enrollment.getRoleMask();
8282
}
8383
}

src/main/java/org/hyperledger/fabric/sdk/user/IdemixUserStore.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public User getUser(String id) throws IOException, NoSuchAlgorithmException, Inv
4949
IdemixCredential cred = new IdemixCredential(Idemix.Credential.parseFrom(signerConfig.getCred()));
5050
Idemix.CredentialRevocationInformation cri = Idemix.CredentialRevocationInformation.parseFrom(signerConfig.getCredentialRevocationInformation());
5151

52-
IdemixEnrollment enrollment = new IdemixEnrollment(this.ipk, revocationPk, this.mspId, sk, cred, cri, signerConfig.getOrganizationalUnitIdentifier(), signerConfig.getIsAdmin());
52+
IdemixEnrollment enrollment = new IdemixEnrollment(this.ipk, revocationPk, this.mspId, sk, cred, cri, signerConfig.getOrganizationalUnitIdentifier(), signerConfig.getRole());
5353
return new IdemixUser(id, this.mspId, enrollment);
5454
}
5555

src/main/java/org/hyperledger/fabric_ca/sdk/HFCAClient.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
101101
import org.bouncycastle.asn1.x509.Extension;
102102
import org.bouncycastle.util.io.pem.PemReader;
103+
import org.hyperledger.fabric.protos.common.MspPrincipal;
103104
import org.hyperledger.fabric.protos.idemix.Idemix;
104105
import org.hyperledger.fabric.sdk.Enrollment;
105106
import org.hyperledger.fabric.sdk.NetworkConfig;
@@ -110,6 +111,7 @@
110111
import org.hyperledger.fabric.sdk.idemix.IdemixIssuerPublicKey;
111112
import org.hyperledger.fabric.sdk.idemix.IdemixUtils;
112113
import org.hyperledger.fabric.sdk.identity.IdemixEnrollment;
114+
import org.hyperledger.fabric.sdk.identity.IdemixRoles;
113115
import org.hyperledger.fabric.sdk.identity.X509Enrollment;
114116
import org.hyperledger.fabric.sdk.security.CryptoPrimitives;
115117
import org.hyperledger.fabric.sdk.security.CryptoSuite;
@@ -1171,7 +1173,7 @@ public Enrollment idemixEnroll(Enrollment enrollment, String mspID) throws Enrol
11711173
if (Utils.isNullOrEmpty(ou)) {
11721174
throw new InvalidArgumentException("fabric-ca-server did not return a 'ou' attribute in the response from " + HFCA_IDEMIXCRED);
11731175
}
1174-
boolean role = attrs.getBoolean("Role");
1176+
int role = attrs.getInt("Role"); // Encoded IdemixRole from Fabric-Ca
11751177

11761178
// Return the idemix enrollment
11771179
return new IdemixEnrollment(ipk, rpk, mspID, sk, cred, cri, ou, role);

src/main/proto/msp/msp_config.proto

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ message IdemixMSPSignerConfig {
135135
// organizational_unit_identifier defines the organizational unit the default signer is in
136136
string organizational_unit_identifier = 3;
137137

138-
// is_admin defines whether the default signer is admin or not
139-
bool is_admin = 4;
138+
// role defines whether the default signer is admin, peer, member or client
139+
int32 role = 4;
140140

141141
// enrollment_id contains the enrollment id of this signer
142142
string enrollment_id = 5;
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)