Skip to content

Commit

Permalink
FAB-5827 Add integration test ecert attr.
Browse files Browse the repository at this point in the history
PS 5 test ignored for v1.0

Change-Id: I8e6c207b7a967e13bb8b39fe8ec37125f16dc39a
Signed-off-by: rickr <cr22rc@gmail.com>
  • Loading branch information
cr22rc committed Oct 5, 2017
1 parent 1ceab9a commit 85ba053
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 15 deletions.
22 changes: 18 additions & 4 deletions src/main/java/org/hyperledger/fabric_ca/sdk/Attribute.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,40 @@

// An attribute name and value which is used when registering a new user
public class Attribute {
private final Boolean ecert;
private String name;
private String value;

public Attribute(String name, String value) {
this(name, value, null);
}

/**
* @param name Attribute name.
* @param value Attribute value.
* @param defaultAttribute Attribute should be included in certificate even if not specified during enrollment.
*/
public Attribute(String name, String value, Boolean defaultAttribute) {
this.name = name;
this.value = value;
this.ecert = defaultAttribute;
}

public String getName() {
return this.name;
return name;
}

public String getValue() {
return this.value;
return value;
}

public JsonObject toJsonObject() {
JsonObjectBuilder ob = Json.createObjectBuilder();
ob.add("name", this.name);
ob.add("value", this.value);
ob.add("name", name);
ob.add("value", value);
if (ecert != null) {
ob.add("ecert", ecert.booleanValue());
}
return ob.build();
}

Expand Down
35 changes: 27 additions & 8 deletions src/main/java/org/hyperledger/fabric_ca/sdk/EnrollmentRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class EnrollmentRequest {
// A PEM-encoded string containing the CSR (Certificate Signing Request) based on PKCS #10
private String csr;
// Comma-separated list of host names to associate with the certificate
private Collection<String> hosts = new ArrayList<String>();
private Collection<String> hosts = new ArrayList<>();
// Name of the signing profile to use when issuing the certificate
private String profile = null;
// Label used in HSM operations
Expand All @@ -49,7 +49,8 @@ public class EnrollmentRequest {
private String caName;

// Attribute requests. added v1.1
private Map<String, AttrReq> attrreqs = new HashMap<>();
private Map<String, AttrReq> attrreqs = null; //new HashMap<>();

/**
* The certificate signing request if it's not supplied it will be generated.
*
Expand Down Expand Up @@ -86,11 +87,6 @@ KeyPair getKeyPair() {
return keypair;
}

/**
* The keypair used to create the certificate request if it's not supplied.
* @param keypair
*/

/**
* The Key pair to create the signing certificate if not supplied it will be generated.
*
Expand Down Expand Up @@ -163,7 +159,7 @@ private JsonObject toJsonObject() {
}
factory.add("certificate_request", csr);

if (!attrreqs.isEmpty()) {
if (attrreqs != null) {
JsonArrayBuilder ab = Json.createArrayBuilder();
for (AttrReq attrReq : attrreqs.values()) {
JsonObjectBuilder i = Json.createObjectBuilder();
Expand All @@ -180,6 +176,26 @@ private JsonObject toJsonObject() {
return factory.build();
}

/**
* Add attribute request to ensure no attributes are in the certificate - not even default ones.
*
* @throws InvalidArgumentException
*/
public void addAttrReq() throws InvalidArgumentException {
if (attrreqs != null && !attrreqs.isEmpty()) {
throw new InvalidArgumentException("Attributes have already been defined.");

}
attrreqs = new HashMap<>();
}

/**
* Add attribute to certificate.
*
* @param name Name of attribute.
* @return Attribute added.
* @throws InvalidArgumentException
*/
public AttrReq addAttrReq(String name) throws InvalidArgumentException {
if (name == null || name.isEmpty()) {
throw new InvalidArgumentException("name may not be null or empty.");
Expand All @@ -194,6 +210,9 @@ public class AttrReq {

AttrReq(String name) {
this.name = name;
if (attrreqs == null) {
attrreqs = new HashMap<>();
}
attrreqs.put(name, this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ void setCAName(String caName) {
public String toJson() {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = Json.createWriter(new PrintWriter(stringWriter));
jsonWriter.writeObject(this.toJsonObject());
jsonWriter.writeObject(toJsonObject());
jsonWriter.close();
return stringWriter.toString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,12 @@ public String getTestChannelPath() {

}

public boolean isRunningAgainstFabric10() {

return "IntegrationSuiteV1.java".equals(System.getProperty("org.hyperledger.fabric.sdktest.ITSuite"));

}

private String getDomainName(final String name) {
int dot = name.indexOf(".");
if (-1 == dot) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class SampleUser implements User, Serializable {
private transient SampleStore keyValStore;
private String keyValStoreName;

SampleUser(String name, String org, SampleStore fs) {
public SampleUser(String name, String org, SampleStore fs) {
this.name = name;

this.keyValStore = fs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,23 @@ public void testEnrollReqToJsonAttrNotThere() throws Exception {
assertFalse(s.contains("\"attr_reqs\":["));
}

@Test
public void testEnrollReqToJsonAttrEmpty() throws Exception {

EnrollmentRequest testEnrollReq = new EnrollmentRequest();
testEnrollReq.addHost("d.com");
testEnrollReq.setCsr(csr);
testEnrollReq.setProfile(profile);
testEnrollReq.setLabel(label);
testEnrollReq.setKeyPair(null);
testEnrollReq.setCAName(caName);
testEnrollReq.addAttrReq(); // means empty. force no attributes.

String s = testEnrollReq.toJson();
assertNotNull(s);
assertTrue(s.contains("\"attr_reqs\":[]"));
}

@Test
public void testEnrollReqToJsonAttrNullName() throws Exception {
thrown.expect(InvalidArgumentException.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.hyperledger.fabric.sdk.Enrollment;
import org.hyperledger.fabric.sdk.security.CryptoSuite;
Expand All @@ -44,6 +47,9 @@
import org.junit.rules.ExpectedException;

import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class HFCAClientIT {
Expand Down Expand Up @@ -104,6 +110,142 @@ public void setup() throws Exception {

}

// Tests attributes
@Test
public void testRegisterAttributes() throws Exception {

if (testConfig.isRunningAgainstFabric10()) {
return; // needs v1.1
}

SampleUser user = new SampleUser("mrAttributes", TEST_ADMIN_ORG, sampleStore);

RegistrationRequest rr = new RegistrationRequest(user.getName(), TEST_USER1_AFFILIATION);
String password = "mrAttributespassword";
rr.setSecret(password);

rr.addAttribute(new Attribute("testattr1", "mrAttributesValue1"));
rr.addAttribute(new Attribute("testattr2", "mrAttributesValue2"));
rr.addAttribute(new Attribute("testattrDEFAULTATTR", "mrAttributesValueDEFAULTATTR", true));
user.setEnrollmentSecret(client.register(rr, admin));
if (!user.getEnrollmentSecret().equals(password)) {
fail("Secret returned from RegistrationRequest not match : " + user.getEnrollmentSecret());
}
EnrollmentRequest req = new EnrollmentRequest();
req.addAttrReq("testattr2").setRequire(true);

user.setEnrollment(client.enroll(user.getName(), user.getEnrollmentSecret(), req));

Enrollment enrollment = user.getEnrollment();
String cert = enrollment.getCert();
String certdec = getStringCert(cert);

assertTrue(format("Missing testattr2 in certficate decoded: %s", certdec), certdec.contains("\"testattr2\":\"mrAttributesValue2\""));
//Since request had specific attributes don't expect defaults.
assertFalse(format("Contains testattrDEFAULTATTR in certificate decoded: %s", certdec), certdec.contains("\"testattrDEFAULTATTR\"")
|| certdec.contains("\"mrAttributesValueDEFAULTATTR\""));
assertFalse(format("Contains testattr1 in certificate decoded: %s", certdec), certdec.contains("\"testattr1\"") || certdec.contains("\"mrAttributesValue1\""));

}

/**
* Test that we get default attributes.
*
* @throws Exception
*/
@Test
public void testRegisterAttributesDefault() throws Exception {

if (testConfig.isRunningAgainstFabric10()) {
return; // needs v1.1
}

SampleUser user = new SampleUser("mrAttributesDefault", TEST_ADMIN_ORG, sampleStore);

RegistrationRequest rr = new RegistrationRequest(user.getName(), TEST_USER1_AFFILIATION);
String password = "mrAttributespassword";
rr.setSecret(password);

rr.addAttribute(new Attribute("testattr1", "mrAttributesValue1"));
rr.addAttribute(new Attribute("testattr2", "mrAttributesValue2"));
rr.addAttribute(new Attribute("testattrDEFAULTATTR", "mrAttributesValueDEFAULTATTR", true));
user.setEnrollmentSecret(client.register(rr, admin));
if (!user.getEnrollmentSecret().equals(password)) {
fail("Secret returned from RegistrationRequest not match : " + user.getEnrollmentSecret());
}

user.setEnrollment(client.enroll(user.getName(), user.getEnrollmentSecret()));

Enrollment enrollment = user.getEnrollment();
String cert = enrollment.getCert();

String certdec = getStringCert(cert);

assertTrue(format("Missing testattrDEFAULTATTR in certficate decoded: %s", certdec), certdec.contains("\"testattrDEFAULTATTR\":\"mrAttributesValueDEFAULTATTR\""));
//Since request and no attribute requests at all defaults should be in certificate.

assertFalse(format("Contains testattr1 in certificate decoded: %s", certdec), certdec.contains("\"testattr1\"") || certdec.contains("\"mrAttributesValue1\""));
assertFalse(format("Contains testattr2 in certificate decoded: %s", certdec), certdec.contains("\"testattr2\"") || certdec.contains("\"mrAttributesValue2\""));

}

/**
* Test that we get no attributes.
*
* @throws Exception
*/
@Test
public void testRegisterAttributesNONE() throws Exception {

SampleUser user = new SampleUser("mrAttributesNone", TEST_ADMIN_ORG, sampleStore);

RegistrationRequest rr = new RegistrationRequest(user.getName(), TEST_USER1_AFFILIATION);
String password = "mrAttributespassword";
rr.setSecret(password);

rr.addAttribute(new Attribute("testattr1", "mrAttributesValue1"));
rr.addAttribute(new Attribute("testattr2", "mrAttributesValue2"));
rr.addAttribute(new Attribute("testattrDEFAULTATTR", "mrAttributesValueDEFAULTATTR", true));
user.setEnrollmentSecret(client.register(rr, admin));
if (!user.getEnrollmentSecret().equals(password)) {
fail("Secret returned from RegistrationRequest not match : " + user.getEnrollmentSecret());
}

EnrollmentRequest req = new EnrollmentRequest();
req.addAttrReq(); // empty ensure no attributes.

user.setEnrollment(client.enroll(user.getName(), user.getEnrollmentSecret(), req));

Enrollment enrollment = user.getEnrollment();
String cert = enrollment.getCert();

String certdec = getStringCert(cert);

assertFalse(format("Contains testattrDEFAULTATTR in certificate decoded: %s", certdec),
certdec.contains("\"testattrDEFAULTATTR\"") || certdec.contains("\"mrAttributesValueDEFAULTATTR\""));
assertFalse(format("Contains testattr1 in certificate decoded: %s", certdec), certdec.contains("\"testattr1\"") || certdec.contains("\"mrAttributesValue1\""));
assertFalse(format("Contains testattr2 in certificate decoded: %s", certdec), certdec.contains("\"testattr2\"") || certdec.contains("\"mrAttributesValue2\""));

}

private static final Pattern compile = Pattern.compile("^-----BEGIN CERTIFICATE-----$" + "(.*?)" + "\n-----END CERTIFICATE-----\n", Pattern.DOTALL | Pattern.MULTILINE);

static String getStringCert(String pemFormat) {
String ret = null;

final Matcher matcher = compile.matcher(pemFormat);
if (matcher.matches()) {
final String base64part = matcher.group(1).replaceAll("\n", "");
Base64.Decoder b64dec = Base64.getDecoder();
ret = new String(b64dec.decode(base64part.getBytes(UTF_8)));

} else {
fail("Certificate failed to match expected pattern. Certificate:\n" + pemFormat);
}

return ret;
}

// Tests re-enrolling a user that has had an enrollment revoked
@Test
public void testReenrollAndRevoke() throws Exception {
Expand Down Expand Up @@ -406,7 +548,7 @@ private void verifyOptions(String cert, EnrollmentRequest req) throws Certificat
}
ArrayList<String> subAltList = new ArrayList<>();
for (List<?> item : altNames) {
int type = ((Integer) item.get(0)).intValue();
int type = (Integer) item.get(0);
if (type == 2) {
subAltList.add((String) item.get(1));
}
Expand Down

0 comments on commit 85ba053

Please # to comment.