diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java index 2cb861ef..af085ca6 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -461,7 +461,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe int algorithmLength = baseline[0].length(); String[] storedPcrs = buildStoredPcrs(pcrContent, algorithmLength); - if (storedPcrs[0].isEmpty()) { + if (storedPcrs[0] == null || storedPcrs[0].isEmpty()) { // validation fail fwStatus = new AppraisalStatus(FAIL, "Firmware validation failed: " diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java index b0cf463e..7b84263b 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java @@ -35,15 +35,17 @@ import javax.servlet.http.HttpServletResponse; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Arrays; import java.util.Enumeration; +import java.util.List; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; /** * Controller for the Validation Reports page. @@ -59,7 +61,7 @@ public class ValidationReportsPageController extends PageController 4) { + reportData.delete(reportData.lastIndexOf(",") - 4, reportData.length()); + } } } bufferedWriter.append(columnHeaders + "\n"); @@ -259,13 +266,42 @@ public class ValidationReportsPageController extends PageController> parseComponents(final PlatformCredential pc) { ArrayList> parsedComponents = new ArrayList>(); + ArrayList> chainComponents = new ArrayList<>(); + + StringBuilder componentFailureString = new StringBuilder(); if (pc.getComponentIdentifiers() != null && pc.getComponentIdentifiers().size() > 0) { - LOGGER.info("Component failures: " + pc.getComponentFailures()); - ArrayList componentFailures = - new ArrayList(Arrays.asList(pc.getComponentFailures().split(";"))); + componentFailureString.append(pc.getComponentFailures()); + // get all the certificates associated with the platform serial + List chainCertificates = PlatformCredential + .select(certificateManager) + .byBoardSerialNumber(pc.getPlatformSerial()) + .getCertificates().stream().collect(Collectors.toList()); + // combine all components in each certificate for (ComponentIdentifier ci : pc.getComponentIdentifiers()) { + ArrayList issuerAndComponent = new ArrayList(); + 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 issuerAndComponent = new ArrayList(); + issuerAndComponent.add(cert.getIssuer()); + issuerAndComponent.add(ci); + chainComponents.add(issuerAndComponent); + } + } + } + LOGGER.info("Component failures: " + componentFailureString.toString()); + for (ArrayList issuerAndComponent : chainComponents) { ArrayList componentData = new ArrayList(); + String issuer = (String) issuerAndComponent.get(0); + issuer = issuer.replaceAll(",", " "); + ComponentIdentifier ci = (ComponentIdentifier) issuerAndComponent.get(1); if (ci instanceof ComponentIdentifierV2) { componentData.add(((ComponentIdentifierV2) ci).getComponentClass().toString()); } else { @@ -274,8 +310,9 @@ public class ValidationReportsPageController extends PageController issuerCertificates = new HashSet<>(); CertificateAuthorityCredential skiCA = null; + String issuerResult; //Check if there is a subject organization if (certificate.getAuthKeyId() != null && !certificate.getAuthKeyId().isEmpty()) { @@ -147,7 +158,7 @@ public final class CertificateStringMapBuilder { .select(certificateManager) .bySubjectKeyIdentifier(bytes).getCertificate(); } 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())); } @@ -171,7 +182,8 @@ public final class CertificateStringMapBuilder { for (Certificate issuerCert : issuerCertificates) { try { // 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 if (BouncyCastleUtils.x500NameCompare(issuerCert.getIssuer(), issuerCert.getSubject())) { diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/certificate-details.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/certificate-details.jsp index c9711c0b..a7c1393f 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/certificate-details.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/certificate-details.jsp @@ -88,7 +88,7 @@ + title="${initialData.missingChainIssuer}"> diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/Certificate.java b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/Certificate.java index feafa223..c38795e6 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/Certificate.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/Certificate.java @@ -8,31 +8,34 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1GeneralizedTime; +import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; 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.DEROctetString; +import org.bouncycastle.asn1.DERTaggedObject; 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.AttCertIssuer; +import org.bouncycastle.asn1.x509.AttributeCertificate; +import org.bouncycastle.asn1.x509.AttributeCertificateInfo; 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.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 javax.persistence.Column; @@ -64,9 +67,6 @@ import java.util.Date; import java.util.List; import java.util.ListIterator; 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 * @throws IOException if there is an issue deserializing either certificate */ - public boolean isIssuer(final Certificate issuer) throws IOException { - boolean isIssuer = false; + public String isIssuer(final Certificate issuer) throws IOException { + String isIssuer = "Certificate signature failed to verify"; // only run if of the correct type, otherwise false if (issuer.getCertificateType() == CertificateType.X509_CERTIFICATE) { X509Certificate issuerX509 = issuer.getX509Certificate(); @@ -764,7 +764,7 @@ public abstract class Certificate extends ArchivableEntity { X509Certificate certX509 = getX509Certificate(); try { certX509.verify(issuerX509.getPublicKey()); - isIssuer = true; + isIssuer = ""; } catch (CertificateException | NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException | SignatureException e) { LOGGER.error(e); @@ -777,7 +777,9 @@ public abstract class Certificate extends ArchivableEntity { Signature sig = Signature.getInstance(algorithm); sig.initVerify(issuerX509.getPublicKey()); sig.update(attCert.getAcinfo().getEncoded()); - isIssuer = sig.verify(attCert.getSignatureValue().getBytes()); + if (sig.verify(attCert.getSignatureValue().getBytes())) { + isIssuer = ""; + } } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java index ce35d6e1..9dd07a52 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java @@ -4,22 +4,11 @@ import com.google.common.base.Preconditions; import hirs.data.persist.certificate.attributes.ComponentIdentifier; import hirs.data.persist.certificate.attributes.PlatformConfiguration; 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.URIReference; +import hirs.data.persist.certificate.attributes.V2.PlatformConfigurationV2; import hirs.persist.CertificateManager; 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.logging.log4j.LogManager; 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.AttributeCertificateInfo; 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.GeneralName; 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.operator.ContentVerifier; 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 * 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. */ private static final Map TCG_PLATFORM_MAP = new HashMap() {{ - put("#00000000", "Client"); - put("#00000001", "Server"); + put("#00000000", "Unclassified"); + 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. diff --git a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java index da294f42..18226062 100644 --- a/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java +++ b/HIRS_Utils/src/main/java/hirs/validation/SupplyChainCredentialValidator.java @@ -4,17 +4,21 @@ import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; 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.info.HardwareInfo; +import hirs.data.persist.SupplyChainValidation; import hirs.data.persist.certificate.EndorsementCredential; import hirs.data.persist.certificate.PlatformCredential; 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.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.util.Strings; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.CertException; @@ -41,11 +45,14 @@ import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; 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.FAIL; 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 String baseErrorMessage = "Can't validate platform credential without "; String message; + String certVerifyMsg; if (pc == null) { message = baseErrorMessage + "a platform credential\n"; LOGGER.error(message); @@ -233,19 +234,21 @@ public final class SupplyChainCredentialValidator implements CredentialValidator // verify cert against truststore try { - if (verifyCertificate(attributeCert, trustStore)) { + certVerifyMsg = verifyCertificate(attributeCert, trustStore); + if (certVerifyMsg.isEmpty()) { message = PLATFORM_VALID; LOGGER.info(message); return new AppraisalStatus(PASS, message); } else { - message = "Platform credential failed verification"; + message = String.format("Platform credential failed verification%n%s", + certVerifyMsg); LOGGER.error(message); return new AppraisalStatus(FAIL, message); } - } catch (SupplyChainValidatorException e) { + } catch (SupplyChainValidatorException scvEx) { message = "An error occurred indicating the credential is not valid"; - LOGGER.warn(message, e); - return new AppraisalStatus(FAIL, message + " " + e.getMessage()); + LOGGER.warn(message, scvEx); + return new AppraisalStatus(FAIL, message + " " + scvEx.getMessage()); } } @@ -1244,14 +1247,14 @@ public final class SupplyChainCredentialValidator implements CredentialValidator * @throws SupplyChainValidatorException * 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 { if (cert == null || trustStore == null) { throw new SupplyChainValidatorException("Certificate or trust store is null"); } try { - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); Enumeration alias = trustStore.aliases(); @@ -1259,15 +1262,14 @@ public final class SupplyChainCredentialValidator implements CredentialValidator trustedCerts.add((X509Certificate) trustStore.getCertificate(alias.nextElement())); } - boolean certChainValidated = validateCertChain(cert, trustedCerts); - if (!certChainValidated) { + String certChainValidated = validateCertChain(cert, trustedCerts); + if (!certChainValidated.isEmpty()) { LOGGER.error("Cert chain could not be validated"); } return certChainValidated; } catch (KeyStoreException 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"); } try { - Set trustedCerts = new HashSet(); + Set trustedCerts = new HashSet<>(); Enumeration alias = trustStore.aliases(); @@ -1299,7 +1301,7 @@ public final class SupplyChainCredentialValidator implements CredentialValidator trustedCerts.add((X509Certificate) trustStore.getCertificate(alias.nextElement())); } - return validateCertChain(cert, trustedCerts); + return validateCertChain(cert, trustedCerts).isEmpty(); } catch (KeyStoreException e) { LOGGER.error("Error accessing keystore", 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 * @throws SupplyChainValidatorException tried to validate using null certificates */ - public static boolean validateCertChain(final X509AttributeCertificateHolder cert, + public static String validateCertChain(final X509AttributeCertificateHolder cert, final Set additionalCerts) throws SupplyChainValidatorException { if (cert == null || additionalCerts == null) { throw new SupplyChainValidatorException( "Certificate or validation certificates are null"); } - boolean foundRootOfCertChain = false; + String foundRootOfCertChain = ""; Iterator certIterator = additionalCerts.iterator(); X509Certificate trustedCert; + boolean issuerMatchesSubject = false; + boolean signatureMatchesPublicKey = false; - while (!foundRootOfCertChain && certIterator.hasNext()) { + while (foundRootOfCertChain.isEmpty() && certIterator.hasNext()) { trustedCert = certIterator.next(); - if (issuerMatchesSubjectDN(cert, trustedCert) - && signatureMatchesPublicKey(cert, trustedCert)) { + issuerMatchesSubject = issuerMatchesSubjectDN(cert, trustedCert); + signatureMatchesPublicKey = signatureMatchesPublicKey(cert, trustedCert); + if (issuerMatchesSubject && signatureMatchesPublicKey) { if (isSelfSigned(trustedCert)) { LOGGER.info("CA Root found."); - foundRootOfCertChain = true; } else { foundRootOfCertChain = validateCertChain(trustedCert, additionalCerts); - if (!foundRootOfCertChain) { + if (!foundRootOfCertChain.isEmpty()) { LOGGER.error("Root of certificate chain not found. Check for CA Cert: " + 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 * @throws SupplyChainValidatorException tried to validate using null certificates */ - public static boolean validateCertChain(final X509Certificate cert, + public static String validateCertChain(final X509Certificate cert, final Set additionalCerts) throws SupplyChainValidatorException { if (cert == null || additionalCerts == null) { throw new SupplyChainValidatorException( "Certificate or validation certificates are null"); } - boolean foundRootOfCertChain = false; + String foundRootOfCertChain = ""; Iterator certIterator = additionalCerts.iterator(); X509Certificate trustedCert; + boolean issuerMatchesSubject = false; + boolean signatureMatchesPublicKey = false; - while (!foundRootOfCertChain && certIterator.hasNext()) { + while (foundRootOfCertChain.isEmpty() && certIterator.hasNext()) { trustedCert = certIterator.next(); - if (issuerMatchesSubjectDN(cert, trustedCert) - && signatureMatchesPublicKey(cert, trustedCert)) { + issuerMatchesSubject = issuerMatchesSubjectDN(cert, trustedCert); + signatureMatchesPublicKey = signatureMatchesPublicKey(cert, trustedCert); + if (issuerMatchesSubject && signatureMatchesPublicKey) { if (isSelfSigned(trustedCert)) { LOGGER.info("CA Root found."); - foundRootOfCertChain = true; } else if (!cert.equals(trustedCert)) { foundRootOfCertChain = validateCertChain(trustedCert, additionalCerts); - if (!foundRootOfCertChain) { + if (!foundRootOfCertChain.isEmpty()) { LOGGER.error("Root of certificate chain not found. Check for CA Cert: " + 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, final X509Certificate signingCert) throws SupplyChainValidatorException { - if (cert == null || signingCert == null) { - throw new SupplyChainValidatorException("Certificate or signing certificate is null"); + if (signingCert == null) { + throw new SupplyChainValidatorException("Signing certificate is null"); } return signatureMatchesPublicKey(cert, signingCert.getPublicKey()); } diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/certificate/CertificateTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/certificate/CertificateTest.java index ee8f0bbd..3dbd7404 100644 --- a/HIRS_Utils/src/test/java/hirs/data/persist/certificate/CertificateTest.java +++ b/HIRS_Utils/src/test/java/hirs/data/persist/certificate/CertificateTest.java @@ -441,8 +441,8 @@ public class CertificateTest { Certificate issuerCert = getTestCertificate(FAKE_ROOT_CA_FILE); Certificate cert = getTestCertificate(INT_CA_CERT02); - Assert.assertFalse(issuerCert.isIssuer(cert)); - Assert.assertTrue(cert.isIssuer(issuerCert)); + Assert.assertFalse(!issuerCert.isIssuer(cert).isEmpty()); + Assert.assertTrue(cert.isIssuer(issuerCert).isEmpty()); } /** diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/certificate/PlatformCredentialTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/certificate/PlatformCredentialTest.java index de054891..55a357b9 100644 --- a/HIRS_Utils/src/test/java/hirs/data/persist/certificate/PlatformCredentialTest.java +++ b/HIRS_Utils/src/test/java/hirs/data/persist/certificate/PlatformCredentialTest.java @@ -7,6 +7,7 @@ import hirs.data.persist.certificate.attributes.TBBSecurityAssertion; import hirs.data.persist.certificate.attributes.URIReference; import hirs.data.persist.certificate.attributes.V2.PlatformConfigurationV2; import org.apache.commons.codec.binary.Hex; +import org.bouncycastle.util.encoders.Base64; import org.testng.Assert; import org.testng.annotations.Test; @@ -19,8 +20,6 @@ import java.util.Calendar; import java.util.List; import java.util.TimeZone; -import org.bouncycastle.util.encoders.Base64; - import static org.testng.Assert.fail; /** @@ -405,7 +404,7 @@ public class PlatformCredentialTest { Base64.decode(EXPECTED_CERT_SIGNATURE_FOR_CERT2_1)); //Check if issuer certificate issued the platform credential - Assert.assertTrue(platformCert.isIssuer(issuer)); + Assert.assertTrue(platformCert.isIssuer(issuer).isEmpty()); } /** diff --git a/HIRS_Utils/src/test/java/hirs/validation/SupplyChainCredentialValidatorTest.java b/HIRS_Utils/src/test/java/hirs/validation/SupplyChainCredentialValidatorTest.java index df28a10f..e7f865b7 100644 --- a/HIRS_Utils/src/test/java/hirs/validation/SupplyChainCredentialValidatorTest.java +++ b/HIRS_Utils/src/test/java/hirs/validation/SupplyChainCredentialValidatorTest.java @@ -895,16 +895,17 @@ public class SupplyChainCredentialValidatorTest { trustedCerts.add(caCert); trustedCerts.add(intermediateCert); + boolean assertion = SupplyChainCredentialValidator.validateCertChain(attrCert, + trustedCerts).isEmpty(); - Assert.assertTrue(SupplyChainCredentialValidator.validateCertChain(attrCert, - trustedCerts)); + Assert.assertTrue(assertion); try { keyStore.setCertificateEntry("CA cert", caCert); keyStore.setCertificateEntry("Intermediate Cert", intermediateCert); - - Assert.assertTrue(SupplyChainCredentialValidator.verifyCertificate(attrCert, - keyStore)); + assertion = SupplyChainCredentialValidator.verifyCertificate(attrCert, + keyStore).isEmpty(); + Assert.assertTrue(assertion); } catch (Exception e) { Assert.fail("Unexpected error occurred while verifying certificate", e); } @@ -938,14 +939,16 @@ public class SupplyChainCredentialValidatorTest { trustedCerts.add(caCert); - Assert.assertFalse(SupplyChainCredentialValidator.validateCertChain(attrCert, - trustedCerts)); + boolean assertion = SupplyChainCredentialValidator.validateCertChain(attrCert, + trustedCerts).isEmpty(); + Assert.assertFalse(assertion); try { keyStore.setCertificateEntry("CA cert", caCert); - Assert.assertFalse(SupplyChainCredentialValidator.verifyCertificate(attrCert, - keyStore)); + assertion = SupplyChainCredentialValidator.verifyCertificate(attrCert, + keyStore).isEmpty(); + Assert.assertFalse(assertion); } catch (Exception e) { Assert.fail("Unexpected error occurred while verifying certificate", e); } @@ -971,12 +974,16 @@ public class SupplyChainCredentialValidatorTest { trustedCerts.add(caCert); - Assert.assertTrue(SupplyChainCredentialValidator.validateCertChain(attrCert, trustedCerts)); + boolean assertion = SupplyChainCredentialValidator.validateCertChain( + attrCert, trustedCerts).isEmpty(); + Assert.assertTrue(assertion); try { keyStore.setCertificateEntry("CA cert", caCert); - Assert.assertTrue(SupplyChainCredentialValidator.verifyCertificate(attrCert, keyStore)); + assertion = SupplyChainCredentialValidator.verifyCertificate( + attrCert, keyStore).isEmpty(); + Assert.assertTrue(assertion); } catch (Exception e) { Assert.fail("Unexpected error occurred while verifying certificate", e); } @@ -1008,8 +1015,9 @@ public class SupplyChainCredentialValidatorTest { trustedCerts.add(caCert); trustedCerts.add(intermediateCert); - Assert.assertTrue(SupplyChainCredentialValidator.validateCertChain(targetCert, - trustedCerts)); + boolean assertion = SupplyChainCredentialValidator.validateCertChain(targetCert, + trustedCerts).isEmpty(); + Assert.assertTrue(assertion); try { keyStore.setCertificateEntry("CA cert", caCert); @@ -1046,8 +1054,9 @@ public class SupplyChainCredentialValidatorTest { trustedCerts.add(caCert); - Assert.assertFalse(SupplyChainCredentialValidator.validateCertChain(targetCert, - trustedCerts)); + boolean assertion = SupplyChainCredentialValidator.validateCertChain(targetCert, + trustedCerts).isEmpty(); + Assert.assertFalse(assertion); try { keyStore.setCertificateEntry("CA cert", caCert); @@ -1076,8 +1085,9 @@ public class SupplyChainCredentialValidatorTest { trustedCerts.add(caCert); - Assert.assertTrue(SupplyChainCredentialValidator.validateCertChain(targetCert, - trustedCerts)); + boolean assertion = SupplyChainCredentialValidator.validateCertChain(targetCert, + trustedCerts).isEmpty(); + Assert.assertTrue(assertion); try { keyStore.setCertificateEntry("CA cert", caCert); diff --git a/scripts/download_validation_reports.sh b/scripts/download_validation_reports.sh new file mode 100644 index 00000000..c67fdac3 --- /dev/null +++ b/scripts/download_validation_reports.sh @@ -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 +