Skip to content

Commit

Permalink
[FAB-7128] Update SDK to comply with swagger
Browse files Browse the repository at this point in the history
Updated HFCAClient to conform to the fabric ca
swagger

Change-Id: Iad81c7559e703a61f6547d28b38d2db38b9ba62a
Signed-off-by: Saad Karim <skarim@us.ibm.com>
  • Loading branch information
Saad Karim committed Feb 9, 2018
1 parent 2adcdbc commit 77cfdc7
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 4 deletions.
85 changes: 84 additions & 1 deletion src/main/java/org/hyperledger/fabric_ca/sdk/HFCAClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,12 @@ public HFCAInfo info() throws InfoException, InvalidArgumentException {

String caName = result.getString("CAName");
String caChain = result.getString("CAChain");
String version = null;
if (result.containsKey("Version")) {
version = result.getString("Version");
}

return new HFCAInfo(caName, caChain);
return new HFCAInfo(caName, caChain, version);

} catch (Exception e) {
InfoException ee = new InfoException(format("Url:%s, Failed to get info", url), e);
Expand Down Expand Up @@ -745,6 +749,85 @@ private String revokeInternal(User revoker, String revokee, String reason, boole
}
}

/**
* revoke one certificate
*
* @param revoker admin user who has revoker attribute configured in CA-server
* @param serial serial number of the certificate to be revoked
* @param aki aki of the certificate to be revoke
* @param reason revoke reason, see RFC 5280
* @throws RevocationException
* @throws InvalidArgumentException
*/

public void revoke(User revoker, String serial, String aki, String reason) throws RevocationException, InvalidArgumentException {
revokeInternal(revoker, serial, aki, reason, false);
}

/**
* revoke one enrollment of user
*
* @param revoker admin user who has revoker attribute configured in CA-server
* @param serial serial number of the certificate to be revoked
* @param aki aki of the certificate to be revoke
* @param reason revoke reason, see RFC 5280
* @param genCRL generate CRL list
* @throws RevocationException
* @throws InvalidArgumentException
*/

public String revoke(User revoker, String serial, String aki, String reason, boolean genCRL) throws RevocationException, InvalidArgumentException {
return revokeInternal(revoker, serial, aki, reason, genCRL);
}

private String revokeInternal(User revoker, String serial, String aki, String reason, boolean genCRL) throws RevocationException, InvalidArgumentException {

if (cryptoSuite == null) {
throw new InvalidArgumentException("Crypto primitives not set.");
}

if (Utils.isNullOrEmpty(serial)) {
throw new IllegalArgumentException("Serial number id required to revoke ceritificate");
}
if (Utils.isNullOrEmpty(aki)) {
throw new IllegalArgumentException("AKI is required to revoke certificate");
}
if (revoker == null) {
throw new InvalidArgumentException("revoker is not set");
}

logger.debug(format("revoke revoker: %s, reason: %s, url: %s", revoker.getName(), reason, url));

try {
setUpSSL();

// build request body
RevocationRequest req = new RevocationRequest(caName, null, serial, aki, reason, genCRL);
String body = req.toJson();

// send revoke request
JsonObject resp = httpPost(url + HFCA_REVOKE, body, revoker);
logger.debug("revoke done");

if (genCRL) {
if (resp.isEmpty()) {
throw new RevocationException("Failed to return CRL, revoke response is empty");
}
if (resp.isNull("CRL")) {
throw new RevocationException("Failed to return CRL");
}
return resp.getString("CRL");
}
return null;
} catch (CertificateException e) {
logger.error("Cannot validate certificate. Error is: " + e.getMessage());
throw new RevocationException("Error while revoking cert. " + e.getMessage(), e);
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RevocationException("Error while revoking the user. " + e.getMessage(), e);
}
}

/**
* Generate certificate revocation list.
*
Expand Down
16 changes: 15 additions & 1 deletion src/main/java/org/hyperledger/fabric_ca/sdk/HFCAInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ public class HFCAInfo {

private final String caName;
private final String caChain;
private final String version;

public HFCAInfo(String caName, String caChain) {
// Contains server/ca information
HFCAInfo(String caName, String caChain, String version) {
this.caName = caName;
this.caChain = caChain;
this.version = version;
}

/**
Expand All @@ -49,4 +52,15 @@ public String getCAName() {
public String getCACertificateChain() {
return caChain;
}

/**
* Version of Fabric CA server
*
* @return Version of Fabric CA server, value will be
* null for Fabric CA prior to 1.1.0
*/

public String getVersion() {
return version;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ private JsonObject toJsonObject() {
factory.add("id", enrollmentID);
} else {
// revoke one particular enrollment
factory.add("serial", "0" + serial);
factory.add("serial", serial);
factory.add("aki", aki);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public void testRevocationReqToJsonNullID() {
testRevocationReq.setAki(revAKI + "000");
testRevocationReq.setReason(revReason + "update");

Assert.assertTrue(testRevocationReq.toJson().contains("0" + revSerialNmbr));
Assert.assertTrue(testRevocationReq.toJson().contains(revSerialNmbr));

} catch (Exception e) {
Assert.fail("Unexpected Exception " + e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.bind.DatatypeConverter;

import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.TBSCertList;
import org.bouncycastle.cert.X509CRLHolder;
import org.bouncycastle.openssl.PEMParser;
Expand All @@ -45,6 +50,7 @@
import org.hyperledger.fabric_ca.sdk.HFCAAffiliation.HFCAAffiliationResp;
import org.hyperledger.fabric_ca.sdk.HFCAClient;
import org.hyperledger.fabric_ca.sdk.HFCAIdentity;
import org.hyperledger.fabric_ca.sdk.HFCAInfo;
import org.hyperledger.fabric_ca.sdk.MockHFCAClient;
import org.hyperledger.fabric_ca.sdk.RegistrationRequest;
import org.hyperledger.fabric_ca.sdk.exception.EnrollmentException;
Expand All @@ -68,6 +74,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

Expand Down Expand Up @@ -368,6 +375,66 @@ public void testUserRevoke() throws Exception {
client.reenroll(user);
}

// Tests revoking a certificate
@Test
public void testCertificateRevoke() throws Exception {

SampleUser user = getTestUser(TEST_USER1_ORG);

if (!user.isRegistered()) {
RegistrationRequest rr = new RegistrationRequest(user.getName(), TEST_USER1_AFFILIATION);
String password = "testUserRevoke";
rr.setSecret(password);
rr.addAttribute(new Attribute("user.role", "department lead"));
rr.addAttribute(new Attribute(HFCAClient.HFCA_ATTRIBUTE_HFREVOKER, "true"));
user.setEnrollmentSecret(client.register(rr, admin)); // Admin can register other users.
if (!user.getEnrollmentSecret().equals(password)) {
fail("Secret returned from RegistrationRequest not match : " + user.getEnrollmentSecret());
}
}

if (!user.isEnrolled()) {
EnrollmentRequest req = new EnrollmentRequest(DEFAULT_PROFILE_NAME, "label 2", null);
req.addHost("example3.ibm.com");
user.setEnrollment(client.enroll(user.getName(), user.getEnrollmentSecret(), req));
}

// verify
String cert = user.getEnrollment().getCert();

BufferedInputStream pem = new BufferedInputStream(new ByteArrayInputStream(cert.getBytes()));
CertificateFactory certFactory = CertificateFactory.getInstance(Config.getConfig().getCertificateFormat());
X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(pem);

// get its serial number
String serial = DatatypeConverter.printHexBinary(certificate.getSerialNumber().toByteArray());

// get its aki
// 2.5.29.35 : AuthorityKeyIdentifier
byte[] extensionValue = certificate.getExtensionValue(Extension.authorityKeyIdentifier.getId());
ASN1OctetString akiOc = ASN1OctetString.getInstance(extensionValue);
String aki = DatatypeConverter.printHexBinary(AuthorityKeyIdentifier.getInstance(akiOc.getOctets()).getKeyIdentifier());


int startedWithRevokes = -1;

if (!testConfig.isRunningAgainstFabric10()) {
Thread.sleep(1000); //prevent clock skewing. make sure we request started with revokes.
startedWithRevokes = getRevokes(null).length; //one more after we do this revoke.
Thread.sleep(1000); //prevent clock skewing. make sure we request started with revokes.
}

// revoke all enrollment of this user
client.revoke(admin, serial, aki, "revoke certificate");
if (!testConfig.isRunningAgainstFabric10()) {

final int newRevokes = getRevokes(null).length;

assertEquals(format("Expected one more revocation %d, but got %d", startedWithRevokes + 1, newRevokes), startedWithRevokes + 1, newRevokes);
}
}


// Tests attempting to revoke a user with Null reason
@Test
public void testUserRevokeNullReason() throws Exception {
Expand Down Expand Up @@ -1014,6 +1081,22 @@ public void testDeleteAffiliationNotAllowed() throws Exception {
assertEquals("Incorrect status code", new Integer(400), new Integer(resp.getStatusCode()));
}

// Tests getting server/ca information
@Test
public void testGetInfo() throws Exception {

if (testConfig.isRunningAgainstFabric10()) {
HFCAInfo info = client.info();
assertNull(info.getVersion());
}

if (!testConfig.isRunningAgainstFabric10()) {
HFCAInfo info = client.info();
assertTrue(info.getVersion().contains("1.1.0"));
}

}

@Test
public void testEnrollNoKeyPair() throws Exception {

Expand Down

0 comments on commit 77cfdc7

Please sign in to comment.