Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#19] General Name/DN equals functionality #93

Merged
merged 10 commits into from
Feb 19, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import hirs.data.persist.certificate.PlatformCredential;
import hirs.data.persist.certificate.attributes.PlatformConfiguration;
import hirs.persist.CertificateManager;
import hirs.utils.BouncyCastleUtils;

/**
* Utility class for mapping certificate information in to string maps. These are used to display
Expand Down Expand Up @@ -140,12 +141,13 @@ public static Certificate containsAllChain(
.getCertificates();
}

for (Certificate issuerCert: issuerCertificates) {
for (Certificate issuerCert : issuerCertificates) {
try {
// Find the certificate that actually signed this cert
if (certificate.isIssuer(issuerCert)) {
//Check if it's root certificate
if (issuerCert.getIssuer().equals(issuerCert.getSubject())) {
if (BouncyCastleUtils.x500NameCompare(issuerCert.getIssuer(),
issuerCert.getSubject())) {
return null;
}
return containsAllChain(issuerCert, certificateManager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@
</c:when>
<c:when test="${param.type=='endorsement'}">
<div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">TPM</span></div>
<div class="col-md-1 col-md-offset-1"><span class="colHeader">System Information</span></div>
<div id="subjectAltName" class="col col-md-8">
<div id="manufacturer">Manufacturer:&nbsp;<span>${initialData.manufacturer}</span></div>
<div id="model">Model:&nbsp;<span>${initialData.model}</span></div>
Expand Down Expand Up @@ -355,7 +355,7 @@
</div>
</div>
<div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">TPM</span></div>
<div class="col-md-1 col-md-offset-1"><span class="colHeader">System Information</span></div>
<div id="subjectAltName" class="col col-md-8">
<div id="manufacturer">Manufacturer:&nbsp;<span>${initialData.manufacturer}</span></div>
<div id="model">Model:&nbsp;<span>${initialData.model}</span></div>
Expand Down
53 changes: 53 additions & 0 deletions HIRS_Utils/src/main/java/hirs/utils/BouncyCastleUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package hirs.utils;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bouncycastle.asn1.x500.X500Name;

/**
* Utilities class specific for additional Bouncy Castle functionality.
*/
public final class BouncyCastleUtils {

private static final String SEPARATOR_COMMA = ",";
private static final String SEPARATOR_PLUS = "+";

private static final Logger LOGGER = LogManager.getLogger(BouncyCastleUtils.class);

/**
* Prevents construction of an instance of this class.
*/
private BouncyCastleUtils() {

}

/**
* This method can be used to compare the distinguished names given from
* certificates. This compare uses X500Name class in bouncy castle, which
* compares the RDNs and not the string itself. The method will check for
* '+' and replace them, X500Name doesn't do this.
*
* @param nameValue1 first general name to be used
* @param nameValue2 second general name to be used
* @return true if the values match based on the RDNs, false if not
*/
public static boolean x500NameCompare(final String nameValue1, final String nameValue2) {
if (nameValue1 == null || nameValue2 == null) {
throw new IllegalArgumentException("Provided DN string is null.");
}

boolean result = false;
X500Name x500Name1;
X500Name x500Name2;

try {
x500Name1 = new X500Name(nameValue1.replace(SEPARATOR_PLUS, SEPARATOR_COMMA));
x500Name2 = new X500Name(nameValue2.replace(SEPARATOR_PLUS, SEPARATOR_COMMA));
result = x500Name1.equals(x500Name2);
} catch (IllegalArgumentException iaEx) {
LOGGER.error(iaEx.toString());
}

return result;
}
}
1 change: 1 addition & 0 deletions HIRS_Utils/src/main/java/hirs/utils/Functional.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Simple utility class to house some functional methods.
*/
public final class Functional {

/**
* Prevents construction of an instance of this class.
*/
Expand Down
79 changes: 79 additions & 0 deletions HIRS_Utils/src/test/java/hirs/utils/BouncyCastleUtilsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package hirs.utils;

import org.apache.logging.log4j.util.Strings;
import org.testng.Assert;
import org.testng.annotations.Test;

/**
* Tests methods in the (@link BouncyCastleUtils) utility class.
*/
public class BouncyCastleUtilsTest {

private static final String VALID_RDN_STRING = "OU=PCTest,O=example.com,C=US";

private static final String VALID_RDN_STRING_SWITCHED = "C=US,OU=PCTest,O=example.com";
private static final String VALID_RDN_STRING_UPPERCASE = "OU=PCTEST,O=EXAMPLE.COM,C=US";
private static final String VALID_RDN_STRING_PLUS = "OU=PCTest+O=example.com+C=US";
private static final String UNEQUAL_RDN_STRING = "OU=PCTest,O=example1.com,C=US";
private static final String MALFORMED_RDN_STRING = "OU=PCTest,OZ=example1.com,C=US";

/**
* True Test of x500NameCompare method, of class BouncyCastleUtils.
*/
@Test
public void testX500NameCompareTrue() {
Assert.assertTrue(BouncyCastleUtils.x500NameCompare(
VALID_RDN_STRING, VALID_RDN_STRING_SWITCHED));
Assert.assertTrue(BouncyCastleUtils.x500NameCompare(
VALID_RDN_STRING, VALID_RDN_STRING_UPPERCASE));
Assert.assertTrue(BouncyCastleUtils.x500NameCompare(
VALID_RDN_STRING, VALID_RDN_STRING_PLUS));
}

/**
* False Test of x500NameCompare method, of class BouncyCastleUtils.
*/
@Test
public void testX500NameCompareFalse() {
Assert.assertFalse(BouncyCastleUtils.x500NameCompare(
VALID_RDN_STRING, UNEQUAL_RDN_STRING));
// Error that aren't thrown but logged
Assert.assertFalse(BouncyCastleUtils.x500NameCompare(VALID_RDN_STRING, Strings.EMPTY));
Assert.assertFalse(BouncyCastleUtils.x500NameCompare(Strings.EMPTY, VALID_RDN_STRING));
Assert.assertFalse(BouncyCastleUtils.x500NameCompare(Strings.EMPTY, Strings.EMPTY));
Assert.assertFalse(BouncyCastleUtils.x500NameCompare(
VALID_RDN_STRING, MALFORMED_RDN_STRING));
Assert.assertFalse(BouncyCastleUtils.x500NameCompare(
MALFORMED_RDN_STRING, VALID_RDN_STRING));
Assert.assertFalse(BouncyCastleUtils.x500NameCompare(
MALFORMED_RDN_STRING, MALFORMED_RDN_STRING));
}

/**
* Null String Error Test of x500NameCompare method, of class
* BouncyCastleUtils.
*/
@Test
public void testX500NameCompareNullError() {
try {
BouncyCastleUtils.x500NameCompare(VALID_RDN_STRING, null);
Assert.fail("No IllegalArgumentException thrown.");
} catch (Exception ex) {
Assert.assertEquals(ex.getMessage(), "Provided DN string is null.");
}

try {
BouncyCastleUtils.x500NameCompare(null, VALID_RDN_STRING);
Assert.fail("No IllegalArgumentException thrown.");
} catch (Exception ex) {
Assert.assertEquals(ex.getMessage(), "Provided DN string is null.");
}

try {
BouncyCastleUtils.x500NameCompare(null, null);
Assert.fail("No IllegalArgumentException thrown.");
} catch (Exception ex) {
Assert.assertEquals(ex.getMessage(), "Provided DN string is null.");
}
}
}