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

Commit 77cfdc7

Browse files
author
Saad Karim
committed
[FAB-7128] Update SDK to comply with swagger
Updated HFCAClient to conform to the fabric ca swagger Change-Id: Iad81c7559e703a61f6547d28b38d2db38b9ba62a Signed-off-by: Saad Karim <skarim@us.ibm.com>
1 parent 2adcdbc commit 77cfdc7

File tree

5 files changed

+184
-4
lines changed

5 files changed

+184
-4
lines changed

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

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,8 +496,12 @@ public HFCAInfo info() throws InfoException, InvalidArgumentException {
496496

497497
String caName = result.getString("CAName");
498498
String caChain = result.getString("CAChain");
499+
String version = null;
500+
if (result.containsKey("Version")) {
501+
version = result.getString("Version");
502+
}
499503

500-
return new HFCAInfo(caName, caChain);
504+
return new HFCAInfo(caName, caChain, version);
501505

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

752+
/**
753+
* revoke one certificate
754+
*
755+
* @param revoker admin user who has revoker attribute configured in CA-server
756+
* @param serial serial number of the certificate to be revoked
757+
* @param aki aki of the certificate to be revoke
758+
* @param reason revoke reason, see RFC 5280
759+
* @throws RevocationException
760+
* @throws InvalidArgumentException
761+
*/
762+
763+
public void revoke(User revoker, String serial, String aki, String reason) throws RevocationException, InvalidArgumentException {
764+
revokeInternal(revoker, serial, aki, reason, false);
765+
}
766+
767+
/**
768+
* revoke one enrollment of user
769+
*
770+
* @param revoker admin user who has revoker attribute configured in CA-server
771+
* @param serial serial number of the certificate to be revoked
772+
* @param aki aki of the certificate to be revoke
773+
* @param reason revoke reason, see RFC 5280
774+
* @param genCRL generate CRL list
775+
* @throws RevocationException
776+
* @throws InvalidArgumentException
777+
*/
778+
779+
public String revoke(User revoker, String serial, String aki, String reason, boolean genCRL) throws RevocationException, InvalidArgumentException {
780+
return revokeInternal(revoker, serial, aki, reason, genCRL);
781+
}
782+
783+
private String revokeInternal(User revoker, String serial, String aki, String reason, boolean genCRL) throws RevocationException, InvalidArgumentException {
784+
785+
if (cryptoSuite == null) {
786+
throw new InvalidArgumentException("Crypto primitives not set.");
787+
}
788+
789+
if (Utils.isNullOrEmpty(serial)) {
790+
throw new IllegalArgumentException("Serial number id required to revoke ceritificate");
791+
}
792+
if (Utils.isNullOrEmpty(aki)) {
793+
throw new IllegalArgumentException("AKI is required to revoke certificate");
794+
}
795+
if (revoker == null) {
796+
throw new InvalidArgumentException("revoker is not set");
797+
}
798+
799+
logger.debug(format("revoke revoker: %s, reason: %s, url: %s", revoker.getName(), reason, url));
800+
801+
try {
802+
setUpSSL();
803+
804+
// build request body
805+
RevocationRequest req = new RevocationRequest(caName, null, serial, aki, reason, genCRL);
806+
String body = req.toJson();
807+
808+
// send revoke request
809+
JsonObject resp = httpPost(url + HFCA_REVOKE, body, revoker);
810+
logger.debug("revoke done");
811+
812+
if (genCRL) {
813+
if (resp.isEmpty()) {
814+
throw new RevocationException("Failed to return CRL, revoke response is empty");
815+
}
816+
if (resp.isNull("CRL")) {
817+
throw new RevocationException("Failed to return CRL");
818+
}
819+
return resp.getString("CRL");
820+
}
821+
return null;
822+
} catch (CertificateException e) {
823+
logger.error("Cannot validate certificate. Error is: " + e.getMessage());
824+
throw new RevocationException("Error while revoking cert. " + e.getMessage(), e);
825+
} catch (Exception e) {
826+
logger.error(e.getMessage(), e);
827+
throw new RevocationException("Error while revoking the user. " + e.getMessage(), e);
828+
}
829+
}
830+
748831
/**
749832
* Generate certificate revocation list.
750833
*

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,13 @@ public class HFCAInfo {
2424

2525
private final String caName;
2626
private final String caChain;
27+
private final String version;
2728

28-
public HFCAInfo(String caName, String caChain) {
29+
// Contains server/ca information
30+
HFCAInfo(String caName, String caChain, String version) {
2931
this.caName = caName;
3032
this.caChain = caChain;
33+
this.version = version;
3134
}
3235

3336
/**
@@ -49,4 +52,15 @@ public String getCAName() {
4952
public String getCACertificateChain() {
5053
return caChain;
5154
}
55+
56+
/**
57+
* Version of Fabric CA server
58+
*
59+
* @return Version of Fabric CA server, value will be
60+
* null for Fabric CA prior to 1.1.0
61+
*/
62+
63+
public String getVersion() {
64+
return version;
65+
}
5266
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ private JsonObject toJsonObject() {
118118
factory.add("id", enrollmentID);
119119
} else {
120120
// revoke one particular enrollment
121-
factory.add("serial", "0" + serial);
121+
factory.add("serial", serial);
122122
factory.add("aki", aki);
123123
}
124124

src/test/java/org/hyperledger/fabric_ca/sdk/RevocationRequestTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public void testRevocationReqToJsonNullID() {
9898
testRevocationReq.setAki(revAKI + "000");
9999
testRevocationReq.setReason(revReason + "update");
100100

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

103103
} catch (Exception e) {
104104
Assert.fail("Unexpected Exception " + e.getMessage());

src/test/java/org/hyperledger/fabric_ca/sdkintegration/HFCAClientIT.java

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131
import java.util.regex.Matcher;
3232
import java.util.regex.Pattern;
3333

34+
import javax.xml.bind.DatatypeConverter;
35+
36+
import org.bouncycastle.asn1.ASN1OctetString;
37+
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
38+
import org.bouncycastle.asn1.x509.Extension;
3439
import org.bouncycastle.asn1.x509.TBSCertList;
3540
import org.bouncycastle.cert.X509CRLHolder;
3641
import org.bouncycastle.openssl.PEMParser;
@@ -45,6 +50,7 @@
4550
import org.hyperledger.fabric_ca.sdk.HFCAAffiliation.HFCAAffiliationResp;
4651
import org.hyperledger.fabric_ca.sdk.HFCAClient;
4752
import org.hyperledger.fabric_ca.sdk.HFCAIdentity;
53+
import org.hyperledger.fabric_ca.sdk.HFCAInfo;
4854
import org.hyperledger.fabric_ca.sdk.MockHFCAClient;
4955
import org.hyperledger.fabric_ca.sdk.RegistrationRequest;
5056
import org.hyperledger.fabric_ca.sdk.exception.EnrollmentException;
@@ -68,6 +74,7 @@
6874
import static org.junit.Assert.assertFalse;
6975
import static org.junit.Assert.assertNotEquals;
7076
import static org.junit.Assert.assertNotNull;
77+
import static org.junit.Assert.assertNull;
7178
import static org.junit.Assert.assertTrue;
7279
import static org.junit.Assert.fail;
7380

@@ -368,6 +375,66 @@ public void testUserRevoke() throws Exception {
368375
client.reenroll(user);
369376
}
370377

378+
// Tests revoking a certificate
379+
@Test
380+
public void testCertificateRevoke() throws Exception {
381+
382+
SampleUser user = getTestUser(TEST_USER1_ORG);
383+
384+
if (!user.isRegistered()) {
385+
RegistrationRequest rr = new RegistrationRequest(user.getName(), TEST_USER1_AFFILIATION);
386+
String password = "testUserRevoke";
387+
rr.setSecret(password);
388+
rr.addAttribute(new Attribute("user.role", "department lead"));
389+
rr.addAttribute(new Attribute(HFCAClient.HFCA_ATTRIBUTE_HFREVOKER, "true"));
390+
user.setEnrollmentSecret(client.register(rr, admin)); // Admin can register other users.
391+
if (!user.getEnrollmentSecret().equals(password)) {
392+
fail("Secret returned from RegistrationRequest not match : " + user.getEnrollmentSecret());
393+
}
394+
}
395+
396+
if (!user.isEnrolled()) {
397+
EnrollmentRequest req = new EnrollmentRequest(DEFAULT_PROFILE_NAME, "label 2", null);
398+
req.addHost("example3.ibm.com");
399+
user.setEnrollment(client.enroll(user.getName(), user.getEnrollmentSecret(), req));
400+
}
401+
402+
// verify
403+
String cert = user.getEnrollment().getCert();
404+
405+
BufferedInputStream pem = new BufferedInputStream(new ByteArrayInputStream(cert.getBytes()));
406+
CertificateFactory certFactory = CertificateFactory.getInstance(Config.getConfig().getCertificateFormat());
407+
X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(pem);
408+
409+
// get its serial number
410+
String serial = DatatypeConverter.printHexBinary(certificate.getSerialNumber().toByteArray());
411+
412+
// get its aki
413+
// 2.5.29.35 : AuthorityKeyIdentifier
414+
byte[] extensionValue = certificate.getExtensionValue(Extension.authorityKeyIdentifier.getId());
415+
ASN1OctetString akiOc = ASN1OctetString.getInstance(extensionValue);
416+
String aki = DatatypeConverter.printHexBinary(AuthorityKeyIdentifier.getInstance(akiOc.getOctets()).getKeyIdentifier());
417+
418+
419+
int startedWithRevokes = -1;
420+
421+
if (!testConfig.isRunningAgainstFabric10()) {
422+
Thread.sleep(1000); //prevent clock skewing. make sure we request started with revokes.
423+
startedWithRevokes = getRevokes(null).length; //one more after we do this revoke.
424+
Thread.sleep(1000); //prevent clock skewing. make sure we request started with revokes.
425+
}
426+
427+
// revoke all enrollment of this user
428+
client.revoke(admin, serial, aki, "revoke certificate");
429+
if (!testConfig.isRunningAgainstFabric10()) {
430+
431+
final int newRevokes = getRevokes(null).length;
432+
433+
assertEquals(format("Expected one more revocation %d, but got %d", startedWithRevokes + 1, newRevokes), startedWithRevokes + 1, newRevokes);
434+
}
435+
}
436+
437+
371438
// Tests attempting to revoke a user with Null reason
372439
@Test
373440
public void testUserRevokeNullReason() throws Exception {
@@ -1014,6 +1081,22 @@ public void testDeleteAffiliationNotAllowed() throws Exception {
10141081
assertEquals("Incorrect status code", new Integer(400), new Integer(resp.getStatusCode()));
10151082
}
10161083

1084+
// Tests getting server/ca information
1085+
@Test
1086+
public void testGetInfo() throws Exception {
1087+
1088+
if (testConfig.isRunningAgainstFabric10()) {
1089+
HFCAInfo info = client.info();
1090+
assertNull(info.getVersion());
1091+
}
1092+
1093+
if (!testConfig.isRunningAgainstFabric10()) {
1094+
HFCAInfo info = client.info();
1095+
assertTrue(info.getVersion().contains("1.1.0"));
1096+
}
1097+
1098+
}
1099+
10171100
@Test
10181101
public void testEnrollNoKeyPair() throws Exception {
10191102

0 commit comments

Comments
 (0)