-
Notifications
You must be signed in to change notification settings - Fork 708
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This change-set does the following: - It introduces an Idemix implementation of the User interface called IdemixUser. - An IdemixUserStore class have been added to load instances of IdemixUser. - Support tests Change-Id: I9b8c4f2aacb132e6cb0b74c0ea3ccbeb61ef63be Signed-off-by: Angelo De Caro <adc@zurich.ibm.com> Signed-off-by: Manu Drijvers (mdr@zurich.ibm.com)
- Loading branch information
Showing
15 changed files
with
310 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
src/main/java/org/hyperledger/fabric/sdk/user/IdemixUser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package org.hyperledger.fabric.sdk.user; | ||
|
||
import java.security.PublicKey; | ||
import java.util.Set; | ||
|
||
import org.apache.milagro.amcl.FP256BN.BIG; | ||
import org.hyperledger.fabric.protos.idemix.Idemix; | ||
import org.hyperledger.fabric.sdk.Enrollment; | ||
import org.hyperledger.fabric.sdk.User; | ||
import org.hyperledger.fabric.sdk.exception.CryptoException; | ||
import org.hyperledger.fabric.sdk.exception.InvalidArgumentException; | ||
import org.hyperledger.fabric.sdk.idemix.IdemixCredential; | ||
import org.hyperledger.fabric.sdk.idemix.IdemixIssuerPublicKey; | ||
import org.hyperledger.fabric.sdk.identity.IdemixEnrollment; | ||
import org.hyperledger.fabric.sdk.identity.IdemixSigningIdentity; | ||
import org.hyperledger.fabric.sdk.identity.SigningIdentity; | ||
|
||
public class IdemixUser implements User { | ||
|
||
protected final String name; | ||
protected final String mspId; | ||
protected final IdemixEnrollment enrollment; | ||
|
||
public IdemixUser(String name, String mspId, IdemixEnrollment enrollment) { | ||
this.name = name; | ||
this.mspId = mspId; | ||
this.enrollment = enrollment; | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return this.name; | ||
} | ||
|
||
@Override | ||
public Set<String> getRoles() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public String getAccount() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public String getAffiliation() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public Enrollment getEnrollment() { | ||
return this.enrollment; | ||
} | ||
|
||
@Override | ||
public String getMspId() { | ||
return this.mspId; | ||
} | ||
|
||
public IdemixIssuerPublicKey getIpk() { | ||
return this.enrollment.getIpk(); | ||
} | ||
|
||
public IdemixCredential getIdemixCredential() { | ||
return this.enrollment.getCred(); | ||
} | ||
|
||
public Idemix.CredentialRevocationInformation getCri() { | ||
return this.enrollment.getCri(); | ||
} | ||
|
||
public BIG getSk() { | ||
return this.enrollment.getSk(); | ||
} | ||
|
||
public PublicKey getRevocationPk() { | ||
return this.enrollment.getRevocationPk(); | ||
} | ||
|
||
public String getOu() { | ||
return this.enrollment.getOu(); | ||
} | ||
|
||
public boolean getRole() { | ||
return this.enrollment.getRole(); | ||
} | ||
} |
103 changes: 103 additions & 0 deletions
103
src/main/java/org/hyperledger/fabric/sdk/user/IdemixUserStore.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package org.hyperledger.fabric.sdk.user; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.security.KeyFactory; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.PublicKey; | ||
import java.security.spec.InvalidKeySpecException; | ||
import java.security.spec.X509EncodedKeySpec; | ||
|
||
import com.google.protobuf.InvalidProtocolBufferException; | ||
import org.apache.milagro.amcl.FP256BN.BIG; | ||
import org.hyperledger.fabric.protos.idemix.Idemix; | ||
import org.hyperledger.fabric.protos.msp.MspConfig; | ||
import org.hyperledger.fabric.sdk.User; | ||
import org.hyperledger.fabric.sdk.exception.CryptoException; | ||
import org.hyperledger.fabric.sdk.idemix.IdemixCredential; | ||
import org.hyperledger.fabric.sdk.idemix.IdemixIssuerPublicKey; | ||
import org.hyperledger.fabric.sdk.identity.IdemixEnrollment; | ||
|
||
public class IdemixUserStore { | ||
|
||
private static final String USER_PATH = "user"; | ||
private static final String VERIFIER_PATH = "msp"; | ||
private static final String IPK_CONFIG = "IssuerPublicKey"; | ||
private static final String REVOCATION_PUBLIC_KEY = "RevocationPublicKey"; | ||
|
||
|
||
protected final String storePath; | ||
protected final String mspId; | ||
protected final IdemixIssuerPublicKey ipk; | ||
|
||
public IdemixUserStore(String storePath, String mspId) throws CryptoException { | ||
this.storePath = storePath; | ||
this.mspId = mspId; | ||
Idemix.IssuerPublicKey ipkProto = readIdemixIssuerPublicKey(Paths.get(mspId, VERIFIER_PATH + IPK_CONFIG).toString()); | ||
this.ipk = new IdemixIssuerPublicKey(ipkProto); | ||
if (!this.ipk.check()) { | ||
throw new CryptoException("Failed verifying issuer public key."); | ||
} | ||
} | ||
|
||
public User getUser(String id) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { | ||
MspConfig.IdemixMSPSignerConfig signerConfig = readIdemixMSPConfig(Paths.get(this.mspId, USER_PATH + id).toString()); | ||
PublicKey revocationPk = readIdemixRevocationPublicKey(this.mspId); | ||
BIG sk = BIG.fromBytes(signerConfig.getSk().toByteArray()); | ||
IdemixCredential cred = new IdemixCredential(Idemix.Credential.parseFrom(signerConfig.getCred())); | ||
Idemix.CredentialRevocationInformation cri = Idemix.CredentialRevocationInformation.parseFrom(signerConfig.getCredentialRevocationInformation()); | ||
|
||
IdemixEnrollment enrollment = new IdemixEnrollment(this.ipk, revocationPk, this.mspId, sk, cred, cri, signerConfig.getOrganizationalUnitIdentifier(), signerConfig.getIsAdmin()); | ||
return new IdemixUser(id, this.mspId, enrollment); | ||
} | ||
|
||
/** | ||
* Helper function: parse Idemix MSP Signer config (is part of the MSPConfig proto) from path | ||
* | ||
* @param id | ||
* @return IdemixMSPSignerConfig proto | ||
*/ | ||
protected MspConfig.IdemixMSPSignerConfig readIdemixMSPConfig(String id) throws IOException { | ||
Path path = Paths.get(this.storePath + id); | ||
return MspConfig.IdemixMSPSignerConfig.parseFrom(Files.readAllBytes(path)); | ||
} | ||
|
||
/** | ||
* Parse Idemix issuer public key from the config file | ||
* | ||
* @param id | ||
* @return Idemix IssuerPublicKey proto | ||
*/ | ||
protected Idemix.IssuerPublicKey readIdemixIssuerPublicKey(String id) { | ||
Path path = Paths.get(this.storePath + id); | ||
byte[] data = null; | ||
try { | ||
data = Files.readAllBytes(path); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
|
||
Idemix.IssuerPublicKey ipk = null; | ||
|
||
try { | ||
ipk = Idemix.IssuerPublicKey.parseFrom(data); | ||
} catch (InvalidProtocolBufferException e) { | ||
e.printStackTrace(); | ||
} | ||
|
||
return ipk; | ||
} | ||
|
||
/** | ||
* Parse Idemix long-term revocation public key | ||
* | ||
* @param id | ||
* @return idemix long-term revocation public key | ||
*/ | ||
protected PublicKey readIdemixRevocationPublicKey(String id) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { | ||
Path path = Paths.get(this.mspId, VERIFIER_PATH + id); | ||
return KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(Files.readAllBytes(path))); | ||
} | ||
} |
Oops, something went wrong.