mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-30 01:39:05 +00:00
Merge branch 'master' into event-digest-update
This commit is contained in:
commit
5a82e48b61
@ -461,7 +461,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
|||||||
int algorithmLength = baseline[0].length();
|
int algorithmLength = baseline[0].length();
|
||||||
String[] storedPcrs = buildStoredPcrs(pcrContent, algorithmLength);
|
String[] storedPcrs = buildStoredPcrs(pcrContent, algorithmLength);
|
||||||
|
|
||||||
if (storedPcrs[0].isEmpty()) {
|
if (storedPcrs[0] == null || storedPcrs[0].isEmpty()) {
|
||||||
// validation fail
|
// validation fail
|
||||||
fwStatus = new AppraisalStatus(FAIL,
|
fwStatus = new AppraisalStatus(FAIL,
|
||||||
"Firmware validation failed: "
|
"Firmware validation failed: "
|
||||||
|
@ -35,15 +35,17 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller for the Validation Reports page.
|
* Controller for the Validation Reports page.
|
||||||
@ -59,7 +61,7 @@ public class ValidationReportsPageController extends PageController<NoPageParams
|
|||||||
private static String columnHeaders = "Verified Manufacturer,"
|
private static String columnHeaders = "Verified Manufacturer,"
|
||||||
+ "Model,SN,Verification Date,Device Status,"
|
+ "Model,SN,Verification Date,Device Status,"
|
||||||
+ "Component name,Component manufacturer,Component model,"
|
+ "Component name,Component manufacturer,Component model,"
|
||||||
+ "Component SN,Component status";
|
+ "Component SN,Issuer,Component status";
|
||||||
private static final String DEFAULT_COMPANY = "AllDevices";
|
private static final String DEFAULT_COMPANY = "AllDevices";
|
||||||
private static final String UNDEFINED = "undefined";
|
private static final String UNDEFINED = "undefined";
|
||||||
private static final Logger LOGGER = getLogger(ValidationReportsPageController.class);
|
private static final Logger LOGGER = getLogger(ValidationReportsPageController.class);
|
||||||
@ -138,6 +140,7 @@ public class ValidationReportsPageController extends PageController<NoPageParams
|
|||||||
* @param response object
|
* @param response object
|
||||||
* @throws IOException thrown by BufferedWriter object
|
* @throws IOException thrown by BufferedWriter object
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("checkstyle:magicnumber")
|
||||||
@RequestMapping(value = "download", method = RequestMethod.POST)
|
@RequestMapping(value = "download", method = RequestMethod.POST)
|
||||||
public void download(final HttpServletRequest request,
|
public void download(final HttpServletRequest request,
|
||||||
final HttpServletResponse response) throws IOException {
|
final HttpServletResponse response) throws IOException {
|
||||||
@ -190,7 +193,8 @@ public class ValidationReportsPageController extends PageController<NoPageParams
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "createTimes":
|
case "createTimes":
|
||||||
if (!parameterValue.equals(UNDEFINED)) {
|
if (!parameterValue.equals(UNDEFINED)
|
||||||
|
&& !parameterValue.isEmpty()) {
|
||||||
String[] timestamps = parameterValue.split(",");
|
String[] timestamps = parameterValue.split(",");
|
||||||
for (String timestamp : timestamps) {
|
for (String timestamp : timestamps) {
|
||||||
createTimes.add(LocalDateTime.parse(timestamp,
|
createTimes.add(LocalDateTime.parse(timestamp,
|
||||||
@ -199,7 +203,8 @@ public class ValidationReportsPageController extends PageController<NoPageParams
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "deviceNames":
|
case "deviceNames":
|
||||||
if (!parameterValue.equals(UNDEFINED)) {
|
if (!parameterValue.equals(UNDEFINED)
|
||||||
|
&& !parameterValue.isEmpty()) {
|
||||||
deviceNames = parameterValue.split(",");
|
deviceNames = parameterValue.split(",");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -211,7 +216,7 @@ public class ValidationReportsPageController extends PageController<NoPageParams
|
|||||||
response.setHeader("Content-Disposition",
|
response.setHeader("Content-Disposition",
|
||||||
"attachment;filename=validation_report.csv");
|
"attachment;filename=validation_report.csv");
|
||||||
BufferedWriter bufferedWriter = new BufferedWriter(
|
BufferedWriter bufferedWriter = new BufferedWriter(
|
||||||
new OutputStreamWriter(response.getOutputStream(), "UTF-8"));
|
new OutputStreamWriter(response.getOutputStream(), StandardCharsets.UTF_8));
|
||||||
StringBuilder reportData = new StringBuilder();
|
StringBuilder reportData = new StringBuilder();
|
||||||
bufferedWriter.append("Company: " + company + "\n");
|
bufferedWriter.append("Company: " + company + "\n");
|
||||||
bufferedWriter.append("Contract number: " + contractNumber + "\n");
|
bufferedWriter.append("Contract number: " + contractNumber + "\n");
|
||||||
@ -237,7 +242,9 @@ public class ValidationReportsPageController extends PageController<NoPageParams
|
|||||||
reportData.deleteCharAt(reportData.length() - 1);
|
reportData.deleteCharAt(reportData.length() - 1);
|
||||||
reportData.append("\n,,,,,");
|
reportData.append("\n,,,,,");
|
||||||
}
|
}
|
||||||
reportData.delete(reportData.lastIndexOf("\n"), reportData.length());
|
if (reportData.lastIndexOf(",") > 4) {
|
||||||
|
reportData.delete(reportData.lastIndexOf(",") - 4, reportData.length());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bufferedWriter.append(columnHeaders + "\n");
|
bufferedWriter.append(columnHeaders + "\n");
|
||||||
@ -259,13 +266,42 @@ public class ValidationReportsPageController extends PageController<NoPageParams
|
|||||||
*/
|
*/
|
||||||
private ArrayList<ArrayList<String>> parseComponents(final PlatformCredential pc) {
|
private ArrayList<ArrayList<String>> parseComponents(final PlatformCredential pc) {
|
||||||
ArrayList<ArrayList<String>> parsedComponents = new ArrayList<ArrayList<String>>();
|
ArrayList<ArrayList<String>> parsedComponents = new ArrayList<ArrayList<String>>();
|
||||||
|
ArrayList<ArrayList<Object>> chainComponents = new ArrayList<>();
|
||||||
|
|
||||||
|
StringBuilder componentFailureString = new StringBuilder();
|
||||||
if (pc.getComponentIdentifiers() != null
|
if (pc.getComponentIdentifiers() != null
|
||||||
&& pc.getComponentIdentifiers().size() > 0) {
|
&& pc.getComponentIdentifiers().size() > 0) {
|
||||||
LOGGER.info("Component failures: " + pc.getComponentFailures());
|
componentFailureString.append(pc.getComponentFailures());
|
||||||
ArrayList<String> componentFailures =
|
// get all the certificates associated with the platform serial
|
||||||
new ArrayList<String>(Arrays.asList(pc.getComponentFailures().split(";")));
|
List<PlatformCredential> chainCertificates = PlatformCredential
|
||||||
|
.select(certificateManager)
|
||||||
|
.byBoardSerialNumber(pc.getPlatformSerial())
|
||||||
|
.getCertificates().stream().collect(Collectors.toList());
|
||||||
|
// combine all components in each certificate
|
||||||
for (ComponentIdentifier ci : pc.getComponentIdentifiers()) {
|
for (ComponentIdentifier ci : pc.getComponentIdentifiers()) {
|
||||||
|
ArrayList<Object> issuerAndComponent = new ArrayList<Object>();
|
||||||
|
issuerAndComponent.add(pc.getIssuer());
|
||||||
|
issuerAndComponent.add(ci);
|
||||||
|
chainComponents.add(issuerAndComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PlatformCredential cert : chainCertificates) {
|
||||||
|
componentFailureString.append(cert.getComponentFailures());
|
||||||
|
if (!cert.isBase()) {
|
||||||
|
for (ComponentIdentifier ci : cert.getComponentIdentifiers()) {
|
||||||
|
ArrayList<Object> issuerAndComponent = new ArrayList<Object>();
|
||||||
|
issuerAndComponent.add(cert.getIssuer());
|
||||||
|
issuerAndComponent.add(ci);
|
||||||
|
chainComponents.add(issuerAndComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOGGER.info("Component failures: " + componentFailureString.toString());
|
||||||
|
for (ArrayList<Object> issuerAndComponent : chainComponents) {
|
||||||
ArrayList<String> componentData = new ArrayList<String>();
|
ArrayList<String> componentData = new ArrayList<String>();
|
||||||
|
String issuer = (String) issuerAndComponent.get(0);
|
||||||
|
issuer = issuer.replaceAll(",", " ");
|
||||||
|
ComponentIdentifier ci = (ComponentIdentifier) issuerAndComponent.get(1);
|
||||||
if (ci instanceof ComponentIdentifierV2) {
|
if (ci instanceof ComponentIdentifierV2) {
|
||||||
componentData.add(((ComponentIdentifierV2) ci).getComponentClass().toString());
|
componentData.add(((ComponentIdentifierV2) ci).getComponentClass().toString());
|
||||||
} else {
|
} else {
|
||||||
@ -274,8 +310,9 @@ public class ValidationReportsPageController extends PageController<NoPageParams
|
|||||||
componentData.add(ci.getComponentManufacturer().getString());
|
componentData.add(ci.getComponentManufacturer().getString());
|
||||||
componentData.add(ci.getComponentModel().getString());
|
componentData.add(ci.getComponentModel().getString());
|
||||||
componentData.add(ci.getComponentSerial().getString());
|
componentData.add(ci.getComponentSerial().getString());
|
||||||
//Failing components are identified by manufacturer + model
|
componentData.add(issuer);
|
||||||
if (componentFailures.contains(componentData.get(1) + componentData.get(2))) {
|
//Failing components are identified by hashcode
|
||||||
|
if (componentFailureString.toString().contains(String.valueOf(ci.hashCode()))) {
|
||||||
componentData.add("Fail");
|
componentData.add("Fail");
|
||||||
} else {
|
} else {
|
||||||
componentData.add("Pass");
|
componentData.add("Pass");
|
||||||
|
@ -53,10 +53,10 @@ public final class CertificateStringMapBuilder {
|
|||||||
if (certificate != null) {
|
if (certificate != null) {
|
||||||
data.put("issuer", certificate.getIssuer());
|
data.put("issuer", certificate.getIssuer());
|
||||||
//Serial number in hex value
|
//Serial number in hex value
|
||||||
data.put("serialNumber", Long.toHexString(certificate.getSerialNumber().longValue()));
|
data.put("serialNumber", Hex.toHexString(certificate.getSerialNumber().toByteArray()));
|
||||||
if (!certificate.getAuthoritySerialNumber().equals(BigInteger.ZERO)) {
|
if (!certificate.getAuthoritySerialNumber().equals(BigInteger.ZERO)) {
|
||||||
data.put("authSerialNumber", Long.toHexString(certificate
|
data.put("authSerialNumber", Hex.toHexString(certificate
|
||||||
.getAuthoritySerialNumber().longValue()));
|
.getAuthoritySerialNumber().toByteArray()));
|
||||||
}
|
}
|
||||||
if (certificate.getId() != null) {
|
if (certificate.getId() != null) {
|
||||||
data.put("certificateId", certificate.getId().toString());
|
data.put("certificateId", certificate.getId().toString());
|
||||||
@ -103,20 +103,30 @@ public final class CertificateStringMapBuilder {
|
|||||||
if (data.get("isSelfSigned").equals("false")) {
|
if (data.get("isSelfSigned").equals("false")) {
|
||||||
//Get the missing certificate chain for not self sign
|
//Get the missing certificate chain for not self sign
|
||||||
Certificate missingCert = containsAllChain(certificate, certificateManager);
|
Certificate missingCert = containsAllChain(certificate, certificateManager);
|
||||||
|
String issuerResult;
|
||||||
|
|
||||||
if (missingCert != null) {
|
if (missingCert != null) {
|
||||||
data.put("missingChainIssuer", missingCert.getIssuer());
|
data.put("missingChainIssuer", String.format("Missing %s from the chain.",
|
||||||
|
missingCert.getIssuer()));
|
||||||
}
|
}
|
||||||
//Find all certificates that could be the issuer certificate based on subject name
|
//Find all certificates that could be the issuer certificate based on subject name
|
||||||
for (Certificate issuerCert : CertificateAuthorityCredential
|
for (Certificate issuerCert : CertificateAuthorityCredential
|
||||||
.select(certificateManager)
|
.select(certificateManager)
|
||||||
.bySubject(certificate.getIssuer())
|
.bySubjectSorted(certificate.getIssuerSorted())
|
||||||
.getCertificates()) {
|
.getCertificates()) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//Find the certificate that actually signed this cert
|
//Find the certificate that actually signed this cert
|
||||||
if (certificate.isIssuer(issuerCert)) {
|
issuerResult = certificate.isIssuer(issuerCert);
|
||||||
|
if (issuerResult.isEmpty()) {
|
||||||
data.put("issuerID", issuerCert.getId().toString());
|
data.put("issuerID", issuerCert.getId().toString());
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
data.put("issuerID", issuerCert.getId().toString());
|
||||||
|
issuerResult = String.format("%s: %s", issuerResult,
|
||||||
|
issuerCert.getSubject());
|
||||||
|
data.put("missingChainIssuer", issuerResult);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOGGER.error(e);
|
LOGGER.error(e);
|
||||||
@ -139,6 +149,7 @@ public final class CertificateStringMapBuilder {
|
|||||||
final CertificateManager certificateManager) {
|
final CertificateManager certificateManager) {
|
||||||
Set<CertificateAuthorityCredential> issuerCertificates = new HashSet<>();
|
Set<CertificateAuthorityCredential> issuerCertificates = new HashSet<>();
|
||||||
CertificateAuthorityCredential skiCA = null;
|
CertificateAuthorityCredential skiCA = null;
|
||||||
|
String issuerResult;
|
||||||
//Check if there is a subject organization
|
//Check if there is a subject organization
|
||||||
if (certificate.getAuthKeyId() != null
|
if (certificate.getAuthKeyId() != null
|
||||||
&& !certificate.getAuthKeyId().isEmpty()) {
|
&& !certificate.getAuthKeyId().isEmpty()) {
|
||||||
@ -147,7 +158,7 @@ public final class CertificateStringMapBuilder {
|
|||||||
.select(certificateManager)
|
.select(certificateManager)
|
||||||
.bySubjectKeyIdentifier(bytes).getCertificate();
|
.bySubjectKeyIdentifier(bytes).getCertificate();
|
||||||
} else {
|
} else {
|
||||||
LOGGER.info(String.format("Certificate (%s) for %s has no authority key identifier.",
|
LOGGER.error(String.format("Certificate (%s) for %s has no authority key identifier.",
|
||||||
certificate.getClass().toString(), certificate.getSubject()));
|
certificate.getClass().toString(), certificate.getSubject()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +182,8 @@ public final class CertificateStringMapBuilder {
|
|||||||
for (Certificate issuerCert : issuerCertificates) {
|
for (Certificate issuerCert : issuerCertificates) {
|
||||||
try {
|
try {
|
||||||
// Find the certificate that actually signed this cert
|
// Find the certificate that actually signed this cert
|
||||||
if (certificate.isIssuer(issuerCert)) {
|
issuerResult = certificate.isIssuer(issuerCert);
|
||||||
|
if (issuerResult.isEmpty()) {
|
||||||
//Check if it's root certificate
|
//Check if it's root certificate
|
||||||
if (BouncyCastleUtils.x500NameCompare(issuerCert.getIssuer(),
|
if (BouncyCastleUtils.x500NameCompare(issuerCert.getIssuer(),
|
||||||
issuerCert.getSubject())) {
|
issuerCert.getSubject())) {
|
||||||
|
@ -88,7 +88,7 @@
|
|||||||
</c:when>
|
</c:when>
|
||||||
<c:otherwise>
|
<c:otherwise>
|
||||||
<img src="${icons}/ic_error_red_24dp.png"
|
<img src="${icons}/ic_error_red_24dp.png"
|
||||||
title="Missing ${initialData.missingChainIssuer} from the chain.">
|
title="${initialData.missingChainIssuer}">
|
||||||
</c:otherwise>
|
</c:otherwise>
|
||||||
</c:choose>
|
</c:choose>
|
||||||
</span>
|
</span>
|
||||||
|
@ -8,31 +8,34 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.bouncycastle.asn1.ASN1BitString;
|
import org.bouncycastle.asn1.ASN1BitString;
|
||||||
import org.bouncycastle.asn1.ASN1Encodable;
|
import org.bouncycastle.asn1.ASN1Encodable;
|
||||||
|
import org.bouncycastle.asn1.ASN1GeneralizedTime;
|
||||||
|
import org.bouncycastle.asn1.ASN1InputStream;
|
||||||
import org.bouncycastle.asn1.ASN1Integer;
|
import org.bouncycastle.asn1.ASN1Integer;
|
||||||
|
import org.bouncycastle.asn1.ASN1Object;
|
||||||
import org.bouncycastle.asn1.ASN1Primitive;
|
import org.bouncycastle.asn1.ASN1Primitive;
|
||||||
import org.bouncycastle.asn1.ASN1Sequence;
|
import org.bouncycastle.asn1.ASN1Sequence;
|
||||||
import org.bouncycastle.asn1.x500.X500Name;
|
|
||||||
import org.bouncycastle.asn1.x509.AttributeCertificate;
|
|
||||||
import org.bouncycastle.asn1.x509.AttributeCertificateInfo;
|
|
||||||
import org.bouncycastle.asn1.x509.AttCertIssuer;
|
|
||||||
import org.bouncycastle.asn1.x509.Extensions;
|
|
||||||
import org.bouncycastle.asn1.x509.V2Form;
|
|
||||||
import org.bouncycastle.asn1.x509.GeneralNames;
|
|
||||||
import org.bouncycastle.cert.X509AttributeCertificateHolder;
|
|
||||||
import org.bouncycastle.cert.X509CertificateHolder;
|
|
||||||
import org.bouncycastle.asn1.x509.GeneralName;
|
|
||||||
import org.bouncycastle.util.encoders.Base64;
|
|
||||||
import org.bouncycastle.asn1.ASN1GeneralizedTime;
|
|
||||||
import org.bouncycastle.asn1.ASN1Object;
|
|
||||||
import org.bouncycastle.asn1.DERTaggedObject;
|
|
||||||
import org.bouncycastle.asn1.ASN1InputStream;
|
|
||||||
import org.bouncycastle.asn1.DERIA5String;
|
import org.bouncycastle.asn1.DERIA5String;
|
||||||
import org.bouncycastle.asn1.DEROctetString;
|
import org.bouncycastle.asn1.DEROctetString;
|
||||||
|
import org.bouncycastle.asn1.DERTaggedObject;
|
||||||
import org.bouncycastle.asn1.DLSequence;
|
import org.bouncycastle.asn1.DLSequence;
|
||||||
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
|
import org.bouncycastle.asn1.x500.X500Name;
|
||||||
import org.bouncycastle.asn1.x509.AccessDescription;
|
import org.bouncycastle.asn1.x509.AccessDescription;
|
||||||
|
import org.bouncycastle.asn1.x509.AttCertIssuer;
|
||||||
|
import org.bouncycastle.asn1.x509.AttributeCertificate;
|
||||||
|
import org.bouncycastle.asn1.x509.AttributeCertificateInfo;
|
||||||
import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
|
import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
|
||||||
|
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
|
||||||
|
import org.bouncycastle.asn1.x509.CRLDistPoint;
|
||||||
|
import org.bouncycastle.asn1.x509.DistributionPoint;
|
||||||
|
import org.bouncycastle.asn1.x509.DistributionPointName;
|
||||||
import org.bouncycastle.asn1.x509.Extension;
|
import org.bouncycastle.asn1.x509.Extension;
|
||||||
|
import org.bouncycastle.asn1.x509.Extensions;
|
||||||
|
import org.bouncycastle.asn1.x509.GeneralName;
|
||||||
|
import org.bouncycastle.asn1.x509.GeneralNames;
|
||||||
|
import org.bouncycastle.asn1.x509.V2Form;
|
||||||
|
import org.bouncycastle.cert.X509AttributeCertificateHolder;
|
||||||
|
import org.bouncycastle.cert.X509CertificateHolder;
|
||||||
|
import org.bouncycastle.util.encoders.Base64;
|
||||||
import org.bouncycastle.x509.extension.X509ExtensionUtil;
|
import org.bouncycastle.x509.extension.X509ExtensionUtil;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
@ -64,9 +67,6 @@ import java.util.Date;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import org.bouncycastle.asn1.x509.CRLDistPoint;
|
|
||||||
import org.bouncycastle.asn1.x509.DistributionPoint;
|
|
||||||
import org.bouncycastle.asn1.x509.DistributionPointName;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -753,8 +753,8 @@ public abstract class Certificate extends ArchivableEntity {
|
|||||||
* @return whether or not the other certificate is the issuer for this certificate
|
* @return whether or not the other certificate is the issuer for this certificate
|
||||||
* @throws IOException if there is an issue deserializing either certificate
|
* @throws IOException if there is an issue deserializing either certificate
|
||||||
*/
|
*/
|
||||||
public boolean isIssuer(final Certificate issuer) throws IOException {
|
public String isIssuer(final Certificate issuer) throws IOException {
|
||||||
boolean isIssuer = false;
|
String isIssuer = "Certificate signature failed to verify";
|
||||||
// only run if of the correct type, otherwise false
|
// only run if of the correct type, otherwise false
|
||||||
if (issuer.getCertificateType() == CertificateType.X509_CERTIFICATE) {
|
if (issuer.getCertificateType() == CertificateType.X509_CERTIFICATE) {
|
||||||
X509Certificate issuerX509 = issuer.getX509Certificate();
|
X509Certificate issuerX509 = issuer.getX509Certificate();
|
||||||
@ -764,7 +764,7 @@ public abstract class Certificate extends ArchivableEntity {
|
|||||||
X509Certificate certX509 = getX509Certificate();
|
X509Certificate certX509 = getX509Certificate();
|
||||||
try {
|
try {
|
||||||
certX509.verify(issuerX509.getPublicKey());
|
certX509.verify(issuerX509.getPublicKey());
|
||||||
isIssuer = true;
|
isIssuer = "";
|
||||||
} catch (CertificateException | NoSuchAlgorithmException | InvalidKeyException
|
} catch (CertificateException | NoSuchAlgorithmException | InvalidKeyException
|
||||||
| NoSuchProviderException | SignatureException e) {
|
| NoSuchProviderException | SignatureException e) {
|
||||||
LOGGER.error(e);
|
LOGGER.error(e);
|
||||||
@ -777,7 +777,9 @@ public abstract class Certificate extends ArchivableEntity {
|
|||||||
Signature sig = Signature.getInstance(algorithm);
|
Signature sig = Signature.getInstance(algorithm);
|
||||||
sig.initVerify(issuerX509.getPublicKey());
|
sig.initVerify(issuerX509.getPublicKey());
|
||||||
sig.update(attCert.getAcinfo().getEncoded());
|
sig.update(attCert.getAcinfo().getEncoded());
|
||||||
isIssuer = sig.verify(attCert.getSignatureValue().getBytes());
|
if (sig.verify(attCert.getSignatureValue().getBytes())) {
|
||||||
|
isIssuer = "";
|
||||||
|
}
|
||||||
} catch (NoSuchAlgorithmException
|
} catch (NoSuchAlgorithmException
|
||||||
| InvalidKeyException
|
| InvalidKeyException
|
||||||
| SignatureException e) {
|
| SignatureException e) {
|
||||||
|
@ -4,22 +4,11 @@ import com.google.common.base.Preconditions;
|
|||||||
import hirs.data.persist.certificate.attributes.ComponentIdentifier;
|
import hirs.data.persist.certificate.attributes.ComponentIdentifier;
|
||||||
import hirs.data.persist.certificate.attributes.PlatformConfiguration;
|
import hirs.data.persist.certificate.attributes.PlatformConfiguration;
|
||||||
import hirs.data.persist.certificate.attributes.PlatformConfigurationV1;
|
import hirs.data.persist.certificate.attributes.PlatformConfigurationV1;
|
||||||
import hirs.data.persist.certificate.attributes.V2.PlatformConfigurationV2;
|
|
||||||
import hirs.data.persist.certificate.attributes.TBBSecurityAssertion;
|
import hirs.data.persist.certificate.attributes.TBBSecurityAssertion;
|
||||||
import hirs.data.persist.certificate.attributes.URIReference;
|
import hirs.data.persist.certificate.attributes.URIReference;
|
||||||
|
import hirs.data.persist.certificate.attributes.V2.PlatformConfigurationV2;
|
||||||
import hirs.persist.CertificateManager;
|
import hirs.persist.CertificateManager;
|
||||||
import hirs.persist.CertificateSelector;
|
import hirs.persist.CertificateSelector;
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.Transient;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@ -37,15 +26,26 @@ import org.bouncycastle.asn1.x509.Attribute;
|
|||||||
import org.bouncycastle.asn1.x509.AttributeCertificate;
|
import org.bouncycastle.asn1.x509.AttributeCertificate;
|
||||||
import org.bouncycastle.asn1.x509.AttributeCertificateInfo;
|
import org.bouncycastle.asn1.x509.AttributeCertificateInfo;
|
||||||
import org.bouncycastle.asn1.x509.CertificatePolicies;
|
import org.bouncycastle.asn1.x509.CertificatePolicies;
|
||||||
import org.bouncycastle.asn1.x509.PolicyInformation;
|
|
||||||
import org.bouncycastle.asn1.x509.PolicyQualifierInfo;
|
|
||||||
import org.bouncycastle.asn1.x509.Extension;
|
import org.bouncycastle.asn1.x509.Extension;
|
||||||
import org.bouncycastle.asn1.x509.GeneralName;
|
import org.bouncycastle.asn1.x509.GeneralName;
|
||||||
import org.bouncycastle.asn1.x509.GeneralNames;
|
import org.bouncycastle.asn1.x509.GeneralNames;
|
||||||
|
import org.bouncycastle.asn1.x509.PolicyInformation;
|
||||||
|
import org.bouncycastle.asn1.x509.PolicyQualifierInfo;
|
||||||
import org.bouncycastle.asn1.x509.UserNotice;
|
import org.bouncycastle.asn1.x509.UserNotice;
|
||||||
import org.bouncycastle.operator.ContentVerifier;
|
import org.bouncycastle.operator.ContentVerifier;
|
||||||
import org.bouncycastle.operator.ContentVerifierProvider;
|
import org.bouncycastle.operator.ContentVerifierProvider;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Transient;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class persists Platform credentials by extending the base Certificate
|
* This class persists Platform credentials by extending the base Certificate
|
||||||
* class with fields unique to a Platform credentials, as defined in the Trusted
|
* class with fields unique to a Platform credentials, as defined in the Trusted
|
||||||
@ -89,8 +89,21 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
|
|||||||
* At this time these are placeholder values.
|
* At this time these are placeholder values.
|
||||||
*/
|
*/
|
||||||
private static final Map<String, String> TCG_PLATFORM_MAP = new HashMap<String, String>() {{
|
private static final Map<String, String> TCG_PLATFORM_MAP = new HashMap<String, String>() {{
|
||||||
put("#00000000", "Client");
|
put("#00000000", "Unclassified");
|
||||||
put("#00000001", "Server");
|
put("#00000001", "PC Client");
|
||||||
|
put("#00000002", "PDA");
|
||||||
|
put("#00000003", "CELLPHONE");
|
||||||
|
put("#00000004", "SERVER");
|
||||||
|
put("#00000005", "PERIPHERAL");
|
||||||
|
put("#00000006", "TSS");
|
||||||
|
put("#00000007", "STORAGE");
|
||||||
|
put("#00000008", "AUTHENTICATION");
|
||||||
|
put("#00000009", "EMBEDDED");
|
||||||
|
put("#00000010", "HARD COPY");
|
||||||
|
put("#00000011", "INFRASTRUCTURE");
|
||||||
|
put("#00000012", "VIRTUALIZATION");
|
||||||
|
put("#00000013", "TNC");
|
||||||
|
put("#00000014", "MULTI-TENANT");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// number of extra bytes potentially present in a cert header.
|
// number of extra bytes potentially present in a cert header.
|
||||||
|
@ -4,17 +4,21 @@ import com.fasterxml.jackson.core.JsonFactory;
|
|||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import hirs.data.persist.AppraisalStatus;
|
import hirs.data.persist.AppraisalStatus;
|
||||||
import hirs.data.persist.info.ComponentInfo;
|
import hirs.data.persist.ArchivableEntity;
|
||||||
import hirs.data.persist.DeviceInfoReport;
|
import hirs.data.persist.DeviceInfoReport;
|
||||||
import hirs.data.persist.info.HardwareInfo;
|
import hirs.data.persist.SupplyChainValidation;
|
||||||
import hirs.data.persist.certificate.EndorsementCredential;
|
import hirs.data.persist.certificate.EndorsementCredential;
|
||||||
import hirs.data.persist.certificate.PlatformCredential;
|
import hirs.data.persist.certificate.PlatformCredential;
|
||||||
import hirs.data.persist.certificate.attributes.ComponentIdentifier;
|
import hirs.data.persist.certificate.attributes.ComponentIdentifier;
|
||||||
|
import hirs.data.persist.certificate.attributes.V2.ComponentIdentifierV2;
|
||||||
|
import hirs.data.persist.info.ComponentInfo;
|
||||||
|
import hirs.data.persist.info.HardwareInfo;
|
||||||
import org.apache.commons.codec.Charsets;
|
import org.apache.commons.codec.Charsets;
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.logging.log4j.util.Strings;
|
||||||
import org.bouncycastle.asn1.DERUTF8String;
|
import org.bouncycastle.asn1.DERUTF8String;
|
||||||
import org.bouncycastle.asn1.x500.X500Name;
|
import org.bouncycastle.asn1.x500.X500Name;
|
||||||
import org.bouncycastle.cert.CertException;
|
import org.bouncycastle.cert.CertException;
|
||||||
@ -41,11 +45,14 @@ import java.security.cert.CertificateExpiredException;
|
|||||||
import java.security.cert.CertificateNotYetValidException;
|
import java.security.cert.CertificateNotYetValidException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -55,13 +62,6 @@ import java.util.stream.Collectors;
|
|||||||
import static hirs.data.persist.AppraisalStatus.Status.ERROR;
|
import static hirs.data.persist.AppraisalStatus.Status.ERROR;
|
||||||
import static hirs.data.persist.AppraisalStatus.Status.FAIL;
|
import static hirs.data.persist.AppraisalStatus.Status.FAIL;
|
||||||
import static hirs.data.persist.AppraisalStatus.Status.PASS;
|
import static hirs.data.persist.AppraisalStatus.Status.PASS;
|
||||||
import hirs.data.persist.ArchivableEntity;
|
|
||||||
import hirs.data.persist.SupplyChainValidation;
|
|
||||||
import hirs.data.persist.certificate.attributes.V2.ComponentIdentifierV2;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import org.apache.logging.log4j.util.Strings;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -196,6 +196,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
final boolean acceptExpired) {
|
final boolean acceptExpired) {
|
||||||
final String baseErrorMessage = "Can't validate platform credential without ";
|
final String baseErrorMessage = "Can't validate platform credential without ";
|
||||||
String message;
|
String message;
|
||||||
|
String certVerifyMsg;
|
||||||
if (pc == null) {
|
if (pc == null) {
|
||||||
message = baseErrorMessage + "a platform credential\n";
|
message = baseErrorMessage + "a platform credential\n";
|
||||||
LOGGER.error(message);
|
LOGGER.error(message);
|
||||||
@ -233,19 +234,21 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
|
|
||||||
// verify cert against truststore
|
// verify cert against truststore
|
||||||
try {
|
try {
|
||||||
if (verifyCertificate(attributeCert, trustStore)) {
|
certVerifyMsg = verifyCertificate(attributeCert, trustStore);
|
||||||
|
if (certVerifyMsg.isEmpty()) {
|
||||||
message = PLATFORM_VALID;
|
message = PLATFORM_VALID;
|
||||||
LOGGER.info(message);
|
LOGGER.info(message);
|
||||||
return new AppraisalStatus(PASS, message);
|
return new AppraisalStatus(PASS, message);
|
||||||
} else {
|
} else {
|
||||||
message = "Platform credential failed verification";
|
message = String.format("Platform credential failed verification%n%s",
|
||||||
|
certVerifyMsg);
|
||||||
LOGGER.error(message);
|
LOGGER.error(message);
|
||||||
return new AppraisalStatus(FAIL, message);
|
return new AppraisalStatus(FAIL, message);
|
||||||
}
|
}
|
||||||
} catch (SupplyChainValidatorException e) {
|
} catch (SupplyChainValidatorException scvEx) {
|
||||||
message = "An error occurred indicating the credential is not valid";
|
message = "An error occurred indicating the credential is not valid";
|
||||||
LOGGER.warn(message, e);
|
LOGGER.warn(message, scvEx);
|
||||||
return new AppraisalStatus(FAIL, message + " " + e.getMessage());
|
return new AppraisalStatus(FAIL, message + " " + scvEx.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1244,14 +1247,14 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
* @throws SupplyChainValidatorException
|
* @throws SupplyChainValidatorException
|
||||||
* if the verification is not successful
|
* if the verification is not successful
|
||||||
*/
|
*/
|
||||||
public static boolean verifyCertificate(final X509AttributeCertificateHolder cert,
|
public static String verifyCertificate(final X509AttributeCertificateHolder cert,
|
||||||
final KeyStore trustStore) throws SupplyChainValidatorException {
|
final KeyStore trustStore) throws SupplyChainValidatorException {
|
||||||
if (cert == null || trustStore == null) {
|
if (cert == null || trustStore == null) {
|
||||||
throw new SupplyChainValidatorException("Certificate or trust store is null");
|
throw new SupplyChainValidatorException("Certificate or trust store is null");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Set<X509Certificate> trustedCerts = new HashSet<X509Certificate>();
|
Set<X509Certificate> trustedCerts = new HashSet<>();
|
||||||
|
|
||||||
Enumeration<String> alias = trustStore.aliases();
|
Enumeration<String> alias = trustStore.aliases();
|
||||||
|
|
||||||
@ -1259,15 +1262,14 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
trustedCerts.add((X509Certificate) trustStore.getCertificate(alias.nextElement()));
|
trustedCerts.add((X509Certificate) trustStore.getCertificate(alias.nextElement()));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean certChainValidated = validateCertChain(cert, trustedCerts);
|
String certChainValidated = validateCertChain(cert, trustedCerts);
|
||||||
if (!certChainValidated) {
|
if (!certChainValidated.isEmpty()) {
|
||||||
LOGGER.error("Cert chain could not be validated");
|
LOGGER.error("Cert chain could not be validated");
|
||||||
}
|
}
|
||||||
return certChainValidated;
|
return certChainValidated;
|
||||||
} catch (KeyStoreException e) {
|
} catch (KeyStoreException e) {
|
||||||
throw new SupplyChainValidatorException("Error with the trust store", e);
|
throw new SupplyChainValidatorException("Error with the trust store", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1291,7 +1293,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
throw new SupplyChainValidatorException("Certificate or trust store is null");
|
throw new SupplyChainValidatorException("Certificate or trust store is null");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Set<X509Certificate> trustedCerts = new HashSet<X509Certificate>();
|
Set<X509Certificate> trustedCerts = new HashSet<>();
|
||||||
|
|
||||||
Enumeration<String> alias = trustStore.aliases();
|
Enumeration<String> alias = trustStore.aliases();
|
||||||
|
|
||||||
@ -1299,7 +1301,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
trustedCerts.add((X509Certificate) trustStore.getCertificate(alias.nextElement()));
|
trustedCerts.add((X509Certificate) trustStore.getCertificate(alias.nextElement()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return validateCertChain(cert, trustedCerts);
|
return validateCertChain(cert, trustedCerts).isEmpty();
|
||||||
} catch (KeyStoreException e) {
|
} catch (KeyStoreException e) {
|
||||||
LOGGER.error("Error accessing keystore", e);
|
LOGGER.error("Error accessing keystore", e);
|
||||||
throw new SupplyChainValidatorException("Error with the trust store", e);
|
throw new SupplyChainValidatorException("Error with the trust store", e);
|
||||||
@ -1321,31 +1323,40 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
* @return boolean indicating if the validation was successful
|
* @return boolean indicating if the validation was successful
|
||||||
* @throws SupplyChainValidatorException tried to validate using null certificates
|
* @throws SupplyChainValidatorException tried to validate using null certificates
|
||||||
*/
|
*/
|
||||||
public static boolean validateCertChain(final X509AttributeCertificateHolder cert,
|
public static String validateCertChain(final X509AttributeCertificateHolder cert,
|
||||||
final Set<X509Certificate> additionalCerts) throws SupplyChainValidatorException {
|
final Set<X509Certificate> additionalCerts) throws SupplyChainValidatorException {
|
||||||
if (cert == null || additionalCerts == null) {
|
if (cert == null || additionalCerts == null) {
|
||||||
throw new SupplyChainValidatorException(
|
throw new SupplyChainValidatorException(
|
||||||
"Certificate or validation certificates are null");
|
"Certificate or validation certificates are null");
|
||||||
}
|
}
|
||||||
boolean foundRootOfCertChain = false;
|
String foundRootOfCertChain = "";
|
||||||
Iterator<X509Certificate> certIterator = additionalCerts.iterator();
|
Iterator<X509Certificate> certIterator = additionalCerts.iterator();
|
||||||
X509Certificate trustedCert;
|
X509Certificate trustedCert;
|
||||||
|
boolean issuerMatchesSubject = false;
|
||||||
|
boolean signatureMatchesPublicKey = false;
|
||||||
|
|
||||||
while (!foundRootOfCertChain && certIterator.hasNext()) {
|
while (foundRootOfCertChain.isEmpty() && certIterator.hasNext()) {
|
||||||
trustedCert = certIterator.next();
|
trustedCert = certIterator.next();
|
||||||
if (issuerMatchesSubjectDN(cert, trustedCert)
|
issuerMatchesSubject = issuerMatchesSubjectDN(cert, trustedCert);
|
||||||
&& signatureMatchesPublicKey(cert, trustedCert)) {
|
signatureMatchesPublicKey = signatureMatchesPublicKey(cert, trustedCert);
|
||||||
|
if (issuerMatchesSubject && signatureMatchesPublicKey) {
|
||||||
if (isSelfSigned(trustedCert)) {
|
if (isSelfSigned(trustedCert)) {
|
||||||
LOGGER.info("CA Root found.");
|
LOGGER.info("CA Root found.");
|
||||||
foundRootOfCertChain = true;
|
|
||||||
} else {
|
} else {
|
||||||
foundRootOfCertChain = validateCertChain(trustedCert, additionalCerts);
|
foundRootOfCertChain = validateCertChain(trustedCert, additionalCerts);
|
||||||
|
|
||||||
if (!foundRootOfCertChain) {
|
if (!foundRootOfCertChain.isEmpty()) {
|
||||||
LOGGER.error("Root of certificate chain not found. Check for CA Cert: "
|
LOGGER.error("Root of certificate chain not found. Check for CA Cert: "
|
||||||
+ cert.getIssuer().getNames()[0]);
|
+ cert.getIssuer().getNames()[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (!issuerMatchesSubject) {
|
||||||
|
foundRootOfCertChain = "Issuer DN does not match Subject DN";
|
||||||
|
}
|
||||||
|
if (!signatureMatchesPublicKey) {
|
||||||
|
foundRootOfCertChain = "Certificate signature failed to verify";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1366,31 +1377,40 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
* @return boolean indicating if the validation was successful
|
* @return boolean indicating if the validation was successful
|
||||||
* @throws SupplyChainValidatorException tried to validate using null certificates
|
* @throws SupplyChainValidatorException tried to validate using null certificates
|
||||||
*/
|
*/
|
||||||
public static boolean validateCertChain(final X509Certificate cert,
|
public static String validateCertChain(final X509Certificate cert,
|
||||||
final Set<X509Certificate> additionalCerts) throws SupplyChainValidatorException {
|
final Set<X509Certificate> additionalCerts) throws SupplyChainValidatorException {
|
||||||
if (cert == null || additionalCerts == null) {
|
if (cert == null || additionalCerts == null) {
|
||||||
throw new SupplyChainValidatorException(
|
throw new SupplyChainValidatorException(
|
||||||
"Certificate or validation certificates are null");
|
"Certificate or validation certificates are null");
|
||||||
}
|
}
|
||||||
boolean foundRootOfCertChain = false;
|
String foundRootOfCertChain = "";
|
||||||
Iterator<X509Certificate> certIterator = additionalCerts.iterator();
|
Iterator<X509Certificate> certIterator = additionalCerts.iterator();
|
||||||
X509Certificate trustedCert;
|
X509Certificate trustedCert;
|
||||||
|
boolean issuerMatchesSubject = false;
|
||||||
|
boolean signatureMatchesPublicKey = false;
|
||||||
|
|
||||||
while (!foundRootOfCertChain && certIterator.hasNext()) {
|
while (foundRootOfCertChain.isEmpty() && certIterator.hasNext()) {
|
||||||
trustedCert = certIterator.next();
|
trustedCert = certIterator.next();
|
||||||
if (issuerMatchesSubjectDN(cert, trustedCert)
|
issuerMatchesSubject = issuerMatchesSubjectDN(cert, trustedCert);
|
||||||
&& signatureMatchesPublicKey(cert, trustedCert)) {
|
signatureMatchesPublicKey = signatureMatchesPublicKey(cert, trustedCert);
|
||||||
|
if (issuerMatchesSubject && signatureMatchesPublicKey) {
|
||||||
if (isSelfSigned(trustedCert)) {
|
if (isSelfSigned(trustedCert)) {
|
||||||
LOGGER.info("CA Root found.");
|
LOGGER.info("CA Root found.");
|
||||||
foundRootOfCertChain = true;
|
|
||||||
} else if (!cert.equals(trustedCert)) {
|
} else if (!cert.equals(trustedCert)) {
|
||||||
foundRootOfCertChain = validateCertChain(trustedCert, additionalCerts);
|
foundRootOfCertChain = validateCertChain(trustedCert, additionalCerts);
|
||||||
|
|
||||||
if (!foundRootOfCertChain) {
|
if (!foundRootOfCertChain.isEmpty()) {
|
||||||
LOGGER.error("Root of certificate chain not found. Check for CA Cert: "
|
LOGGER.error("Root of certificate chain not found. Check for CA Cert: "
|
||||||
+ cert.getIssuerDN().getName());
|
+ cert.getIssuerDN().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (!issuerMatchesSubject) {
|
||||||
|
foundRootOfCertChain = "Issuer DN does not match Subject DN";
|
||||||
|
}
|
||||||
|
if (!signatureMatchesPublicKey) {
|
||||||
|
foundRootOfCertChain = "Certificate signature failed to verify";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1611,8 +1631,8 @@ public final class SupplyChainCredentialValidator implements CredentialValidator
|
|||||||
*/
|
*/
|
||||||
public static boolean signatureMatchesPublicKey(final X509AttributeCertificateHolder cert,
|
public static boolean signatureMatchesPublicKey(final X509AttributeCertificateHolder cert,
|
||||||
final X509Certificate signingCert) throws SupplyChainValidatorException {
|
final X509Certificate signingCert) throws SupplyChainValidatorException {
|
||||||
if (cert == null || signingCert == null) {
|
if (signingCert == null) {
|
||||||
throw new SupplyChainValidatorException("Certificate or signing certificate is null");
|
throw new SupplyChainValidatorException("Signing certificate is null");
|
||||||
}
|
}
|
||||||
return signatureMatchesPublicKey(cert, signingCert.getPublicKey());
|
return signatureMatchesPublicKey(cert, signingCert.getPublicKey());
|
||||||
}
|
}
|
||||||
|
@ -441,8 +441,8 @@ public class CertificateTest {
|
|||||||
Certificate issuerCert = getTestCertificate(FAKE_ROOT_CA_FILE);
|
Certificate issuerCert = getTestCertificate(FAKE_ROOT_CA_FILE);
|
||||||
Certificate cert = getTestCertificate(INT_CA_CERT02);
|
Certificate cert = getTestCertificate(INT_CA_CERT02);
|
||||||
|
|
||||||
Assert.assertFalse(issuerCert.isIssuer(cert));
|
Assert.assertFalse(!issuerCert.isIssuer(cert).isEmpty());
|
||||||
Assert.assertTrue(cert.isIssuer(issuerCert));
|
Assert.assertTrue(cert.isIssuer(issuerCert).isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,6 +7,7 @@ import hirs.data.persist.certificate.attributes.TBBSecurityAssertion;
|
|||||||
import hirs.data.persist.certificate.attributes.URIReference;
|
import hirs.data.persist.certificate.attributes.URIReference;
|
||||||
import hirs.data.persist.certificate.attributes.V2.PlatformConfigurationV2;
|
import hirs.data.persist.certificate.attributes.V2.PlatformConfigurationV2;
|
||||||
import org.apache.commons.codec.binary.Hex;
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
import org.bouncycastle.util.encoders.Base64;
|
||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
@ -19,8 +20,6 @@ import java.util.Calendar;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import org.bouncycastle.util.encoders.Base64;
|
|
||||||
|
|
||||||
import static org.testng.Assert.fail;
|
import static org.testng.Assert.fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -405,7 +404,7 @@ public class PlatformCredentialTest {
|
|||||||
Base64.decode(EXPECTED_CERT_SIGNATURE_FOR_CERT2_1));
|
Base64.decode(EXPECTED_CERT_SIGNATURE_FOR_CERT2_1));
|
||||||
|
|
||||||
//Check if issuer certificate issued the platform credential
|
//Check if issuer certificate issued the platform credential
|
||||||
Assert.assertTrue(platformCert.isIssuer(issuer));
|
Assert.assertTrue(platformCert.isIssuer(issuer).isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -895,16 +895,17 @@ public class SupplyChainCredentialValidatorTest {
|
|||||||
|
|
||||||
trustedCerts.add(caCert);
|
trustedCerts.add(caCert);
|
||||||
trustedCerts.add(intermediateCert);
|
trustedCerts.add(intermediateCert);
|
||||||
|
boolean assertion = SupplyChainCredentialValidator.validateCertChain(attrCert,
|
||||||
|
trustedCerts).isEmpty();
|
||||||
|
|
||||||
Assert.assertTrue(SupplyChainCredentialValidator.validateCertChain(attrCert,
|
Assert.assertTrue(assertion);
|
||||||
trustedCerts));
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
keyStore.setCertificateEntry("CA cert", caCert);
|
keyStore.setCertificateEntry("CA cert", caCert);
|
||||||
keyStore.setCertificateEntry("Intermediate Cert", intermediateCert);
|
keyStore.setCertificateEntry("Intermediate Cert", intermediateCert);
|
||||||
|
assertion = SupplyChainCredentialValidator.verifyCertificate(attrCert,
|
||||||
Assert.assertTrue(SupplyChainCredentialValidator.verifyCertificate(attrCert,
|
keyStore).isEmpty();
|
||||||
keyStore));
|
Assert.assertTrue(assertion);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Assert.fail("Unexpected error occurred while verifying certificate", e);
|
Assert.fail("Unexpected error occurred while verifying certificate", e);
|
||||||
}
|
}
|
||||||
@ -938,14 +939,16 @@ public class SupplyChainCredentialValidatorTest {
|
|||||||
|
|
||||||
trustedCerts.add(caCert);
|
trustedCerts.add(caCert);
|
||||||
|
|
||||||
Assert.assertFalse(SupplyChainCredentialValidator.validateCertChain(attrCert,
|
boolean assertion = SupplyChainCredentialValidator.validateCertChain(attrCert,
|
||||||
trustedCerts));
|
trustedCerts).isEmpty();
|
||||||
|
Assert.assertFalse(assertion);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
keyStore.setCertificateEntry("CA cert", caCert);
|
keyStore.setCertificateEntry("CA cert", caCert);
|
||||||
|
|
||||||
Assert.assertFalse(SupplyChainCredentialValidator.verifyCertificate(attrCert,
|
assertion = SupplyChainCredentialValidator.verifyCertificate(attrCert,
|
||||||
keyStore));
|
keyStore).isEmpty();
|
||||||
|
Assert.assertFalse(assertion);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Assert.fail("Unexpected error occurred while verifying certificate", e);
|
Assert.fail("Unexpected error occurred while verifying certificate", e);
|
||||||
}
|
}
|
||||||
@ -971,12 +974,16 @@ public class SupplyChainCredentialValidatorTest {
|
|||||||
|
|
||||||
trustedCerts.add(caCert);
|
trustedCerts.add(caCert);
|
||||||
|
|
||||||
Assert.assertTrue(SupplyChainCredentialValidator.validateCertChain(attrCert, trustedCerts));
|
boolean assertion = SupplyChainCredentialValidator.validateCertChain(
|
||||||
|
attrCert, trustedCerts).isEmpty();
|
||||||
|
Assert.assertTrue(assertion);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
keyStore.setCertificateEntry("CA cert", caCert);
|
keyStore.setCertificateEntry("CA cert", caCert);
|
||||||
|
|
||||||
Assert.assertTrue(SupplyChainCredentialValidator.verifyCertificate(attrCert, keyStore));
|
assertion = SupplyChainCredentialValidator.verifyCertificate(
|
||||||
|
attrCert, keyStore).isEmpty();
|
||||||
|
Assert.assertTrue(assertion);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Assert.fail("Unexpected error occurred while verifying certificate", e);
|
Assert.fail("Unexpected error occurred while verifying certificate", e);
|
||||||
}
|
}
|
||||||
@ -1008,8 +1015,9 @@ public class SupplyChainCredentialValidatorTest {
|
|||||||
trustedCerts.add(caCert);
|
trustedCerts.add(caCert);
|
||||||
trustedCerts.add(intermediateCert);
|
trustedCerts.add(intermediateCert);
|
||||||
|
|
||||||
Assert.assertTrue(SupplyChainCredentialValidator.validateCertChain(targetCert,
|
boolean assertion = SupplyChainCredentialValidator.validateCertChain(targetCert,
|
||||||
trustedCerts));
|
trustedCerts).isEmpty();
|
||||||
|
Assert.assertTrue(assertion);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
keyStore.setCertificateEntry("CA cert", caCert);
|
keyStore.setCertificateEntry("CA cert", caCert);
|
||||||
@ -1046,8 +1054,9 @@ public class SupplyChainCredentialValidatorTest {
|
|||||||
|
|
||||||
trustedCerts.add(caCert);
|
trustedCerts.add(caCert);
|
||||||
|
|
||||||
Assert.assertFalse(SupplyChainCredentialValidator.validateCertChain(targetCert,
|
boolean assertion = SupplyChainCredentialValidator.validateCertChain(targetCert,
|
||||||
trustedCerts));
|
trustedCerts).isEmpty();
|
||||||
|
Assert.assertFalse(assertion);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
keyStore.setCertificateEntry("CA cert", caCert);
|
keyStore.setCertificateEntry("CA cert", caCert);
|
||||||
@ -1076,8 +1085,9 @@ public class SupplyChainCredentialValidatorTest {
|
|||||||
|
|
||||||
trustedCerts.add(caCert);
|
trustedCerts.add(caCert);
|
||||||
|
|
||||||
Assert.assertTrue(SupplyChainCredentialValidator.validateCertChain(targetCert,
|
boolean assertion = SupplyChainCredentialValidator.validateCertChain(targetCert,
|
||||||
trustedCerts));
|
trustedCerts).isEmpty();
|
||||||
|
Assert.assertTrue(assertion);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
keyStore.setCertificateEntry("CA cert", caCert);
|
keyStore.setCertificateEntry("CA cert", caCert);
|
||||||
|
26
scripts/download_validation_reports.sh
Normal file
26
scripts/download_validation_reports.sh
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#User input parameters:
|
||||||
|
#$1 filter start date 'yyyy-mm-dd'
|
||||||
|
#$2 filter end date 'yyyy-mm-dd'
|
||||||
|
#$3 ACA address, default is localhost if not given
|
||||||
|
|
||||||
|
if [ -z "$3" ]
|
||||||
|
then
|
||||||
|
endpoint="https://localhost:8443/HIRS_AttestationCAPortal/portal/validation-reports"
|
||||||
|
else
|
||||||
|
endpoint="https://$3:8443/HIRS_AttestationCAPortal/portal/validation-reports"
|
||||||
|
fi
|
||||||
|
echo "$endpoint"
|
||||||
|
content=$(curl --insecure $endpoint/list)
|
||||||
|
rawTimes=$(jq -r '.data | map(.createTime | tostring) | join(",")' <<< "$content")
|
||||||
|
createTimes=""
|
||||||
|
for i in ${rawTimes//,/ }
|
||||||
|
do
|
||||||
|
createTimes+="$(date -u +"%Y-%m-%d %H:%M:%S" -d @"$(($i/1000))"),"
|
||||||
|
done
|
||||||
|
deviceNames=$(jq -r '.data | map(.device.name) | join(",")' <<< "$content")
|
||||||
|
echo "Create times: $createTimes"
|
||||||
|
echo "Device names: $deviceNames"
|
||||||
|
curl --data "dateStart=$1&dateEnd=$2&createTimes=$createTimes&deviceNames=$deviceNames" --insecure $endpoint/download
|
||||||
|
|
Loading…
Reference in New Issue
Block a user