From 09bfb9fe0600346a8ad20fb94d89dfc05aac07d3 Mon Sep 17 00:00:00 2001 From: iadgovuser29 <33426478+iadgovuser29@users.noreply.github.com> Date: Mon, 18 Sep 2023 10:10:56 -0400 Subject: [PATCH 01/26] New context mappings for the index page. --- .../portal/page/controllers/IndexPageController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IndexPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IndexPageController.java index d1430342..07a0c849 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IndexPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IndexPageController.java @@ -14,7 +14,7 @@ import org.springframework.web.servlet.ModelAndView; */ @Controller @Log4j2 -@RequestMapping("/HIRS_AttestationCAPortal/portal/index") +@RequestMapping(value={"/", "/HIRS_AttestationCAPortal", "/HIRS_AttestationCAPortal/", "/HIRS_AttestationCAPortal/portal/index"}) public class IndexPageController extends PageController { /** From 4b67747e3e6344ee23c8939719cc75d4e4bae3c0 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Thu, 21 Sep 2023 15:02:24 -0400 Subject: [PATCH 02/26] Updated the bulk of the code that does all provisioning from a client. There is some parsed functionality to ease sorting through the changes and updates needed in the future. --- HIRS_AttestationCA/build.gradle | 1 + .../persist/PCRQuoteValidator.java | 223 --- .../ReferenceDigestValueRepository.java | 5 +- .../manager/ReferenceManifestRepository.java | 2 + .../certificate/PlatformCredential.java | 2 + .../provision/CertificateRequestHandler.java | 1 + .../provision/IdentityClaimHandler.java | 9 +- .../service/SupplyChainValidationService.java | 366 +++- .../SupplyChainValidationServiceImpl.java | 377 ---- .../attestationca/persist/util}/PciIds.java | 2 +- .../validation/CredentialValidator.java | 223 ++- .../persist/validation/PcrValidator.java | 26 + .../SupplyChainCredentialValidator.java | 496 ++++- ...eferenceManifestDetailsPageController.java | 28 +- .../utils/CertificateStringMapBuilder.java | 1 + .../utils/SupplyChainCredentialValidator.java | 1766 ----------------- .../utils/tpm/eventlog/uefi/UefiGuid.java | 2 +- 17 files changed, 1055 insertions(+), 2475 deletions(-) delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/PCRQuoteValidator.java delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationServiceImpl.java rename {HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils => HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util}/PciIds.java (99%) delete mode 100644 HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/SupplyChainCredentialValidator.java diff --git a/HIRS_AttestationCA/build.gradle b/HIRS_AttestationCA/build.gradle index 31806ddd..e9427645 100644 --- a/HIRS_AttestationCA/build.gradle +++ b/HIRS_AttestationCA/build.gradle @@ -36,6 +36,7 @@ dependencies { implementation libs.jakarta.api implementation libs.jakarta.xml implementation libs.hibernate.core + implementation libs.pci implementation libs.guava implementation libs.jackson.core implementation libs.jackson.databind diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/PCRQuoteValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/PCRQuoteValidator.java deleted file mode 100644 index 431dacf6..00000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/PCRQuoteValidator.java +++ /dev/null @@ -1,223 +0,0 @@ -package hirs.attestationca.persist; - -import hirs.attestationca.persist.entity.userdefined.PolicySettings; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.extern.log4j.Log4j2; - -/** - * The class handles the flags that ignore certain PCRs for validation. - */ -@Log4j2 -@NoArgsConstructor -public class PCRQuoteValidator { - - /** - * Minimum possible value for a PCR ID. This is 0. - */ - public static final int MIN_PCR_ID = 0; - - /** - * Maximum possible value for a PCR ID. This is 23. - */ - public static final int MAX_PCR_ID = 23; - - private static final int NUM_TO_SKIP = 1; - private static final int NUM_OF_TBOOT_PCR = 3; - // PCR 5-16 - private static final int PXE_PCR_START = 5; - private static final int PXE_PCR_END = 16; - // PCR 10 - private static final int IMA_PCR = 10; - // PCR 17-19 - private static final int TBOOT_PCR_START = 17; - private static final int TBOOT_PCR_END = 19; - // PCR 5 - private static final int GPT_PCR = 5; - private static final int IMA_MASK = 0xfffbff; - - // Event Log Event Types - private static final String EVT_EFI_BOOT = "EV_EFI_BOOT_SERVICES_APPLICATION"; - private static final String EVT_EFI_VAR = "EV_EFI_VARIABLE_BOOT"; - private static final String EVT_EFI_GPT = "EV_EFI_GPT_EVENT"; - private static final String EVT_EFI_CFG = "EV_EFI_VARIABLE_DRIVER_CONFIG"; - - private String[] baselinePCRS = new String[MAX_PCR_ID + 1]; - @Getter - @Setter - private PolicySettings settings; - - /** - * Constructor to parse PCR values. - * @param pcrValues pcrValues RIM provided baseline PCRs - * @param settings settings for the supply chain portal settings for provisioning - */ - public PCRQuoteValidator(final String[] pcrValues, - final PolicySettings settings) { - if (pcrValues != null) { - baselinePCRS = new String[MAX_PCR_ID + 1]; - for (int i = 0; i <= MAX_PCR_ID; i++) { - baselinePCRS[i] = pcrValues[i]; - } - } - - this.settings = settings; - } - - /** - * Getter for the array of baseline PCRs. - * @return instance of the PCRs. - */ - public String[] getBaselinePCRS() { - return baselinePCRS.clone(); - } - - /** - * Setter for the array of baseline PCRs. - * @param baselinePCRS instance of the PCRs. - */ - public void setBaselinePCRS(final String[] baselinePCRS) { - this.baselinePCRS = baselinePCRS.clone(); - } - - /** - * Compares the baseline pcr list and the quote pcr list. If the - * ignore flags are set, 10 and 17-19 will be skipped for comparison. - * - * @param storedPCRS non-baseline pcr list - * @return a StringBuilder that is empty if everything passes. - */ - public StringBuilder validatePCRS(final String[] storedPCRS) { - StringBuilder sb = new StringBuilder(); - String failureMsg = "PCR %d does not match%n"; - if (storedPCRS[0] == null || storedPCRS[0].isEmpty()) { - sb.append("failureMsg"); - } else { - for (int i = 0; i <= MAX_PCR_ID; i++) { - if (settings.isIgnoreImaEnabled() && i == IMA_PCR) { - log.info("PCR Policy IMA Ignore enabled."); - i += NUM_TO_SKIP; - } - - if (settings.isIgnoretBootEnabled() && i == TBOOT_PCR_START) { - log.info("PCR Policy TBoot Ignore enabled."); - i += NUM_OF_TBOOT_PCR; - } - - if (settings.isIgnoreGptEnabled() && i == GPT_PCR) { - log.info("PCR Policy GPT Ignore enabled."); - i += NUM_TO_SKIP; - } - - if (!baselinePCRS[i].equals(storedPCRS[i])) { - //error - log.error(String.format("%s =/= %s", baselinePCRS[i], storedPCRS[i])); - sb.append(String.format(failureMsg, i)); - } - } - } - - return sb; - } - - /** - * Checks that the expected FM events occurring. There are policy options that - * will ignore certain PCRs, Event Types and Event Variables present. - * @param tcgMeasurementLog Measurement log from the client - * @param eventValueMap The events stored as baseline to compare - * @return the events that didn't pass - */ -// public List validateTpmEvents(final TCGEventLog tcgMeasurementLog, -// final Map eventValueMap) { -// List tpmPcrEvents = new LinkedList<>(); -// for (TpmPcrEvent tpe : tcgMeasurementLog.getEventList()) { -// if (enableIgnoreIma && tpe.getPcrIndex() == IMA_PCR) { -// log.info(String.format("IMA Ignored -> %s", tpe)); -// } else if (enableIgnoretBoot && (tpe.getPcrIndex() >= TBOOT_PCR_START -// && tpe.getPcrIndex() <= TBOOT_PCR_END)) { -// log.info(String.format("TBOOT Ignored -> %s", tpe)); -// } else if (enableIgnoreOsEvt && (tpe.getPcrIndex() >= PXE_PCR_START -// && tpe.getPcrIndex() <= PXE_PCR_END)) { -// log.info(String.format("OS Evt Ignored -> %s", tpe)); -// } else { -// if (enableIgnoreGpt && tpe.getEventTypeStr().contains(EVT_EFI_GPT)) { -// log.info(String.format("GPT Ignored -> %s", tpe)); -// } else if (enableIgnoreOsEvt && (tpe.getEventTypeStr().contains(EVT_EFI_BOOT) -// || tpe.getEventTypeStr().contains(EVT_EFI_VAR))) { -// log.info(String.format("OS Evt Ignored -> %s", tpe)); -// } else if (enableIgnoreOsEvt && (tpe.getEventTypeStr().contains(EVT_EFI_CFG) -// && tpe.getEventContentStr().contains("SecureBoot"))) { -// log.info(String.format("OS Evt Config Ignored -> %s", tpe)); -// } else { -// if (!eventValueMap.containsKey(tpe.getEventDigestStr())) { -// tpmPcrEvents.add(tpe); -// } -// } -// } -// } -// -// return tpmPcrEvents; -// } - - /** - * Compares hashes to validate the quote from the client. - * - * @param tpmQuote the provided quote - * @param storedPCRS values from the RIM file - * @return true if validated, false if not - */ -// public boolean validateQuote(final byte[] tpmQuote, final String[] storedPCRS) { -// System.out.println("Validating quote from associated device."); -// boolean validated = false; -// short localityAtRelease = 0; -// String quoteString = new String(tpmQuote, StandardCharsets.UTF_8); -// int pcrMaskSelection = PcrSelection.ALL_PCRS_ON; -// -// if (enableIgnoreIma) { -// pcrMaskSelection = IMA_MASK; -// } -// -// ArrayList measurements = new ArrayList<>(); -// -// try { -// for (int i = 0; i < storedPcrs.length; i++) { -// if (i == IMA_PCR && enableIgnoreIma) { -// log.info("Ignore IMA PCR policy is enabled."); -// } else { -// measurements.add(new TPMMeasurementRecord(i, storedPcrs[i])); -// } -// } -// } catch (DecoderException deEx) { -// //error -// System.out.println(deEx); -// } -// -// PcrSelection pcrSelection = new PcrSelection(pcrMaskSelection); -// PcrComposite pcrComposite = new PcrComposite(pcrSelection); -// PcrInfoShort pcrInfoShort = new PcrInfoShort(pcrSelection, -// localityAtRelease, -// tpmQuote, pcrComposite); -// -// try { -// /** -// * The calculated string is being used in the contains method -// * because the TPM Quote's hash isn't just for PCR values, -// * it contains the calculated digest of the PCRs, along with -// * other information. -// */ -// String calculatedString = Hex.encodeHexString( -// pcrInfoShort.getCalculatedDigest()); -// validated = quoteString.contains(calculatedString); -// if (!validated) { -// // warn -// System.out.println(calculatedString + " not found in " + quoteString); -// } -// } catch (NoSuchAlgorithmException naEx) { -// // error -// System.out.println(naEx); -// } -// -// return validated; -// } -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/ReferenceDigestValueRepository.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/ReferenceDigestValueRepository.java index 24be3dd5..c228a587 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/ReferenceDigestValueRepository.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/ReferenceDigestValueRepository.java @@ -11,12 +11,9 @@ import java.util.UUID; @Repository public interface ReferenceDigestValueRepository extends JpaRepository { - @Query(value = "SELECT * FROM ReferenceDigestValue", nativeQuery = true) - List listAll(); List findByModel(String model); List findByManufacturer(String manufacturer); - @Query(value = "SELECT * FROM ReferenceDigestValue WHERE baseRimId = '?1' OR supportRimId = '?1'", nativeQuery = true) - List getValuesByRimId(UUID associatedRimId); + List findValuesByBaseRimId(UUID associatedRimId); List findBySupportRimId(UUID supportRimId); List findBySupportRimHash(String supportRimHash); List findByManufacturerAndModel(String manufacturer, String model); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/ReferenceManifestRepository.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/ReferenceManifestRepository.java index b74516bf..eb0892b2 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/ReferenceManifestRepository.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/ReferenceManifestRepository.java @@ -39,4 +39,6 @@ public interface ReferenceManifestRepository extends JpaRepository getSupportByManufacturerModel(String manufacturer, String model); + @Query(value = "SELECT * FROM ReferenceManifest WHERE platformModel = ?1 AND DTYPE = 'EventLogMeasurements'", nativeQuery = true) + EventLogMeasurements getLogByModel(String model); } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java index 52b6769e..4956723f 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredential.java @@ -176,6 +176,8 @@ public class PlatformCredential extends DeviceAssociatedCertificate { @Column(length = MAX_MESSAGE_LENGTH) private String componentFailures = Strings.EMPTY; + @Column(length = MAX_MESSAGE_LENGTH) + private String componentFailureMessage = Strings.EMPTY; @Transient private EndorsementCredential endorsementCredential = null; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestHandler.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestHandler.java index 2ca0611c..5eb42b76 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestHandler.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestHandler.java @@ -198,6 +198,7 @@ public class CertificateRequestHandler extends AbstractRequestHandler { * @return the {@link AppraisalStatus} of the supply chain validation */ private AppraisalStatus.Status doQuoteValidation(final Device device) { + log.info("Beginning Quote Validation..."); // perform supply chain validation SupplyChainValidationSummary scvs = supplyChainValidationService.validateQuote( device); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimHandler.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimHandler.java index a2d6dfc8..4dc3458c 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimHandler.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimHandler.java @@ -124,6 +124,7 @@ public class IdentityClaimHandler extends AbstractRequestHandler { try { validationResult = doSupplyChainValidation(claim, ekPub); } catch (Exception ex) { + log.error(ex.getMessage()); for (StackTraceElement ste : ex.getStackTrace()) { log.error(ste.toString()); } @@ -191,12 +192,15 @@ public class IdentityClaimHandler extends AbstractRequestHandler { // this is to check what is in the platform object and pull // additional information from the DB if information exists if (platformCredentials.size() == 1) { + List tempList = new LinkedList<>(); for (PlatformCredential pc : platformCredentials) { if (pc != null && pc.getPlatformSerial() != null) { - platformCredentials.addAll(certificateRepository + tempList.addAll(certificateRepository .byBoardSerialNumber(pc.getPlatformSerial())); } } + + platformCredentials.addAll(tempList); } // perform supply chain validation SupplyChainValidationSummary summary = supplyChainValidationService.validateSupplyChain( @@ -227,6 +231,9 @@ public class IdentityClaimHandler extends AbstractRequestHandler { log.info("Processing Device Info Report"); // store device and device info report. Device device = this.deviceRepository.findByName(deviceInfoReport.getNetworkInfo().getHostname()); + if (device == null) { + device = new Device(deviceInfoReport); + } device.setDeviceInfo(deviceInfoReport); return this.deviceRepository.save(device); } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java index 55e01b09..1c6e9ec1 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java @@ -1,30 +1,259 @@ package hirs.attestationca.persist.service; +import hirs.attestationca.persist.DBManagerException; +import hirs.attestationca.persist.entity.ArchivableEntity; +import hirs.attestationca.persist.entity.manager.CACredentialRepository; +import hirs.attestationca.persist.entity.manager.CertificateRepository; +import hirs.attestationca.persist.entity.manager.ComponentResultRepository; +import hirs.attestationca.persist.entity.manager.PolicyRepository; +import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository; +import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository; +import hirs.attestationca.persist.entity.manager.SupplyChainValidationSummaryRepository; import hirs.attestationca.persist.entity.userdefined.Device; +import hirs.attestationca.persist.entity.userdefined.PolicySettings; +import hirs.attestationca.persist.entity.userdefined.SupplyChainValidation; import hirs.attestationca.persist.entity.userdefined.SupplyChainValidationSummary; import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; +import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements; +import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest; +import hirs.attestationca.persist.enums.AppraisalStatus; +import hirs.attestationca.persist.validation.PcrValidator; +import hirs.attestationca.persist.validation.SupplyChainCredentialValidator; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import java.security.KeyStore; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; import java.util.List; +import java.util.Map; + +import org.apache.logging.log4j.Level; + +import static hirs.attestationca.persist.enums.AppraisalStatus.Status.FAIL; +import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS; + +@Log4j2 +@Service +public class SupplyChainValidationService { + + private CACredentialRepository caCredentialRepository; + private PolicyRepository policyRepository; + private ReferenceManifestRepository referenceManifestRepository; + private ReferenceDigestValueRepository referenceDigestValueRepository; + private ComponentResultRepository componentResultRepository; + private CertificateRepository certificateRepository; + private SupplyChainValidationSummaryRepository supplyChainValidationSummaryRepository; -/** - * Interface defining a component that will perform supply chain validations, which yields a - * {@link SupplyChainValidationSummary}. - */ -public interface SupplyChainValidationService { /** - * The "main" method of supply chain validation. Takes the credentials from an identity - * request and validates the supply chain in accordance to the current supply chain - * policy. + * Constructor. * - * @param ec The endorsement credential from the identity request. - * @param pc The set of platform credentials from the identity request. - * @param device The device to be validated. - * @return True if validation is successful, false otherwise. + * @param caCredentialRepository ca credential repository + * @param policyRepository the policy manager + * @param certificateRepository the cert manager + * @param componentResultRepository the comp result manager + * @param referenceManifestRepository the RIM manager + * @param supplyChainValidationSummaryRepository the summary manager + * @param referenceDigestValueRepository the even manager */ - SupplyChainValidationSummary validateSupplyChain(EndorsementCredential ec, - List pc, - Device device); + @Autowired + @SuppressWarnings("ParameterNumberCheck") + public SupplyChainValidationService( + final CACredentialRepository caCredentialRepository, + final PolicyRepository policyRepository, + final CertificateRepository certificateRepository, + final ComponentResultRepository componentResultRepository, + final ReferenceManifestRepository referenceManifestRepository, + final SupplyChainValidationSummaryRepository supplyChainValidationSummaryRepository, + final ReferenceDigestValueRepository referenceDigestValueRepository) { + this.caCredentialRepository = caCredentialRepository; + this.policyRepository = policyRepository; + this.certificateRepository = certificateRepository; + this.componentResultRepository = componentResultRepository; + this.referenceManifestRepository = referenceManifestRepository; + this.supplyChainValidationSummaryRepository = supplyChainValidationSummaryRepository; + this.referenceDigestValueRepository = referenceDigestValueRepository; + } + + /** + * The "main" method of supply chain validation. Takes the credentials from + * an identity request and validates the supply chain in accordance to the + * current supply chain policy. + * + * @param ec The endorsement credential from the identity request. + * @param pcs The platform credentials from the identity request. + * @param device The device to be validated. + * @return A summary of the validation results. + */ + @SuppressWarnings("methodlength") + public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredential ec, + final List pcs, + final Device device) { + boolean acceptExpiredCerts = getPolicySettings().isExpiredCertificateValidationEnabled(); + PlatformCredential baseCredential = null; + SupplyChainValidation platformScv = null; + SupplyChainValidation basePlatformScv = null; + boolean chkDeltas = false; + String pcErrorMessage = ""; + List validations = new LinkedList<>(); + Map deltaMapping = new HashMap<>(); + SupplyChainValidation.ValidationType platformType = SupplyChainValidation + .ValidationType.PLATFORM_CREDENTIAL; + log.info("Beginning Supply Chain Validation..."); + + log.info("Beginning Endorsement Credential Validation..."); + // Validate the Endorsement Credential + if (getPolicySettings().isEcValidationEnabled()) { + validations.add(ValidationManager.evaluateEndorsementCredentialStatus(ec, this.caCredentialRepository, acceptExpiredCerts)); + // store the device with the credential + if (ec != null) { + ec.setDeviceId(device.getId()); + this.certificateRepository.save(ec); + } + } + + log.info("Beginning Platform Credential Validation..."); + // Validate Platform Credential signatures + if (getPolicySettings().isPcValidationEnabled()) { + // Ensure there are platform credentials to validate + if (pcs == null || pcs.isEmpty()) { + log.error("There were no Platform Credentials to validate."); + pcErrorMessage = "Platform credential(s) missing\n"; + } else { + for (PlatformCredential pc : pcs) { + KeyStore trustedCa = ValidationManager.getCaChain(pc, caCredentialRepository); + platformScv = ValidationManager.evaluatePlatformCredentialStatus( + pc, trustedCa, acceptExpiredCerts); + + if (platformScv.getValidationResult() == AppraisalStatus.Status.FAIL) { + pcErrorMessage = String.format("%s%s%n", pcErrorMessage, + platformScv.getMessage()); + } + // set the base credential + if (pc.isPlatformBase()) { + baseCredential = pc; + basePlatformScv = platformScv; + } else { + chkDeltas = true; + deltaMapping.put(pc, null); + } + pc.setDeviceId(device.getId()); + this.certificateRepository.save(pc); + + } + + // check that the delta certificates validity date is after + // the base + if (baseCredential != null) { + for (PlatformCredential pc : pcs) { + int result = baseCredential.getBeginValidity() + .compareTo(pc.getBeginValidity()); + if (!pc.isPlatformBase() && (result > 0)) { + pcErrorMessage = String.format("%s%s%n", pcErrorMessage, + "Delta Certificate's validity " + + "date is not after Base"); + break; + } + } + } else { + // we don't have a base cert, fail + pcErrorMessage = String.format("%s%s%n", pcErrorMessage, + "Base Platform credential missing"); + } + } + + if (pcErrorMessage.isEmpty()) { + validations.add(platformScv); + } else { + if (pcs == null) { + validations.add(new SupplyChainValidation(platformType, + AppraisalStatus.Status.FAIL, new ArrayList<>(), pcErrorMessage)); + } else { + validations.add(new SupplyChainValidation(platformType, + AppraisalStatus.Status.FAIL, new ArrayList<>(pcs), pcErrorMessage)); + } + } + } + + log.info("Beginning Platform Attributes Validation..."); + // Validate Platform Credential attributes + if (getPolicySettings().isPcAttributeValidationEnabled() + && pcErrorMessage.isEmpty()) { + // Ensure there are platform credentials to validate + SupplyChainValidation attributeScv = null; + String attrErrorMessage = ""; + List aes = new ArrayList<>(); + // need to check if there are deltas, if not then just verify + // components of the base + if (baseCredential == null) { + validations.add(ValidationManager.buildValidationRecord( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + AppraisalStatus.Status.FAIL, + "Base Platform credential missing." + + " Cannot validate attributes", + null, Level.ERROR)); + } else { + if (chkDeltas) { + aes.addAll(basePlatformScv.getCertificatesUsed()); + Iterator it = pcs.iterator(); + while (it.hasNext()) { + PlatformCredential pc = it.next(); + if (pc != null && !pc.isPlatformBase()) { + attributeScv = ValidationManager.evaluateDeltaAttributesStatus( + pc, device.getDeviceInfo(), + baseCredential, deltaMapping, certificateRepository); + if (attributeScv.getValidationResult() == AppraisalStatus.Status.FAIL) { + attrErrorMessage = String.format("%s%s%n", attrErrorMessage, + attributeScv.getMessage()); + } + } + } + } else { + aes.add(baseCredential); + validations.remove(platformScv); + // if there are no deltas, just check base credential + platformScv = ValidationManager.evaluatePCAttributesStatus( + baseCredential, device.getDeviceInfo(), ec, + certificateRepository, componentResultRepository); + validations.add(new SupplyChainValidation( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + platformScv.getValidationResult(), aes, platformScv.getMessage())); + } + } + if (!attrErrorMessage.isEmpty()) { + //combine platform and platform attributes + validations.remove(platformScv); + validations.add(new SupplyChainValidation( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + attributeScv.getValidationResult(), aes, attributeScv.getMessage())); + } + } + + log.info("Beginning Firmware Validation..."); + if (getPolicySettings().isFirmwareValidationEnabled()) { + // may need to associated with device to pull the correct info + // compare tpm quote with what is pulled from RIM associated file + validations.add(ValidationManager.evaluateFirmwareStatus(device, getPolicySettings(), + referenceManifestRepository, referenceDigestValueRepository, + caCredentialRepository)); + } + + log.info("The validation finished, summarizing..."); + // Generate validation summary, save it, and return it. + SupplyChainValidationSummary summary + = new SupplyChainValidationSummary(device, validations); + try { + supplyChainValidationSummaryRepository.save(summary); + } catch (DBManagerException dbMEx) { + log.error("Failed to save Supply Chain Summary"); + } + + return summary; + } /** * A supplemental method that handles validating just the quote post main validation. @@ -32,11 +261,110 @@ public interface SupplyChainValidationService { * @param device the associated device. * @return True if validation is successful, false otherwise. */ - SupplyChainValidationSummary validateQuote(Device device); + public SupplyChainValidationSummary validateQuote(final Device device) { + SupplyChainValidation quoteScv = null; + SupplyChainValidationSummary summary = null; + Level level = Level.ERROR; + AppraisalStatus fwStatus = new AppraisalStatus(FAIL, + "Unknown exception caught during quote validation."); + SupportReferenceManifest sRim = null; + EventLogMeasurements eventLog = null; + + // check if the policy is enabled + if (getPolicySettings().isFirmwareValidationEnabled()) { + String[] baseline = new String[Integer.SIZE]; + String deviceName = device.getDeviceInfo() + .getNetworkInfo().getHostname(); + + try { + List supportRims = referenceManifestRepository + .getSupportByManufacturerModel( + device.getDeviceInfo().getHardwareInfo().getManufacturer(), + device.getDeviceInfo().getHardwareInfo().getProductName()); + for (SupportReferenceManifest support : supportRims) { + if (support.isBaseSupport()) { + sRim = support; + } + } + eventLog = (EventLogMeasurements) referenceManifestRepository + .findByHexDecHash(sRim.getEventLogHash()); + + if (sRim == null) { + fwStatus = new AppraisalStatus(FAIL, + String.format("Firmware Quote validation failed: " + + "No associated Support RIM file " + + "could be found for %s", + deviceName)); + } else if (eventLog == null) { + fwStatus = new AppraisalStatus(FAIL, + String.format("Firmware Quote validation failed: " + + "No associated Client Log file " + + "could be found for %s", + deviceName)); + } else { + baseline = sRim.getExpectedPCRList(); + String[] storedPcrs = eventLog.getExpectedPCRList(); + PcrValidator pcrValidator = new PcrValidator(baseline); + // grab the quote + byte[] hash = device.getDeviceInfo().getTpmInfo().getTpmQuoteHash(); + if (pcrValidator.validateQuote(hash, storedPcrs, getPolicySettings())) { + level = Level.INFO; + fwStatus = new AppraisalStatus(PASS, + SupplyChainCredentialValidator.FIRMWARE_VALID); + fwStatus.setMessage("Firmware validation of TPM Quote successful."); + } else { + fwStatus.setMessage("Firmware validation of TPM Quote failed." + + "\nPCR hash and Quote hash do not match."); + } + eventLog.setOverallValidationResult(fwStatus.getAppStatus()); + this.referenceManifestRepository.save(eventLog); + } + } catch (Exception ex) { + log.error(ex); + } + + quoteScv = ValidationManager.buildValidationRecord(SupplyChainValidation + .ValidationType.FIRMWARE, + fwStatus.getAppStatus(), fwStatus.getMessage(), eventLog, level); + + // Generate validation summary, save it, and return it. + List validations = new ArrayList<>(); + SupplyChainValidationSummary previous + = this.supplyChainValidationSummaryRepository.findByDevice(deviceName); + for (SupplyChainValidation scv : previous.getValidations()) { + if (scv.getValidationType() != SupplyChainValidation.ValidationType.FIRMWARE) { + validations.add(ValidationManager.buildValidationRecord(scv.getValidationType(), + scv.getValidationResult(), scv.getMessage(), + scv.getCertificatesUsed().get(0), Level.INFO)); + } + } + validations.add(quoteScv); + previous.archive(); + supplyChainValidationSummaryRepository.save(previous); + summary = new SupplyChainValidationSummary(device, validations); + + // try removing the supply chain validation as well and resaving that + try { + supplyChainValidationSummaryRepository.save(summary); + } catch (DBManagerException dbEx) { + log.error("Failed to save Supply Chain Summary", dbEx); + } + } + + return summary; + } /** - * Allows other service access to the policy information. - * @return supply chain policy + * Helper function to get a fresh load of the default policy from the DB. + * + * @return The default Supply Chain Policy */ -// SupplyChainPolicy getPolicy(); + private PolicySettings getPolicySettings() { + PolicySettings defaultSettings = this.policyRepository.findByName("Default"); + + if (defaultSettings == null) { + defaultSettings = new PolicySettings("Default", "Settings are configured for no validation flags set."); + } + return defaultSettings; + } } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationServiceImpl.java deleted file mode 100644 index 02c7c7ab..00000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationServiceImpl.java +++ /dev/null @@ -1,377 +0,0 @@ -package hirs.attestationca.persist.service; - -import hirs.attestationca.persist.entity.ArchivableEntity; -import hirs.attestationca.persist.DBManagerException; -import hirs.attestationca.persist.entity.manager.CACredentialRepository; -import hirs.attestationca.persist.entity.manager.CertificateRepository; -import hirs.attestationca.persist.entity.manager.ComponentResultRepository; -import hirs.attestationca.persist.entity.manager.PolicyRepository; -import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository; -import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository; -import hirs.attestationca.persist.entity.manager.SupplyChainValidationSummaryRepository; -import hirs.attestationca.persist.entity.userdefined.Certificate; -import hirs.attestationca.persist.entity.userdefined.Device; -import hirs.attestationca.persist.entity.userdefined.PolicySettings; -import hirs.attestationca.persist.entity.userdefined.SupplyChainValidation; -import hirs.attestationca.persist.entity.userdefined.SupplyChainValidationSummary; -import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential; -import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; -import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; -import hirs.attestationca.persist.entity.userdefined.record.TPMMeasurementRecord; -import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements; -import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest; -import hirs.attestationca.persist.enums.AppraisalStatus; -import hirs.attestationca.persist.validation.CredentialValidator; -import hirs.attestationca.persist.validation.PcrValidator; -import hirs.attestationca.persist.validation.SupplyChainCredentialValidator; -import hirs.utils.BouncyCastleUtils; -import lombok.extern.log4j.Log4j2; -import org.bouncycastle.util.encoders.Hex; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.io.IOException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import org.apache.logging.log4j.Level; - -import static hirs.attestationca.persist.enums.AppraisalStatus.Status.FAIL; -import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS; - -@Log4j2 -@Service -public class SupplyChainValidationServiceImpl implements SupplyChainValidationService { - - private CACredentialRepository caCredentialRepository; - private PolicyRepository policyRepository; - private ReferenceManifestRepository referenceManifestRepository; - private ReferenceDigestValueRepository referenceDigestValueRepository; - private ComponentResultRepository componentResultRepository; - private CertificateRepository certificateRepository; - private CredentialValidator supplyChainCredentialValidator; - private SupplyChainValidationSummaryRepository supplyChainValidationSummaryRepository; - - /** - * Constructor to set just the CertificateRepository, so that cert chain validating - * methods can be called from outside classes. - * - * @param certificateRepository the cert repository - */ - public SupplyChainValidationServiceImpl(final CertificateRepository certificateRepository) { - this.certificateRepository = certificateRepository; - } - - /** - * Constructor. - * - * @param caCredentialRepository ca credential repository - * @param policyRepository the policy manager - * @param certificateRepository the cert manager - * @param componentResultRepository the comp result manager - * @param referenceManifestRepository the RIM manager - * @param supplyChainValidationSummaryRepository the summary manager - * @param supplyChainCredentialValidator the credential validator - * @param referenceDigestValueRepository the even manager - */ - @Autowired - @SuppressWarnings("ParameterNumberCheck") - public SupplyChainValidationServiceImpl( - final CACredentialRepository caCredentialRepository, - final PolicyRepository policyRepository, - final CertificateRepository certificateRepository, - final ComponentResultRepository componentResultRepository, - final ReferenceManifestRepository referenceManifestRepository, - final SupplyChainValidationSummaryRepository supplyChainValidationSummaryRepository, - final CredentialValidator supplyChainCredentialValidator, - final ReferenceDigestValueRepository referenceDigestValueRepository) { - this.caCredentialRepository = caCredentialRepository; - this.policyRepository = policyRepository; - this.certificateRepository = certificateRepository; - this.componentResultRepository = componentResultRepository; - this.referenceManifestRepository = referenceManifestRepository; - this.supplyChainValidationSummaryRepository = supplyChainValidationSummaryRepository; - this.supplyChainCredentialValidator = supplyChainCredentialValidator; - this.referenceDigestValueRepository = referenceDigestValueRepository; - } - - @Override - public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredential ec, - final List pc, - final Device device) { - return null; - } - - /** - * A supplemental method that handles validating just the quote post main validation. - * - * @param device the associated device. - * @return True if validation is successful, false otherwise. - */ - @Override - public SupplyChainValidationSummary validateQuote(final Device device) { - SupplyChainValidation quoteScv = null; - SupplyChainValidationSummary summary = null; - Level level = Level.ERROR; - AppraisalStatus fwStatus = new AppraisalStatus(FAIL, - "Unknown exception caught during quote validation."); - SupportReferenceManifest sRim = null; - EventLogMeasurements eventLog = null; - - // check if the policy is enabled - if (getPolicySettings().isFirmwareValidationEnabled()) { - String[] baseline = new String[Integer.SIZE]; - String deviceName = device.getDeviceInfo() - .getNetworkInfo().getHostname(); - - try { - List supportRims = referenceManifestRepository.getSupportByManufacturerModel( - device.getDeviceInfo().getHardwareInfo().getManufacturer(), - device.getDeviceInfo().getHardwareInfo().getProductName()); - for (SupportReferenceManifest support : supportRims) { - if (support.isBaseSupport()) { - sRim = support; - } - } - eventLog = (EventLogMeasurements) referenceManifestRepository - .findByHexDecHash(sRim.getEventLogHash()); - - if (sRim == null) { - fwStatus = new AppraisalStatus(FAIL, - String.format("Firmware Quote validation failed: " - + "No associated Support RIM file " - + "could be found for %s", - deviceName)); - } else if (eventLog == null) { - fwStatus = new AppraisalStatus(FAIL, - String.format("Firmware Quote validation failed: " - + "No associated Client Log file " - + "could be found for %s", - deviceName)); - } else { - baseline = sRim.getExpectedPCRList(); - String[] storedPcrs = eventLog.getExpectedPCRList(); - PcrValidator pcrValidator = new PcrValidator(baseline); - // grab the quote - byte[] hash = device.getDeviceInfo().getTpmInfo().getTpmQuoteHash(); - if (pcrValidator.validateQuote(hash, storedPcrs, getPolicySettings())) { - level = Level.INFO; - fwStatus = new AppraisalStatus(PASS, - SupplyChainCredentialValidator.FIRMWARE_VALID); - fwStatus.setMessage("Firmware validation of TPM Quote successful."); - } else { - fwStatus.setMessage("Firmware validation of TPM Quote failed." - + "\nPCR hash and Quote hash do not match."); - } - eventLog.setOverallValidationResult(fwStatus.getAppStatus()); - this.referenceManifestRepository.save(eventLog); - } - } catch (Exception ex) { - log.error(ex); - } - - quoteScv = buildValidationRecord(SupplyChainValidation - .ValidationType.FIRMWARE, - fwStatus.getAppStatus(), fwStatus.getMessage(), eventLog, level); - - // Generate validation summary, save it, and return it. - List validations = new ArrayList<>(); - SupplyChainValidationSummary previous - = this.supplyChainValidationSummaryRepository.findByDevice(deviceName); - for (SupplyChainValidation scv : previous.getValidations()) { - if (scv.getValidationType() != SupplyChainValidation.ValidationType.FIRMWARE) { - validations.add(buildValidationRecord(scv.getValidationType(), - scv.getValidationResult(), scv.getMessage(), - scv.getCertificatesUsed().get(0), Level.INFO)); - } - } - validations.add(quoteScv); - previous.archive(); - supplyChainValidationSummaryRepository.save(previous); - summary = new SupplyChainValidationSummary(device, validations); - - // try removing the supply chain validation as well and resaving that - try { - supplyChainValidationSummaryRepository.save(summary); - } catch (DBManagerException dbEx) { - log.error("Failed to save Supply Chain Summary", dbEx); - } - } - - return summary; - } - - /** - * Creates a supply chain validation record and logs the validation message - * at the specified log level. - * - * @param validationType the type of validation - * @param result the appraisal status - * @param message the validation message to include in the summary and log - * @param archivableEntity the archivableEntity associated with the - * validation - * @param logLevel the log level - * @return a SupplyChainValidation - */ - private SupplyChainValidation buildValidationRecord( - final SupplyChainValidation.ValidationType validationType, - final AppraisalStatus.Status result, final String message, - final ArchivableEntity archivableEntity, final Level logLevel) { - List aeList = new ArrayList<>(); - if (archivableEntity != null) { - aeList.add(archivableEntity); - } - - log.log(logLevel, message); - return new SupplyChainValidation(validationType, result, aeList, message); - } - - /** - * This method is used to retrieve the entire CA chain (up to a trusted - * self-signed certificate) for the given certificate. This method will look - * up CA certificates that have a matching issuer organization as the given - * certificate, and will perform that operation recursively until all - * certificates for all relevant organizations have been retrieved. For that - * reason, the returned set of certificates may be larger than the the - * single trust chain for the queried certificate, but is guaranteed to - * include the trust chain if it exists in this class' CertificateManager. - * Returns the certificate authority credentials in a KeyStore. - * - * @param credential the credential whose CA chain should be retrieved - * @return A keystore containing all relevant CA credentials to the given - * certificate's organization or null if the keystore can't be assembled - */ - public KeyStore getCaChain(final Certificate credential) { - KeyStore caKeyStore = null; - try { - caKeyStore = caCertSetToKeystore(getCaChainRec(credential, Collections.emptySet())); - } catch (KeyStoreException | IOException e) { - log.error("Unable to assemble CA keystore", e); - } - return caKeyStore; - } - - /** - * This is a recursive method which is used to retrieve the entire CA chain - * (up to a trusted self-signed certificate) for the given certificate. This - * method will look up CA certificates that have a matching issuer - * organization as the given certificate, and will perform that operation - * recursively until all certificates for all relevant organizations have - * been retrieved. For that reason, the returned set of certificates may be - * larger than the the single trust chain for the queried certificate, but - * is guaranteed to include the trust chain if it exists in this class' - * CertificateManager. - *

- * Implementation notes: 1. Queries for CA certs with a subject org matching - * the given (argument's) issuer org 2. Add that org to - * queriedOrganizations, so we don't search for that organization again 3. - * For each returned CA cert, add that cert to the result set, and recurse - * with that as the argument (to go up the chain), if and only if we haven't - * already queried for that organization (which prevents infinite loops on - * certs with an identical subject and issuer org) - * - * @param credential the credential whose CA chain should be retrieved - * @param previouslyQueriedSubjects a list of organizations to refrain - * from querying - * @return a Set containing all relevant CA credentials to the given - * certificate's organization - */ - private Set getCaChainRec( - final Certificate credential, - final Set previouslyQueriedSubjects) { - CertificateAuthorityCredential skiCA = null; - List certAuthsWithMatchingIssuer = new LinkedList<>(); - if (credential.getAuthorityKeyIdentifier() != null - && !credential.getAuthorityKeyIdentifier().isEmpty()) { - byte[] bytes = Hex.decode(credential.getAuthorityKeyIdentifier()); - // CYRUS is SKI unique? - skiCA = caCredentialRepository.findBySubjectKeyIdentifier(bytes); - } - - if (skiCA == null) { - if (credential.getIssuerSorted() == null - || credential.getIssuerSorted().isEmpty()) { - certAuthsWithMatchingIssuer = caCredentialRepository.findBySubject(credential.getIssuer()); - } else { - //Get certificates by subject organization - certAuthsWithMatchingIssuer = caCredentialRepository.findBySubjectSorted(credential.getIssuerSorted()); - } - } else { - certAuthsWithMatchingIssuer.add(skiCA); - } - Set queriedOrganizations = new HashSet<>(previouslyQueriedSubjects); - queriedOrganizations.add(credential.getIssuer()); - - HashSet caCreds = new HashSet<>(); - for (CertificateAuthorityCredential cred : certAuthsWithMatchingIssuer) { - caCreds.add(cred); - if (!BouncyCastleUtils.x500NameCompare(cred.getIssuer(), - cred.getSubject())) { - caCreds.addAll(getCaChainRec(cred, queriedOrganizations)); - } - } - return caCreds; - } - - private KeyStore caCertSetToKeystore(final Set certs) - throws KeyStoreException, IOException { - KeyStore keyStore = KeyStore.getInstance("JKS"); - try { - keyStore.load(null, "".toCharArray()); - for (Certificate cert : certs) { - keyStore.setCertificateEntry(cert.getId().toString(), cert.getX509Certificate()); - } - } catch (IOException | CertificateException | NoSuchAlgorithmException e) { - throw new IOException("Could not create and populate keystore", e); - } - - return keyStore; - } - - private String[] buildStoredPcrs(final String pcrContent, final int algorithmLength) { - // we have a full set of PCR values - String[] pcrSet = pcrContent.split("\\n"); - String[] storedPcrs = new String[TPMMeasurementRecord.MAX_PCR_ID + 1]; - - // we need to scroll through the entire list until we find - // a matching hash length - int offset = 1; - - for (int i = 0; i < pcrSet.length; i++) { - if (pcrSet[i].contains("sha")) { - // entered a new set, check size - if (pcrSet[i + offset].split(":")[1].trim().length() - == algorithmLength) { - // found the matching set - for (int j = 0; j <= TPMMeasurementRecord.MAX_PCR_ID; j++) { - storedPcrs[j] = pcrSet[++i].split(":")[1].trim(); - } - break; - } - } - } - - return storedPcrs; - } - - /** - * Helper function to get a fresh load of the default policy from the DB. - * - * @return The default Supply Chain Policy - */ - private PolicySettings getPolicySettings() { - PolicySettings defaultSettings = this.policyRepository.findByName("Default"); - - if (defaultSettings == null) { - defaultSettings = new PolicySettings("Default", "Settings are configured for no validation flags set."); - } - return defaultSettings; - } -} diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/PciIds.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/PciIds.java similarity index 99% rename from HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/PciIds.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/PciIds.java index 3623e922..e17fd1e8 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/PciIds.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/PciIds.java @@ -1,4 +1,4 @@ -package hirs.attestationca.portal.page.utils; +package hirs.attestationca.persist.util; import com.github.marandus.pciid.model.Device; import com.github.marandus.pciid.model.Vendor; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java index 7e4638bf..2084cfe9 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java @@ -1,19 +1,86 @@ package hirs.attestationca.persist.validation; -import hirs.attestationca.persist.entity.userdefined.SupplyChainValidation; import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport; import hirs.attestationca.persist.enums.AppraisalStatus; +import lombok.extern.log4j.Log4j2; +import org.bouncycastle.cert.X509AttributeCertificateHolder; +import java.io.IOException; import java.security.KeyStore; -import java.util.Map; +import java.security.KeyStoreException; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.X509Certificate; +import java.util.Date; + +import static hirs.attestationca.persist.enums.AppraisalStatus.Status.ERROR; +import static hirs.attestationca.persist.enums.AppraisalStatus.Status.FAIL; +import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS; + +@Log4j2 +public class CredentialValidator extends SupplyChainCredentialValidator { + + /** + * Checks if the endorsement credential is valid. + * + * @param ec the endorsement credential to verify. + * @param trustStore trust store holding trusted trusted certificates. + * @param acceptExpired whether or not to accept expired and not yet valid certificates + * as valid. + * @return the result of the validation. + */ + public static AppraisalStatus validateEndorsementCredential(final EndorsementCredential ec, + final KeyStore trustStore, + final boolean acceptExpired) { + final String baseErrorMessage = "Can't validate endorsement credential attributes without "; + String message; + if (ec == null) { + message = baseErrorMessage + "an endorsement credential"; + log.error(message); + return new AppraisalStatus(FAIL, message); + } + if (trustStore == null) { + message = baseErrorMessage + "a trust store"; + log.error(message); + return new AppraisalStatus(FAIL, message); + } + + try { + X509Certificate verifiableCert = ec.getX509Certificate(); + + // check validity period, currently acceptExpired will also accept not yet + // valid certificates + if (!acceptExpired) { + verifiableCert.checkValidity(); + } + + if (verifyCertificate(verifiableCert, trustStore)) { + return new AppraisalStatus(PASS, ENDORSEMENT_VALID); + } else { + return new AppraisalStatus(FAIL, "Endorsement credential does not have a valid " + + "signature chain in the trust store"); + } + } catch (IOException e) { + message = "Couldn't retrieve X509 certificate from endorsement credential"; + log.error(message, e); + return new AppraisalStatus(ERROR, message + " " + e.getMessage()); + } catch (SupplyChainValidatorException e) { + message = "An error occurred indicating the credential is not valid"; + log.warn(message, e); + return new AppraisalStatus(ERROR, message + " " + e.getMessage()); + } catch (CertificateExpiredException e) { + message = "The endorsement credential is expired"; + log.warn(message, e); + return new AppraisalStatus(FAIL, message + " " + e.getMessage()); + } catch (CertificateNotYetValidException e) { + message = "The endorsement credential is not yet valid"; + log.warn(message, e); + return new AppraisalStatus(FAIL, message + " " + e.getMessage()); + } + } -/** - * A class used to support supply chain validation by performing the actual - * validation of credentials. - */ -public interface CredentialValidator { /** * Checks if the platform credential is valid. * @@ -22,47 +89,113 @@ public interface CredentialValidator { * @param acceptExpired whether or not to accept expired certificates as valid. * @return The result of the validation. */ - AppraisalStatus validatePlatformCredential(PlatformCredential pc, - KeyStore trustStore, - boolean acceptExpired); + public static AppraisalStatus validatePlatformCredential(final PlatformCredential pc, + final KeyStore trustStore, + 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"; + log.error(message); + return new AppraisalStatus(FAIL, message); + } + try { + if (trustStore == null || trustStore.size() == 0) { + message = baseErrorMessage + "an Issuer Cert in the Trust Store\n"; + log.error(message); + return new AppraisalStatus(FAIL, message); + } + } catch (KeyStoreException e) { + message = baseErrorMessage + "an initialized trust store"; + log.error(message); + return new AppraisalStatus(FAIL, message); + } + + X509AttributeCertificateHolder attributeCert = null; + try { + attributeCert = pc.getX509AttributeCertificateHolder(); + } catch (IOException e) { + message = "Could not retrieve X509 Attribute certificate"; + log.error(message, e); + return new AppraisalStatus(FAIL, message + " " + e.getMessage()); + } + + // check validity period, currently acceptExpired will also accept not yet + // valid certificates + if (!acceptExpired && !pc.isValidOn(new Date())) { + message = "Platform credential has expired"; + // if not valid at the current time + log.warn(message); + return new AppraisalStatus(FAIL, message); + } + + // verify cert against truststore + try { + certVerifyMsg = verifyCertificate(attributeCert, trustStore); + if (certVerifyMsg.isEmpty()) { + message = PLATFORM_VALID; + log.info(message); + return new AppraisalStatus(PASS, message); + } else { + message = String.format("Platform credential failed verification%n%s", + certVerifyMsg); + log.error(message); + return new AppraisalStatus(FAIL, message); + } + } catch (SupplyChainValidatorException scvEx) { + message = "An error occurred indicating the credential is not valid"; + log.warn(message, scvEx); + return new AppraisalStatus(FAIL, message + " " + scvEx.getMessage()); + } + } /** * Checks if the platform credential's attributes are valid. - * @param pc The platform credential to verify. - * @param deviceInfoReport Report containing the serial numbers of the platform to be validated. - * @param ec The endorsement credential supplied from the same identity request as - * the platform credential. - * @return The result of the validation. - */ - AppraisalStatus validatePlatformCredentialAttributes(PlatformCredential pc, - DeviceInfoReport deviceInfoReport, - EndorsementCredential ec); - - /** - * Checks if the delta credential's attributes are valid. - * @param delta the delta credential to verify + * @param platformCredential The platform credential to verify. * @param deviceInfoReport The device info report containing * serial number of the platform to be validated. - * @param base the base credential from the same identity request - * as the delta credential. - * @param deltaMapping delta certificates associated with the - * delta supply validation. - * @return the result of the validation. + * @param endorsementCredential The endorsement credential supplied from the same + * identity request as the platform credential. + * @return The result of the validation. */ - AppraisalStatus validateDeltaPlatformCredentialAttributes(PlatformCredential delta, - DeviceInfoReport deviceInfoReport, - PlatformCredential base, - Map deltaMapping); - /** - * Checks if the endorsement credential is valid. - * - * @param ec the endorsement credential to verify. - * @param trustStore trust store holding trusted trusted certificates. - * @param acceptExpired whether or not to accept expired certificates as valid. - * @return the result of the validation. - */ - AppraisalStatus validateEndorsementCredential(EndorsementCredential ec, - KeyStore trustStore, - boolean acceptExpired); -} + public static AppraisalStatus validatePlatformCredentialAttributes( + final PlatformCredential platformCredential, + final DeviceInfoReport deviceInfoReport, + final EndorsementCredential endorsementCredential) { + final String baseErrorMessage = "Can't validate platform credential attributes without "; + String message; + if (platformCredential == null) { + message = baseErrorMessage + "a platform credential"; + log.error(message); + return new AppraisalStatus(FAIL, message); + } + if (deviceInfoReport == null) { + message = baseErrorMessage + "a device info report"; + log.error(message); + return new AppraisalStatus(FAIL, message); + } + if (endorsementCredential == null) { + message = baseErrorMessage + "an endorsement credential"; + log.error(message); + return new AppraisalStatus(FAIL, message); + } + + // Quick, early check if the platform credential references the endorsement credential + if (!endorsementCredential.getSerialNumber() + .equals(platformCredential.getHolderSerialNumber())) { + message = "Platform Credential holder serial number does not match " + + "the Endorsement Credential's serial number"; + log.error(message); + return new AppraisalStatus(FAIL, message); + } + + String credentialType = platformCredential.getCredentialType(); + if (PlatformCredential.CERTIFICATE_TYPE_2_0.equals(credentialType)) { + return CertificateAttributeScvValidator.validatePlatformCredentialAttributesV2p0( + platformCredential, deviceInfoReport); + } + return CertificateAttributeScvValidator.validatePlatformCredentialAttributesV1p2( + platformCredential, deviceInfoReport); + } +} \ No newline at end of file diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/PcrValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/PcrValidator.java index 9e8b738c..568ebe72 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/PcrValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/PcrValidator.java @@ -226,4 +226,30 @@ public class PcrValidator { return validated; } + + public static String[] buildStoredPcrs(final String pcrContent, final int algorithmLength) { + // we have a full set of PCR values + String[] pcrSet = pcrContent.split("\\n"); + String[] storedPcrs = new String[TPMMeasurementRecord.MAX_PCR_ID + 1]; + + // we need to scroll through the entire list until we find + // a matching hash length + int offset = 1; + + for (int i = 0; i < pcrSet.length; i++) { + if (pcrSet[i].contains("sha")) { + // entered a new set, check size + if (pcrSet[i + offset].split(":")[1].trim().length() + == algorithmLength) { + // found the matching set + for (int j = 0; j <= TPMMeasurementRecord.MAX_PCR_ID; j++) { + storedPcrs[j] = pcrSet[++i].split(":")[1].trim(); + } + break; + } + } + } + + return storedPcrs; + } } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java index 70aaec2c..bcdc9d92 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java @@ -1,23 +1,50 @@ package hirs.attestationca.persist.validation; -import hirs.attestationca.persist.entity.userdefined.SupplyChainValidation; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult; -import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; -import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; -import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport; -import hirs.attestationca.persist.enums.AppraisalStatus; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2; +import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo; import lombok.NoArgsConstructor; import lombok.extern.log4j.Log4j2; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.util.Strings; +import org.bouncycastle.asn1.DERUTF8String; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.cert.CertException; +import org.bouncycastle.cert.X509AttributeCertificateHolder; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.ContentVerifierProvider; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; +import javax.security.auth.x500.X500Principal; +import java.io.IOException; +import java.security.InvalidKeyException; import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PublicKey; +import java.security.Security; +import java.security.SignatureException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.Map; +import java.util.Set; @Log4j2 @NoArgsConstructor -public class SupplyChainCredentialValidator implements CredentialValidator { +public class SupplyChainCredentialValidator { + public static final int NUC_VARIABLE_BIT = 159; /** * AppraisalStatus message for a valid endorsement credential appraisal. */ @@ -39,34 +66,447 @@ public class SupplyChainCredentialValidator implements CredentialValidator { */ public static final String FIRMWARE_VALID = "Firmware validated"; - private static List componentResultList = new LinkedList<>(); + /** + * Ensure that BouncyCastle is configured as a javax.security.Security provider, as this + * class expects it to be available. + */ + static { + Security.addProvider(new BouncyCastleProvider()); + } - @Override - public AppraisalStatus validatePlatformCredential(final PlatformCredential pc, - final KeyStore trustStore, - final boolean acceptExpired) { + /** + * Attempts to check if the certificate is validated by certificates in a cert chain. The cert + * chain is expected to be stored in a non-ordered KeyStore (trust store). If the signing + * certificate for the target cert is found, but it is an intermediate cert, the validation will + * continue to try to find the signing cert of the intermediate cert. It will continue searching + * until it follows the chain up to a root (self-signed) cert. + * + * @param cert + * certificate to validate + * @param trustStore + * trust store holding trusted root certificates and intermediate certificates + * @return the certificate chain if validation is successful + * @throws SupplyChainValidatorException + * if the verification is not successful + */ + public static String verifyCertificate(final X509AttributeCertificateHolder cert, + final KeyStore trustStore) throws SupplyChainValidatorException { + try { + if (cert == null || trustStore == null) { + throw new SupplyChainValidatorException("Certificate or trust store is null"); + } else if (trustStore.size() == 0) { + throw new SupplyChainValidatorException("Truststore is empty"); + } + } catch (KeyStoreException e) { + log.error("Error accessing trust store: " + e.getMessage()); + } + + try { + Set trustedCerts = new HashSet<>(); + + Enumeration alias = trustStore.aliases(); + + while (alias.hasMoreElements()) { + trustedCerts.add((X509Certificate) trustStore.getCertificate(alias.nextElement())); + } + + String certChainValidated = validateCertChain(cert, trustedCerts); + if (!certChainValidated.isEmpty()) { + log.error("Cert chain could not be validated"); + } + return certChainValidated; + } catch (KeyStoreException e) { + throw new SupplyChainValidatorException("Error with the trust store", e); + } + } + + /** + * Attempts to check if the certificate is validated by certificates in a cert chain. The cert + * chain is expected to be stored in a non-ordered KeyStore (trust store). If the signing + * certificate for the target cert is found, but it is an intermediate cert, the validation will + * continue to try to find the signing cert of the intermediate cert. It will continue searching + * until it follows the chain up to a root (self-signed) cert. + * + * @param cert + * certificate to validate + * @param trustStore + * trust store holding trusted root certificates and intermediate certificates + * @return the certificate chain if validation is successful + * @throws SupplyChainValidatorException + * if the verification is not successful + */ + public static boolean verifyCertificate(final X509Certificate cert, + final KeyStore trustStore) throws SupplyChainValidatorException { + try { + if (cert == null || trustStore == null) { + throw new SupplyChainValidatorException("Certificate or trust store is null"); + } else if (trustStore.size() == 0) { + throw new SupplyChainValidatorException("Truststore is empty"); + } + } catch (KeyStoreException e) { + log.error("Error accessing trust store: " + e.getMessage()); + } + + try { + Set trustedCerts = new HashSet<>(); + Enumeration alias = trustStore.aliases(); + + while (alias.hasMoreElements()) { + trustedCerts.add((X509Certificate) trustStore.getCertificate(alias.nextElement())); + } + + return validateCertChain(cert, trustedCerts).isEmpty(); + } catch (KeyStoreException e) { + log.error("Error accessing keystore", e); + throw new SupplyChainValidatorException("Error with the trust store", e); + } + } + + /** + * Attempts to check if an attribute certificate is validated by certificates in a cert chain. + * The cert chain is represented as a Set of X509Certificates. If the signing certificate for + * the target cert is found, but it is an intermediate cert, the validation will continue to try + * to find the signing cert of the intermediate cert. It will continue searching until it + * follows the chain up to a root (self-signed) cert. + * + * @param cert + * certificate to validate + * @param additionalCerts + * Set of certs to validate against + * @return String status of the cert chain validation - + * blank if successful, error message otherwise + * @throws SupplyChainValidatorException tried to validate using null certificates + */ + 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"); + } + final String intCAError = "Intermediate signing cert found, check for CA cert"; + String foundRootOfCertChain = ""; + X509Certificate nextInChain = null; + + do { + for (X509Certificate trustedCert : additionalCerts) { + boolean issuerMatchesSubject = false; + boolean signatureMatchesPublicKey = false; + if (nextInChain != null) { + issuerMatchesSubject = issuerMatchesSubjectDN(nextInChain, trustedCert); + signatureMatchesPublicKey = signatureMatchesPublicKey(nextInChain, + trustedCert); + } else { + issuerMatchesSubject = issuerMatchesSubjectDN(cert, trustedCert); + signatureMatchesPublicKey = signatureMatchesPublicKey(cert, trustedCert); + } + + if (issuerMatchesSubject && signatureMatchesPublicKey) { + if (isSelfSigned(trustedCert)) { + log.info("CA Root found."); + return ""; + } else { + foundRootOfCertChain = intCAError; + nextInChain = trustedCert; + break; + } + } else { + if (!issuerMatchesSubject) { + foundRootOfCertChain = "Issuer DN does not match Subject DN"; + } + if (!signatureMatchesPublicKey) { + foundRootOfCertChain = "Certificate signature failed to verify"; + } + } + } + } while (foundRootOfCertChain.equals(intCAError)); + + log.error(foundRootOfCertChain); + return foundRootOfCertChain; + } + + /** + * Attempts to check if a public-key certificate is validated by certificates in a cert chain. + * The cert chain is represented as a Set of X509Certificates. If the signing certificate for + * the target cert is found, but it is an intermediate cert, the validation will continue to try + * to find the signing cert of the intermediate cert. It will continue searching until it + * follows the chain up to a root (self-signed) cert. + * + * @param cert + * certificate to validate + * @param additionalCerts + * Set of certs to validate against + * @return String status of the cert chain validation - + * blank if successful, error message otherwise + * @throws SupplyChainValidatorException tried to validate using null certificates + */ + 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"); + } + final String intCAError = "Intermediate signing cert found, check for CA cert"; + String foundRootOfCertChain = ""; + X509Certificate startOfChain = cert; + + do { + for (X509Certificate trustedCert : additionalCerts) { + boolean issuerMatchesSubject = issuerMatchesSubjectDN(startOfChain, trustedCert); + boolean signatureMatchesPublicKey = signatureMatchesPublicKey(startOfChain, + trustedCert); + if (issuerMatchesSubject && signatureMatchesPublicKey) { + if (isSelfSigned(trustedCert)) { + log.info("CA Root found."); + return ""; + } else { + foundRootOfCertChain = intCAError; + startOfChain = trustedCert; + break; + } + } else { + if (!issuerMatchesSubject) { + foundRootOfCertChain = "Issuer DN does not match Subject DN"; + } + if (!signatureMatchesPublicKey) { + foundRootOfCertChain = "Certificate signature failed to verify"; + } + } + } + } while (foundRootOfCertChain.equals(intCAError)); + + log.warn(foundRootOfCertChain); + return foundRootOfCertChain; + } + + /** + * Parses the output from PACCOR's allcomponents.sh script into ComponentInfo objects. + * @param paccorOutput the output from PACCOR's allcomoponents.sh + * @return a list of ComponentInfo objects built from paccorOutput + * @throws java.io.IOException if something goes wrong parsing the JSON + */ + public static List getComponentInfoFromPaccorOutput(final String paccorOutput) + throws IOException { + List componentInfoList = new ArrayList<>(); + + if (StringUtils.isNotEmpty(paccorOutput)) { + ObjectMapper objectMapper = new ObjectMapper(new JsonFactory()); + JsonNode rootNode = objectMapper.readTree(paccorOutput); + Iterator jsonComponentNodes + = rootNode.findValue("COMPONENTS").elements(); + while (jsonComponentNodes.hasNext()) { + JsonNode next = jsonComponentNodes.next(); + componentInfoList.add(new ComponentInfo( + getJSONNodeValueAsText(next, "MANUFACTURER"), + getJSONNodeValueAsText(next, "MODEL"), + getJSONNodeValueAsText(next, "SERIAL"), + getJSONNodeValueAsText(next, "REVISION"))); + } + } + + return componentInfoList; + } + + /** + * Parses the output from PACCOR's allcomponents.sh script into ComponentInfo objects. + * @param paccorOutput the output from PACCOR's allcomoponents.sh + * @return a list of ComponentInfo objects built from paccorOutput + * @throws IOException if something goes wrong parsing the JSON + */ + public static List getV2PaccorOutput( + final String paccorOutput) throws IOException { + List ciList = new LinkedList<>(); + String manufacturer, model, serial, revision; + String componentClass = Strings.EMPTY; + + if (StringUtils.isNotEmpty(paccorOutput)) { + ObjectMapper objectMapper = new ObjectMapper(new JsonFactory()); + JsonNode rootNode = objectMapper.readTree(paccorOutput); + Iterator jsonComponentNodes + = rootNode.findValue("COMPONENTS").elements(); + while (jsonComponentNodes.hasNext()) { + JsonNode next = jsonComponentNodes.next(); + manufacturer = getJSONNodeValueAsText(next, "MANUFACTURER"); + model = getJSONNodeValueAsText(next, "MODEL"); + serial = getJSONNodeValueAsText(next, "SERIAL"); + revision = getJSONNodeValueAsText(next, "REVISION"); + List compClassNodes = next.findValues("COMPONENTCLASS"); + + for (JsonNode subNode : compClassNodes) { + componentClass = getJSONNodeValueAsText(subNode, + "COMPONENTCLASSVALUE"); + } + ciList.add(new ComponentInfo(manufacturer, model, + serial, revision, componentClass)); + } + } + + return ciList; + } + + private static String getJSONNodeValueAsText(final JsonNode node, final String fieldName) { + if (node.hasNonNull(fieldName)) { + return node.findValue(fieldName).asText(); + } return null; } - @Override - public AppraisalStatus validatePlatformCredentialAttributes(final PlatformCredential pc, - final DeviceInfoReport deviceInfoReport, - final EndorsementCredential ec) { - return null; + /** + * Checks if the issuer info of an attribute cert matches the supposed signing cert's + * distinguished name. + * + * @param cert + * the attribute certificate with the signature to validate + * @param signingCert + * the certificate with the public key to validate + * @return boolean indicating if the names + * @throws SupplyChainValidatorException tried to validate using null certificates + */ + public static boolean issuerMatchesSubjectDN(final X509AttributeCertificateHolder cert, + final X509Certificate signingCert) throws SupplyChainValidatorException { + if (cert == null || signingCert == null) { + throw new SupplyChainValidatorException("Certificate or signing certificate is null"); + } + String signingCertSubjectDN = signingCert.getSubjectX500Principal().getName(); + X500Name namedSubjectDN = new X500Name(signingCertSubjectDN); + + X500Name issuerDN = cert.getIssuer().getNames()[0]; + + // equality check ignore DN component ordering + return issuerDN.equals(namedSubjectDN); } - @Override - public AppraisalStatus validateDeltaPlatformCredentialAttributes(final PlatformCredential delta, - final DeviceInfoReport deviceInfoReport, - final PlatformCredential base, - final Map deltaMapping) { - return null; + /** + * Checks if the issuer info of a public-key cert matches the supposed signing cert's + * distinguished name. + * + * @param cert + * the public-key certificate with the signature to validate + * @param signingCert + * the certificate with the public key to validate + * @return boolean indicating if the names + * @throws SupplyChainValidatorException tried to validate using null certificates + */ + public static boolean issuerMatchesSubjectDN(final X509Certificate cert, + final X509Certificate signingCert) throws SupplyChainValidatorException { + if (cert == null || signingCert == null) { + throw new SupplyChainValidatorException("Certificate or signing certificate is null"); + } + String signingCertSubjectDN = signingCert.getSubjectX500Principal(). + getName(X500Principal.RFC1779); + X500Name namedSubjectDN = new X500Name(signingCertSubjectDN); + + String certIssuerDN = cert.getIssuerX500Principal().getName(); + X500Name namedIssuerDN = new X500Name(certIssuerDN); + + // equality check ignore DN component ordering + return namedIssuerDN.equals(namedSubjectDN); } - @Override - public AppraisalStatus validateEndorsementCredential(final EndorsementCredential ec, - final KeyStore trustStore, - final boolean acceptExpired) { - return null; + /** + * Checks if the signature of an attribute cert is validated against the signing cert's public + * key. + * + * @param cert + * the public-key certificate with the signature to validate + * @param signingCert + * the certificate with the public key to validate + * @return boolean indicating if the validation passed + * @throws SupplyChainValidatorException tried to validate using null certificates + */ + public static boolean signatureMatchesPublicKey(final X509Certificate cert, + final X509Certificate signingCert) throws SupplyChainValidatorException { + if (cert == null || signingCert == null) { + throw new SupplyChainValidatorException("Certificate or signing certificate is null"); + } + try { + cert.verify(signingCert.getPublicKey(), BouncyCastleProvider.PROVIDER_NAME); + return true; + } catch (InvalidKeyException e) { + log.info("Incorrect key given to validate this cert's signature"); + } catch (CertificateException e) { + log.info("Encoding error while validating this cert's signature"); + } catch (NoSuchAlgorithmException e) { + log.info("Unsupported signature algorithm found during validation"); + } catch (NoSuchProviderException e) { + log.info("Incorrect provider for cert signature validation"); + } catch (SignatureException e) { + log.info(String.format("%s.verify(%s)", cert.getSubjectX500Principal(), + signingCert.getSubjectX500Principal())); + } + return false; + + } + + /** + * Checks if the signature of a public-key cert is validated against the signing cert's public + * key. + * + * @param cert + * the attribute certificate with the signature to validate + * @param signingCert + * the certificate with the public key to validate + * @return boolean indicating if the validation passed + * @throws SupplyChainValidatorException tried to validate using null certificates + */ + public static boolean signatureMatchesPublicKey(final X509AttributeCertificateHolder cert, + final X509Certificate signingCert) throws SupplyChainValidatorException { + if (signingCert == null) { + throw new SupplyChainValidatorException("Signing certificate is null"); + } + return signatureMatchesPublicKey(cert, signingCert.getPublicKey()); + } + + /** + * Checks if an X509 Attribute Certificate is valid directly against a public key. + * + * @param cert + * the attribute certificate with the signature to validate + * @param signingKey + * the key to use to check the attribute cert + * @return boolean indicating if the validation passed + * @throws SupplyChainValidatorException tried to validate using null certificates + */ + public static boolean signatureMatchesPublicKey(final X509AttributeCertificateHolder cert, + final PublicKey signingKey) throws SupplyChainValidatorException { + if (cert == null || signingKey == null) { + throw new SupplyChainValidatorException("Certificate or signing certificate is null"); + } + ContentVerifierProvider contentVerifierProvider; + try { + contentVerifierProvider = + new JcaContentVerifierProviderBuilder().setProvider("BC").build(signingKey); + return cert.isSignatureValid(contentVerifierProvider); + } catch (OperatorCreationException | CertException e) { + log.info("Exception thrown while verifying certificate", e); + log.info(String.format("%s.isSignatureValid(%s)", cert.getSerialNumber(), + signingKey.getFormat())); + return false; + } + } + + /** + * Checks whether given X.509 public-key certificate is self-signed. If the cert can be + * verified using its own public key, that means it was self-signed. + * + * @param cert + * X.509 Certificate + * @return boolean indicating if the cert was self-signed + */ + private static boolean isSelfSigned(final X509Certificate cert) + throws SupplyChainValidatorException { + if (cert == null) { + throw new SupplyChainValidatorException("Certificate is null"); + } + try { + PublicKey key = cert.getPublicKey(); + cert.verify(key); + return true; + } catch (SignatureException | InvalidKeyException e) { + return false; + } catch (CertificateException | NoSuchAlgorithmException | NoSuchProviderException e) { + log.error("Exception occurred while checking if cert is self-signed", e); + return false; + } } } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java index c2947c68..110bbd00 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java @@ -1,6 +1,7 @@ package hirs.attestationca.portal.page.controllers; import hirs.attestationca.persist.DBServiceException; +import hirs.attestationca.persist.entity.manager.CACredentialRepository; import hirs.attestationca.persist.entity.manager.CertificateRepository; import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository; import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository; @@ -10,14 +11,14 @@ import hirs.attestationca.persist.entity.userdefined.rim.BaseReferenceManifest; import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements; import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue; import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest; -import hirs.attestationca.persist.service.SupplyChainValidationServiceImpl; +import hirs.attestationca.persist.service.ValidationManager; import hirs.attestationca.persist.validation.ReferenceManifestValidator; +import hirs.attestationca.persist.validation.SupplyChainCredentialValidator; import hirs.attestationca.persist.validation.SupplyChainValidatorException; import hirs.attestationca.portal.page.Page; import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageMessages; import hirs.attestationca.portal.page.params.ReferenceManifestDetailsPageParams; -import hirs.attestationca.portal.page.utils.SupplyChainCredentialValidator; import hirs.utils.SwidResource; import hirs.utils.tpm.eventlog.TCGEventLog; import hirs.utils.tpm.eventlog.TpmPcrEvent; @@ -52,6 +53,7 @@ public class ReferenceManifestDetailsPageController extends PageController getRimDetailInfo(final UUID uuid, final ReferenceManifestRepository referenceManifestRepository, final ReferenceDigestValueRepository referenceDigestValueRepository, - final CertificateRepository certificateRepository) + final CertificateRepository certificateRepository, + final CACredentialRepository caCertificateRepository) throws IOException, CertificateException, NoSuchAlgorithmException { HashMap data = new HashMap<>(); @@ -146,7 +154,7 @@ public class ReferenceManifestDetailsPageController extends PageController getBaseRimInfo( final BaseReferenceManifest baseRim, final ReferenceManifestRepository referenceManifestRepository, - final CertificateRepository certificateRepository) + final CertificateRepository certificateRepository, + final CACredentialRepository caCertificateRepository) throws IOException, CertificateException, NoSuchAlgorithmException { HashMap data = new HashMap<>(); @@ -288,9 +298,7 @@ public class ReferenceManifestDetailsPageController extends PageController getComponentInfoFromPaccorOutput(final String paccorOutput) - throws IOException { - List componentInfoList = new ArrayList<>(); - - if (StringUtils.isNotEmpty(paccorOutput)) { - ObjectMapper objectMapper = new ObjectMapper(new JsonFactory()); - JsonNode rootNode = objectMapper.readTree(paccorOutput); - Iterator jsonComponentNodes - = rootNode.findValue("COMPONENTS").elements(); - while (jsonComponentNodes.hasNext()) { - JsonNode next = jsonComponentNodes.next(); - componentInfoList.add(new ComponentInfo( - getJSONNodeValueAsText(next, "MANUFACTURER"), - getJSONNodeValueAsText(next, "MODEL"), - getJSONNodeValueAsText(next, "SERIAL"), - getJSONNodeValueAsText(next, "REVISION"))); - } - } - - return componentInfoList; - } - - /** - * Parses the output from PACCOR's allcomponents.sh script into ComponentInfo objects. - * @param paccorOutput the output from PACCOR's allcomoponents.sh - * @return a list of ComponentInfo objects built from paccorOutput - * @throws IOException if something goes wrong parsing the JSON - */ - public static List getV2PaccorOutput( - final String paccorOutput) throws IOException { - List ciList = new LinkedList<>(); - String manufacturer, model, serial, revision; - String componentClass = Strings.EMPTY; - - if (StringUtils.isNotEmpty(paccorOutput)) { - ObjectMapper objectMapper = new ObjectMapper(new JsonFactory()); - JsonNode rootNode = objectMapper.readTree(paccorOutput); - Iterator jsonComponentNodes - = rootNode.findValue("COMPONENTS").elements(); - while (jsonComponentNodes.hasNext()) { - JsonNode next = jsonComponentNodes.next(); - manufacturer = getJSONNodeValueAsText(next, "MANUFACTURER"); - model = getJSONNodeValueAsText(next, "MODEL"); - serial = getJSONNodeValueAsText(next, "SERIAL"); - revision = getJSONNodeValueAsText(next, "REVISION"); - List compClassNodes = next.findValues("COMPONENTCLASS"); - - for (JsonNode subNode : compClassNodes) { - componentClass = getJSONNodeValueAsText(subNode, - "COMPONENTCLASSVALUE"); - } - ciList.add(new ComponentInfo(manufacturer, model, - serial, revision, componentClass)); - } - } - - return ciList; - } - - private static String getJSONNodeValueAsText(final JsonNode node, final String fieldName) { - if (node.hasNonNull(fieldName)) { - return node.findValue(fieldName).asText(); - } - return null; - } - - /** - * Checks if the platform credential is valid. - * - * @param pc The platform credential to verify. - * @param trustStore trust store holding trusted certificates. - * @param acceptExpired whether or not to accept expired certificates as valid. - * @return The result of the validation. - */ - @Override - public AppraisalStatus validatePlatformCredential(final PlatformCredential pc, - final KeyStore trustStore, - 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"; - log.error(message); - return new AppraisalStatus(FAIL, message); - } - try { - if (trustStore == null || trustStore.size() == 0) { - message = baseErrorMessage + "an Issuer Cert in the Trust Store\n"; - log.error(message); - return new AppraisalStatus(FAIL, message); - } - } catch (KeyStoreException e) { - message = baseErrorMessage + "an initialized trust store"; - log.error(message); - return new AppraisalStatus(FAIL, message); - } - - X509AttributeCertificateHolder attributeCert = null; - try { - attributeCert = pc.getX509AttributeCertificateHolder(); - } catch (IOException e) { - message = "Could not retrieve X509 Attribute certificate"; - log.error(message, e); - return new AppraisalStatus(FAIL, message + " " + e.getMessage()); - } - - // check validity period, currently acceptExpired will also accept not yet - // valid certificates - if (!acceptExpired && !pc.isValidOn(new Date())) { - message = "Platform credential has expired"; - // if not valid at the current time - log.warn(message); - return new AppraisalStatus(FAIL, message); - } - - // verify cert against truststore - try { - certVerifyMsg = verifyCertificate(attributeCert, trustStore); - if (certVerifyMsg.isEmpty()) { - message = PLATFORM_VALID; - log.info(message); - return new AppraisalStatus(PASS, message); - } else { - message = String.format("Platform credential failed verification%n%s", - certVerifyMsg); - log.error(message); - return new AppraisalStatus(FAIL, message); - } - } catch (SupplyChainValidatorException scvEx) { - message = "An error occurred indicating the credential is not valid"; - log.warn(message, scvEx); - return new AppraisalStatus(FAIL, message + " " + scvEx.getMessage()); - } - } - - /** - * Checks if the platform credential's attributes are valid. - * @param platformCredential The platform credential to verify. - * @param deviceInfoReport The device info report containing - * serial number of the platform to be validated. - * @param endorsementCredential The endorsement credential supplied from the same - * identity request as the platform credential. - * @return The result of the validation. - */ - @Override - public AppraisalStatus validatePlatformCredentialAttributes( - final PlatformCredential platformCredential, - final DeviceInfoReport deviceInfoReport, - final EndorsementCredential endorsementCredential) { - final String baseErrorMessage = "Can't validate platform credential attributes without "; - String message; - if (platformCredential == null) { - message = baseErrorMessage + "a platform credential"; - log.error(message); - return new AppraisalStatus(FAIL, message); - } - if (deviceInfoReport == null) { - message = baseErrorMessage + "a device info report"; - log.error(message); - return new AppraisalStatus(FAIL, message); - } - if (endorsementCredential == null) { - message = baseErrorMessage + "an endorsement credential"; - log.error(message); - return new AppraisalStatus(FAIL, message); - } - - // Quick, early check if the platform credential references the endorsement credential - if (!endorsementCredential.getSerialNumber() - .equals(platformCredential.getHolderSerialNumber())) { - message = "Platform Credential holder serial number does not match " - + "the Endorsement Credential's serial number"; - log.error(message); - return new AppraisalStatus(FAIL, message); - } - - String credentialType = platformCredential.getCredentialType(); - if (PlatformCredential.CERTIFICATE_TYPE_2_0.equals(credentialType)) { - return validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport); - } - return validatePlatformCredentialAttributesV1p2(platformCredential, deviceInfoReport); - } - - /** - * Checks if the delta credential's attributes are valid. - * @param deltaPlatformCredential the delta credential to verify - * @param deviceInfoReport The device info report containing - * serial number of the platform to be validated. - * @param basePlatformCredential the base credential from the same identity request - * as the delta credential. - * @param deltaMapping delta certificates associated with the - * delta supply validation. - * @return the result of the validation. - */ - @Override - public AppraisalStatus validateDeltaPlatformCredentialAttributes( - final PlatformCredential deltaPlatformCredential, - final DeviceInfoReport deviceInfoReport, - final PlatformCredential basePlatformCredential, - final Map deltaMapping) { - String message; - - // this needs to be a loop for all deltas, link to issue #110 - // check that they don't have the same serial number - for (PlatformCredential pc : deltaMapping.keySet()) { - if (!basePlatformCredential.getPlatformSerial() - .equals(pc.getPlatformSerial())) { - message = String.format("Base and Delta platform serial " - + "numbers do not match (%s != %s)", - pc.getPlatformSerial(), - basePlatformCredential.getPlatformSerial()); - log.error(message); - return new AppraisalStatus(FAIL, message); - } - // none of the deltas should have the serial number of the base - if (!pc.isPlatformBase() && basePlatformCredential.getSerialNumber() - .equals(pc.getSerialNumber())) { - message = String.format("Delta Certificate with same serial number as base. (%s)", - pc.getSerialNumber()); - log.error(message); - return new AppraisalStatus(FAIL, message); - } - } - - // parse out the provided delta and its specific chain. - List origPcComponents - = new LinkedList<>(basePlatformCredential.getComponentIdentifiers()); - - return validateDeltaAttributesChainV2p0(deviceInfoReport, - deltaMapping, origPcComponents); - } - - private static AppraisalStatus validatePlatformCredentialAttributesV1p2( - final PlatformCredential platformCredential, - final DeviceInfoReport deviceInfoReport) { - - // check the device's board serial number, and compare against this - // platform credential's board serial number. - // Retrieve the various device serial numbers. - String credentialBoardSerialNumber = platformCredential.getPlatformSerial(); - String credentialChassisSerialNumber = platformCredential.getChassisSerialNumber(); - - HardwareInfo hardwareInfo = deviceInfoReport.getHardwareInfo(); - String deviceBaseboardSerialNumber = hardwareInfo.getBaseboardSerialNumber(); - String deviceChassisSerialNumber = hardwareInfo.getChassisSerialNumber(); - String deviceSystemSerialNumber = hardwareInfo.getSystemSerialNumber(); - - // log serial numbers that weren't collected. Force "not specified" serial numbers - // to be ignored in below case checks - Map deviceInfoSerialNumbers = new HashMap<>(); - - if (StringUtils.isEmpty(deviceBaseboardSerialNumber) - || DeviceInfoEnums.NOT_SPECIFIED.equalsIgnoreCase(deviceBaseboardSerialNumber)) { - log.error("Failed to retrieve device baseboard serial number"); - deviceBaseboardSerialNumber = null; - } else { - deviceInfoSerialNumbers.put("board serial number", deviceBaseboardSerialNumber); - log.info("Using device board serial number for validation: " - + deviceBaseboardSerialNumber); - } - - if (StringUtils.isEmpty(deviceChassisSerialNumber) - || DeviceInfoEnums.NOT_SPECIFIED.equalsIgnoreCase(deviceChassisSerialNumber)) { - log.error("Failed to retrieve device chassis serial number"); - } else { - deviceInfoSerialNumbers.put("chassis serial number", deviceChassisSerialNumber); - log.info("Using device chassis serial number for validation: " - + deviceChassisSerialNumber); - } - if (StringUtils.isEmpty(deviceSystemSerialNumber) - || DeviceInfoEnums.NOT_SPECIFIED.equalsIgnoreCase(deviceSystemSerialNumber)) { - log.error("Failed to retrieve device system serial number"); - } else { - deviceInfoSerialNumbers.put("system serial number", deviceSystemSerialNumber); - log.info("Using device system serial number for validation: " - + deviceSystemSerialNumber); - } - - AppraisalStatus status; - - // Test 1: If the board serial number or chassis is set on the PC, - // compare with each of the device serial numbers for any match - if (StringUtils.isNotEmpty(credentialBoardSerialNumber) - || StringUtils.isNotEmpty(credentialChassisSerialNumber)) { - status = validatePlatformSerialsWithDeviceSerials(credentialBoardSerialNumber, - credentialChassisSerialNumber, deviceInfoSerialNumbers); - // Test 2: If the board and chassis serial numbers are not set on the PC, - // compare the SHA1 hash of the device baseboard serial number to - // the certificate serial number - } else { - String message; - log.debug("Credential Serial Number was null"); - if (StringUtils.isEmpty(deviceBaseboardSerialNumber)) { - message = "Device Serial Number was null"; - log.error(message); - status = new AppraisalStatus(FAIL, message); - } else { - // Calculate the SHA1 hash of the UTF8 encoded baseboard serial number - BigInteger baseboardSha1 = new BigInteger(1, - DigestUtils.sha1(deviceBaseboardSerialNumber.getBytes(StandardCharsets.UTF_8))); - BigInteger certificateSerialNumber = platformCredential.getSerialNumber(); - - // compare the SHA1 hash of the baseboard serial number to the certificate SN - if (certificateSerialNumber != null - && certificateSerialNumber.equals(baseboardSha1)) { - log.info("Device Baseboard Serial Number matches " - + "the Certificate Serial Number"); - status = new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID); - } else if (certificateSerialNumber != null - && certificateSerialNumber.equals( - baseboardSha1.clearBit(NUC_VARIABLE_BIT))) { - log.info("Warning! The Certificate serial number had the most significant " - + "bit truncated. 159 bits of it matched the device baseboard " - + "serial number."); - status = new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID); - } else { - message = "The SHA1 hash of the Device Baseboard Serial Number " - + deviceBaseboardSerialNumber - + " did not match the Certificate's Serial Number"; - log.error(message); - status = new AppraisalStatus(FAIL, message); - - } - } - } - - return status; - } - - /** - * Validates device info report against the new platform credential. - * @param platformCredential the Platform Credential - * @param deviceInfoReport the Device Info Report - * @return either PASS or FAIL - */ - static AppraisalStatus validatePlatformCredentialAttributesV2p0( - final PlatformCredential platformCredential, - final DeviceInfoReport deviceInfoReport) { - boolean passesValidation = true; - StringBuilder resultMessage = new StringBuilder(); - - HardwareInfo hardwareInfo = deviceInfoReport.getHardwareInfo(); - - boolean fieldValidation; - fieldValidation = requiredPlatformCredentialFieldIsNonEmptyAndMatches( - "PlatformManufacturerStr", - platformCredential.getManufacturer(), - hardwareInfo.getManufacturer()); - - if (!fieldValidation) { - resultMessage.append("Platform manufacturer did not match\n"); - } - - passesValidation &= fieldValidation; - - fieldValidation = requiredPlatformCredentialFieldIsNonEmptyAndMatches( - "PlatformModel", - platformCredential.getModel(), - hardwareInfo.getProductName()); - - if (!fieldValidation) { - resultMessage.append("Platform model did not match\n"); - } - - passesValidation &= fieldValidation; - - fieldValidation = requiredPlatformCredentialFieldIsNonEmptyAndMatches( - "PlatformVersion", - platformCredential.getVersion(), - hardwareInfo.getVersion()); - - if (!fieldValidation) { - resultMessage.append("Platform version did not match\n"); - } - - passesValidation &= fieldValidation; - - // check PlatformSerial against both system-serial-number and baseboard-serial-number - fieldValidation = ( - (optionalPlatformCredentialFieldNullOrMatches( - "PlatformSerial", - platformCredential.getPlatformSerial(), - hardwareInfo.getSystemSerialNumber())) - || (optionalPlatformCredentialFieldNullOrMatches( - "PlatformSerial", - platformCredential.getPlatformSerial(), - hardwareInfo.getBaseboardSerialNumber()))); - - if (!fieldValidation) { - resultMessage.append("Platform serial did not match\n"); - } - - passesValidation &= fieldValidation; - - // Retrieve the list of all components from the Platform Credential - List allPcComponents - = new ArrayList<>(platformCredential.getComponentIdentifiers()); - - // All components listed in the Platform Credential must have a manufacturer and model - for (ComponentIdentifier pcComponent : allPcComponents) { - fieldValidation = !hasEmptyValueForRequiredField("componentManufacturer", - pcComponent.getComponentManufacturer()); - - if (!fieldValidation) { - resultMessage.append("Component manufacturer is empty\n"); - } - - passesValidation &= fieldValidation; - - fieldValidation = !hasEmptyValueForRequiredField("componentModel", - pcComponent.getComponentModel()); - - if (!fieldValidation) { - resultMessage.append("Component model is empty\n"); - } - - passesValidation &= fieldValidation; - } - - // There is no need to do comparisons with components that are invalid because - // they did not have a manufacturer or model. - List validPcComponents = allPcComponents.stream() - .filter(identifier -> identifier.getComponentManufacturer() != null - && identifier.getComponentModel() != null) - .collect(Collectors.toList()); - - String paccorOutputString = deviceInfoReport.getPaccorOutputString(); - String unmatchedComponents; - try { - List componentInfoList - = getComponentInfoFromPaccorOutput(paccorOutputString); - unmatchedComponents = validateV2p0PlatformCredentialComponentsExpectingExactMatch( - validPcComponents, componentInfoList); - fieldValidation &= unmatchedComponents.isEmpty(); - } catch (IOException e) { - final String baseErrorMessage = "Error parsing JSON output from PACCOR: "; - log.error(baseErrorMessage + e.toString()); - log.error("PACCOR output string:\n" + paccorOutputString); - return new AppraisalStatus(ERROR, baseErrorMessage + e.getMessage()); - } - - StringBuilder additionalInfo = new StringBuilder(); - if (!fieldValidation) { - resultMessage.append("There are unmatched components:\n"); - resultMessage.append(unmatchedComponents); - - // pass information of which ones failed in additionInfo - int counter = 0; - for (ComponentIdentifier ci : validPcComponents) { - counter++; - additionalInfo.append(String.format("%d;", ci.hashCode())); - } - if (counter > 0) { - additionalInfo.insert(0, "COMPID="); - additionalInfo.append(counter); - } - } - - passesValidation &= fieldValidation; - - if (passesValidation) { - return new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID); - } else { - return new AppraisalStatus(FAIL, resultMessage.toString(), additionalInfo.toString()); - } - } - - /** - * The main purpose of this method, the in process of validation, is to - * pick out the changes that lead to the delta cert and make sure the changes - * are valid. - * - * @param deviceInfoReport The paccor profile of device being validated against. - * @param deltaMapping map of delta certificates to their validated status - * @param origPcComponents The component identifier list associated with the - * base cert for this specific chain - * @return Appraisal Status of delta being validated. - */ - @SuppressWarnings("methodlength") - static AppraisalStatus validateDeltaAttributesChainV2p0( - final DeviceInfoReport deviceInfoReport, - final Map deltaMapping, - final List origPcComponents) { - boolean fieldValidation = true; - StringBuilder resultMessage = new StringBuilder(); - String tempStringMessage = ""; - List validOrigPcComponents = origPcComponents.stream() - .filter(identifier -> identifier.getComponentManufacturer() != null - && identifier.getComponentModel() != null) - .collect(Collectors.toList()); - List chainCertificates = new LinkedList<>(deltaMapping.keySet()); - - // map the components throughout the chain - List baseCompList = new LinkedList<>(validOrigPcComponents); - - Collections.sort(chainCertificates, new Comparator() { - @Override - public int compare(final PlatformCredential obj1, - final PlatformCredential obj2) { - if (obj1 == null) { - return 0; - } - if (obj2 == null) { - return 0; - } - if (obj1.getBeginValidity() == null || obj2.getBeginValidity() == null) { - return 0; - } - return obj1.getBeginValidity().compareTo(obj2.getBeginValidity()); - } - }); - // start of some changes - resultMessage.append("There are errors with Delta " - + "Component Statuses:\n"); - List leftOverDeltas = new ArrayList<>(); - List absentSerialNum = new ArrayList<>(); - tempStringMessage = validateDeltaChain(deltaMapping, baseCompList, - leftOverDeltas, absentSerialNum, chainCertificates); - - // check if there were any issues - if (!tempStringMessage.isEmpty()) { - resultMessage.append(tempStringMessage); - fieldValidation = false; - } - - // finished up - List certificateList = null; - SupplyChainValidation scv = null; - StringBuilder deltaSb = new StringBuilder(); - - // non-empty serial values - for (ComponentIdentifier deltaCi : leftOverDeltas) { - String classValue; - ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) deltaCi; - ComponentIdentifierV2 baseCiV2; - boolean classFound; - - for (ComponentIdentifier ci : absentSerialNum) { - classValue = ciV2.getComponentClass().getComponentIdentifier(); - baseCiV2 = (ComponentIdentifierV2) ci; - classFound = classValue.equals(baseCiV2.getComponentClass() - .getComponentIdentifier()); - if (classFound) { - if (isMatch(ciV2, baseCiV2)) { - if (ciV2.isAdded() || ciV2.isModified()) { - // since the base list doesn't have this ci - // just add the delta - baseCompList.add(deltaCi); - break; - } - if (ciV2.isRemoved()) { - baseCompList.remove(ciV2); - break; - } - // if it is a remove - // we do nothing because baseCompList doesn't have it - } else { - // it is an add - if (ciV2.isAdded()) { - baseCompList.add(deltaCi); - } - } - } else { - // delta change to a class not there - if (ciV2.isAdded()) { - baseCompList.add(deltaCi); - } - - if (ciV2.isModified()) { - // error because you can't modify something - // that isn't here - resultMessage.append("MODIFIED attempted without prior instance\n"); - deltaSb.append(String.format("%s;", ci.hashCode())); - } - - if (ciV2.isRemoved()) { - // error because you can't remove something - // that isn't here - resultMessage.append("REMOVED attempted without prior instance\n"); - deltaSb.append(String.format("%s;", ci.hashCode())); - } - } - } - } - - if (!fieldValidation || !deltaSb.toString().isEmpty()) { - deltaSb.insert(0, "COMPID="); - return new AppraisalStatus(FAIL, resultMessage.toString(), deltaSb.toString()); - } - - String paccorOutputString = deviceInfoReport.getPaccorOutputString(); - String unmatchedComponents; - try { - // compare based on component class - List componentInfoList = getV2PaccorOutput(paccorOutputString); - // this is what I want to rewrite - unmatchedComponents = validateV2PlatformCredentialAttributes( - baseCompList, - componentInfoList); - fieldValidation &= unmatchedComponents.isEmpty(); - } catch (IOException ioEx) { - final String baseErrorMessage = "Error parsing JSON output from PACCOR: "; - log.error(baseErrorMessage + ioEx.toString()); - log.error("PACCOR output string:\n" + paccorOutputString); - return new AppraisalStatus(ERROR, baseErrorMessage + ioEx.getMessage()); - } - StringBuilder additionalInfo = new StringBuilder(); - if (!fieldValidation) { - resultMessage = new StringBuilder(); - resultMessage.append("There are unmatched components:\n"); - resultMessage.append(unmatchedComponents); - - // pass information of which ones failed in additionInfo - int counter = 0; - for (ComponentIdentifier ci : baseCompList) { - counter++; - additionalInfo.append(String.format("%d;", ci.hashCode())); - } - if (counter > 0) { - additionalInfo.insert(0, "COMPID="); - additionalInfo.append(counter); - } - } - - if (fieldValidation) { - return new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID); - } else { - return new AppraisalStatus(FAIL, resultMessage.toString(), additionalInfo.toString()); - } - } - - private static String validateV2PlatformCredentialAttributes( - final List fullDeltaChainComponents, - final List allDeviceInfoComponents) { - ComponentIdentifierV2 ciV2; - StringBuilder invalidPcIds = new StringBuilder(); - List subCompIdList = fullDeltaChainComponents - .stream().collect(Collectors.toList()); - List subCompInfoList = allDeviceInfoComponents - .stream().collect(Collectors.toList()); - - // Delta is the baseline - for (ComponentInfo cInfo : allDeviceInfoComponents) { - for (ComponentIdentifier cId : fullDeltaChainComponents) { - ciV2 = (ComponentIdentifierV2) cId; - if (cInfo.getComponentClass().contains( - ciV2.getComponentClass().getComponentIdentifier()) - && isMatch(cId, cInfo)) { - subCompIdList.remove(cId); - subCompInfoList.remove(cInfo); - } - } - } - - if (subCompIdList.isEmpty()) { - return Strings.EMPTY; - } else { - // now we return everything that was unmatched - // what is in the component info/device reported components - // is to be displayed as the failure - fullDeltaChainComponents.clear(); - for (ComponentIdentifier ci : subCompIdList) { - if (ci.isVersion2() && PciIds.DB.isReady()) { - ci = PciIds.translate((ComponentIdentifierV2) ci); - } - log.error("Unmatched component: " + ci); - fullDeltaChainComponents.add(ci); - invalidPcIds.append(String.format( - "Manufacturer=%s, Model=%s, Serial=%s, Revision=%s;%n", - ci.getComponentManufacturer(), - ci.getComponentModel(), - ci.getComponentSerial(), - ci.getComponentRevision())); - } - } - - return invalidPcIds.toString(); - } - - /** - * Compares the component information from the device info report against those of the - * platform credential. All components in the platform credential should exactly match one - * component in the device info report. The device info report is allowed to have extra - * components not represented in the platform credential. - * - * @param untrimmedPcComponents the platform credential components (may contain end whitespace) - * **NEW** this is updated with just the unmatched components - * if there are any failures, otherwise it remains unchanged. - * @param allDeviceInfoComponents the device info report components - * @return true if validation passes - */ - private static String validateV2p0PlatformCredentialComponentsExpectingExactMatch( - final List untrimmedPcComponents, - final List allDeviceInfoComponents) { - // For each manufacturer listed in the platform credential, create two lists: - // 1. a list of components listed in the platform credential for the manufacturer, and - // 2. a list of components listed in the device info for the same manufacturer - // Then eliminate matches from both lists. Finally, decide if the validation passes based - // on the leftovers in the lists and the policy in place. - final List pcComponents = new ArrayList<>(); - for (ComponentIdentifier component : untrimmedPcComponents) { - if (component.getComponentManufacturer() != null) { - component.setComponentManufacturer(new DERUTF8String( - component.getComponentManufacturer().getString().trim())); - } - if (component.getComponentModel() != null) { - component.setComponentModel(new DERUTF8String( - component.getComponentModel().getString().trim())); - } - if (component.getComponentSerial() != null) { - component.setComponentSerial(new DERUTF8String( - component.getComponentSerial().getString().trim())); - } - if (component.getComponentRevision() != null) { - component.setComponentRevision(new DERUTF8String( - component.getComponentRevision().getString().trim())); - } - pcComponents.add(component); - } - - log.info("Validating the following Platform Cert components..."); - pcComponents.forEach(component -> log.info(component.toString())); - log.info("...against the the following DeviceInfoReport components:"); - allDeviceInfoComponents.forEach(component -> log.info(component.toString())); - Set manufacturerSet = new HashSet<>(); - pcComponents.forEach(pcComp -> manufacturerSet.add(pcComp.getComponentManufacturer())); - - // Create a list for unmatched components across all manufacturers to display at the end. - List pcUnmatchedComponents = new ArrayList<>(); - - for (DERUTF8String derUtf8Manufacturer : manufacturerSet) { - List pcComponentsFromManufacturer - = pcComponents.stream().filter(compIdentifier - -> compIdentifier.getComponentManufacturer().equals(derUtf8Manufacturer)) - .collect(Collectors.toList()); - - String pcManufacturer = derUtf8Manufacturer.getString(); - List deviceInfoComponentsFromManufacturer - = allDeviceInfoComponents.stream().filter(componentInfo - -> componentInfo.getComponentManufacturer().equals(pcManufacturer)) - .collect(Collectors.toList()); - // For each component listed in the platform credential from this manufacturer - // find the ones that specify a serial number so we can match the most specific ones - // first. - List pcComponentsFromManufacturerWithSerialNumber - = pcComponentsFromManufacturer.stream().filter(compIdentifier - -> compIdentifier.getComponentSerial() != null - && StringUtils.isNotEmpty(compIdentifier.getComponentSerial().getString())) - .collect(Collectors.toList()); - // Now match up the components from the device info that are from the same - // manufacturer and have a serial number. As matches are found, remove them from - // both lists. - for (ComponentIdentifier pcComponent - : pcComponentsFromManufacturerWithSerialNumber) { - Optional first - = deviceInfoComponentsFromManufacturer.stream() - .filter(componentInfo - -> StringUtils.isNotEmpty(componentInfo.getComponentSerial())) - .filter(componentInfo -> componentInfo.getComponentSerial() - .equals(pcComponent.getComponentSerial().getString())).findFirst(); - - if (first.isPresent()) { - ComponentInfo potentialMatch = first.get(); - if (isMatch(pcComponent, potentialMatch)) { - pcComponentsFromManufacturer.remove(pcComponent); - deviceInfoComponentsFromManufacturer.remove(potentialMatch); - } - } - } - // For each component listed in the platform credential from this manufacturer - // find the ones that specify value for the revision field so we can match the most - // specific ones first. - List pcComponentsFromManufacturerWithRevision - = pcComponentsFromManufacturer.stream().filter(compIdentifier - -> compIdentifier.getComponentRevision() != null - && StringUtils.isNotEmpty(compIdentifier.getComponentRevision().getString())) - .collect(Collectors.toList()); - // Now match up the components from the device info that are from the same - // manufacturer and specify a value for the revision field. As matches are found, - // remove them from both lists. - for (ComponentIdentifier pcComponent - : pcComponentsFromManufacturerWithRevision) { - Optional first - = deviceInfoComponentsFromManufacturer.stream() - .filter(info -> StringUtils.isNotEmpty(info.getComponentRevision())) - .filter(info -> info.getComponentRevision() - .equals(pcComponent.getComponentRevision().getString())) - .findFirst(); - - if (first.isPresent()) { - ComponentInfo potentialMatch = first.get(); - if (isMatch(pcComponent, potentialMatch)) { - pcComponentsFromManufacturer.remove(pcComponent); - deviceInfoComponentsFromManufacturer.remove(potentialMatch); - } - } - } - // The remaining components from the manufacturer have only the 2 required fields so - // just match them. - List templist = new ArrayList<>(pcComponentsFromManufacturer); - for (ComponentIdentifier ci : templist) { - Iterator diComponentIter - = deviceInfoComponentsFromManufacturer.iterator(); - while (diComponentIter.hasNext()) { - ComponentInfo potentialMatch = diComponentIter.next(); - if (isMatch(ci, potentialMatch)) { - pcComponentsFromManufacturer.remove(ci); - diComponentIter.remove(); - } - } - } - pcUnmatchedComponents.addAll(pcComponentsFromManufacturer); - } - - if (!pcUnmatchedComponents.isEmpty()) { - untrimmedPcComponents.clear(); - StringBuilder sb = new StringBuilder(); - log.error(String.format("Platform Credential contained %d unmatched components:", - pcUnmatchedComponents.size())); - - int unmatchedComponentCounter = 1; - for (ComponentIdentifier unmatchedComponent : pcUnmatchedComponents) { - if (unmatchedComponent.isVersion2() && PciIds.DB.isReady()) { - unmatchedComponent = - PciIds.translate((ComponentIdentifierV2) unmatchedComponent); - } - log.error("Unmatched component " + unmatchedComponentCounter++ + ": " - + unmatchedComponent); - sb.append(String.format("Manufacturer=%s, Model=%s, Serial=%s, Revision=%s;%n", - unmatchedComponent.getComponentManufacturer(), - unmatchedComponent.getComponentModel(), - unmatchedComponent.getComponentSerial(), - unmatchedComponent.getComponentRevision())); - unmatchedComponent.setValidationResult(false); - untrimmedPcComponents.add(unmatchedComponent); - } - return sb.toString(); - } - return Strings.EMPTY; - } - - /** - * Returns true if fieldValue is null or empty. - * @param description description of the value - * @param fieldValue value of the field - * @return true if fieldValue is null or empty; false otherwise - */ - private static boolean hasEmptyValueForRequiredField(final String description, - final String fieldValue) { - if (StringUtils.isEmpty(fieldValue)) { - log.error("Required field was empty or null in Platform Credential: " - + description); - return true; - } - return false; - } - - /** - * Returns true if fieldValue is null or empty. - * @param description description of the value - * @param fieldValue value of the field - * @return true if fieldValue is null or empty; false otherwise - */ - private static boolean hasEmptyValueForRequiredField(final String description, - final DERUTF8String fieldValue) { - if (fieldValue == null || StringUtils.isEmpty(fieldValue.getString().trim())) { - log.error("Required field was empty or null in Platform Credential: " - + description); - return true; - } - return false; - } - - /** - * Validates the information supplied for the Platform Credential. This - * method checks if the field is required and therefore if the value is - * present then verifies that the values match. - * @param platformCredentialFieldName name of field to be compared - * @param platformCredentialFieldValue first value to compare - * @param otherValue second value to compare - * @return true if values match - */ - private static boolean requiredPlatformCredentialFieldIsNonEmptyAndMatches( - final String platformCredentialFieldName, - final String platformCredentialFieldValue, - final String otherValue) { - if (hasEmptyValueForRequiredField(platformCredentialFieldName, - platformCredentialFieldValue)) { - return false; - } - - return platformCredentialFieldMatches(platformCredentialFieldName, - platformCredentialFieldValue, otherValue); - } - - /** - * Validates the information supplied for the Platform Credential. This - * method checks if the value is present then verifies that the values match. - * If not present, then returns true. - * @param platformCredentialFieldName name of field to be compared - * @param platformCredentialFieldValue first value to compare - * @param otherValue second value to compare - * @return true if values match or null - */ - private static boolean optionalPlatformCredentialFieldNullOrMatches( - final String platformCredentialFieldName, - final String platformCredentialFieldValue, - final String otherValue) { - if (platformCredentialFieldValue == null) { - return true; - } - - return platformCredentialFieldMatches(platformCredentialFieldName, - platformCredentialFieldValue, otherValue); - } - - private static boolean platformCredentialFieldMatches( - final String platformCredentialFieldName, - final String platformCredentialFieldValue, - final String otherValue) { - String trimmedFieldValue = platformCredentialFieldValue.trim(); - String trimmedOtherValue = otherValue.trim(); - - if (!trimmedFieldValue.equals(trimmedOtherValue)) { - log.debug(String.format("%s field in Platform Credential (%s) does not match " - + "a related field in the DeviceInfoReport (%s)", - platformCredentialFieldName, trimmedFieldValue, trimmedOtherValue)); - return false; - } - - log.debug(String.format("%s field in Platform Credential matches " - + "a related field in the DeviceInfoReport (%s)", - platformCredentialFieldName, trimmedFieldValue) - ); - - return true; - } - - /** - * Checks if the fields in the potentialMatch match the fields in the pcComponent, - * or if the relevant field in the pcComponent is empty. - * @param pcComponent the platform credential component - * @param potentialMatch the component info from a device info report - * @return true if the fields match exactly (null is considered the same as an empty string) - */ - static boolean isMatch(final ComponentIdentifier pcComponent, - final ComponentInfo potentialMatch) { - boolean matchesSoFar = true; - - matchesSoFar &= isMatchOrEmptyInPlatformCert( - potentialMatch.getComponentManufacturer(), - pcComponent.getComponentManufacturer() - ); - - matchesSoFar &= isMatchOrEmptyInPlatformCert( - potentialMatch.getComponentModel(), - pcComponent.getComponentModel() - ); - - matchesSoFar &= isMatchOrEmptyInPlatformCert( - potentialMatch.getComponentSerial(), - pcComponent.getComponentSerial() - ); - - matchesSoFar &= isMatchOrEmptyInPlatformCert( - potentialMatch.getComponentRevision(), - pcComponent.getComponentRevision() - ); - - return matchesSoFar; - } - - /** - * Checks if the fields in the potentialMatch match the fields in the pcComponent, - * or if the relevant field in the pcComponent is empty. - * @param pcComponent the platform credential component - * @param potentialMatch the component info from a device info report - * @return true if the fields match exactly (null is considered the same as an empty string) - */ - static boolean isMatch(final ComponentIdentifierV2 pcComponent, - final ComponentIdentifierV2 potentialMatch) { - boolean matchesSoFar = true; - - matchesSoFar &= isMatchOrEmptyInPlatformCert( - potentialMatch.getComponentManufacturer(), - pcComponent.getComponentManufacturer()); - - matchesSoFar &= isMatchOrEmptyInPlatformCert( - potentialMatch.getComponentModel(), - pcComponent.getComponentModel()); - - return matchesSoFar; - } - - private static boolean isMatchOrEmptyInPlatformCert( - final String evidenceFromDevice, - final DERUTF8String valueInPlatformCert) { - if (valueInPlatformCert == null || StringUtils.isEmpty(valueInPlatformCert.getString())) { - return true; - } - return valueInPlatformCert.getString().equals(evidenceFromDevice); - } - - private static boolean isMatchOrEmptyInPlatformCert( - final DERUTF8String evidenceFromDevice, - final DERUTF8String valueInPlatformCert) { - return evidenceFromDevice.equals(valueInPlatformCert); - } - - /** - * Validates the platform credential's serial numbers with the device info's set of - * serial numbers. - * @param credentialBoardSerialNumber the PC board S/N - * @param credentialChassisSerialNumber the PC chassis S/N - * @param deviceInfoSerialNumbers the map of device info serial numbers with descriptions. - * @return the changed validation status - */ - private static AppraisalStatus validatePlatformSerialsWithDeviceSerials( - final String credentialBoardSerialNumber, final String credentialChassisSerialNumber, - final Map deviceInfoSerialNumbers) { - boolean boardSerialNumberFound = false; - boolean chassisSerialNumberFound = false; - - if (StringUtils.isNotEmpty(credentialBoardSerialNumber)) { - boardSerialNumberFound = deviceInfoContainsPlatformSerialNumber( - credentialBoardSerialNumber, "board serial number", deviceInfoSerialNumbers); - } - if (StringUtils.isNotEmpty(credentialChassisSerialNumber)) { - chassisSerialNumberFound = deviceInfoContainsPlatformSerialNumber( - credentialChassisSerialNumber, - "chassis serial number", deviceInfoSerialNumbers); - } - - if (boardSerialNumberFound || chassisSerialNumberFound) { - log.info("The platform credential's board or chassis serial number matched" - + " with a serial number from the client's device information"); - return new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID); - } - log.error("The platform credential's board and chassis serial numbers did" - + " not match with any device info's serial numbers"); - - return new AppraisalStatus(FAIL, "Platform serial did not match device info"); - } - - - /** - * Checks if a platform credential's serial number matches ANY of the device information's - * set of serial numbers. - * @param platformSerialNumber the platform serial number to compare - * @param platformSerialNumberDescription description of the serial number for logging purposes. - * @param deviceInfoSerialNumbers the map of device info serial numbers - * (key = description, value = serial number) - * @return true if the platform serial number was found (case insensitive search), - * false otherwise - */ - private static boolean deviceInfoContainsPlatformSerialNumber( - final String platformSerialNumber, final String platformSerialNumberDescription, - final Map deviceInfoSerialNumbers) { - // check to see if the platform serial number is contained in the map of device info's - // serial numbers - for (Map.Entry entry : deviceInfoSerialNumbers.entrySet()) { - if (entry.getValue().equalsIgnoreCase(platformSerialNumber)) { - log.info("Device info contained platform {} {}" - + " in the device info's {}", platformSerialNumberDescription, - platformSerialNumber, entry.getKey()); - return true; - } - } - - log.warn("Platform {}, {}, did not match any device info serial numbers", - platformSerialNumberDescription, platformSerialNumber); - return false; - } - - /** - * Checks if the endorsement credential is valid. - * - * @param ec the endorsement credential to verify. - * @param trustStore trust store holding trusted trusted certificates. - * @param acceptExpired whether or not to accept expired and not yet valid certificates - * as valid. - * @return the result of the validation. - */ - @Override - public AppraisalStatus validateEndorsementCredential(final EndorsementCredential ec, - final KeyStore trustStore, - final boolean acceptExpired) { - final String baseErrorMessage = "Can't validate endorsement credential attributes without "; - String message; - if (ec == null) { - message = baseErrorMessage + "an endorsement credential"; - log.error(message); - return new AppraisalStatus(FAIL, message); - } - if (trustStore == null) { - message = baseErrorMessage + "a trust store"; - log.error(message); - return new AppraisalStatus(FAIL, message); - } - - try { - X509Certificate verifiableCert = ec.getX509Certificate(); - - // check validity period, currently acceptExpired will also accept not yet - // valid certificates - if (!acceptExpired) { - verifiableCert.checkValidity(); - } - - if (verifyCertificate(verifiableCert, trustStore)) { - return new AppraisalStatus(PASS, ENDORSEMENT_VALID); - } else { - return new AppraisalStatus(FAIL, "Endorsement credential does not have a valid " - + "signature chain in the trust store"); - } - } catch (IOException e) { - message = "Couldn't retrieve X509 certificate from endorsement credential"; - log.error(message, e); - return new AppraisalStatus(ERROR, message + " " + e.getMessage()); - } catch (SupplyChainValidatorException e) { - message = "An error occurred indicating the credential is not valid"; - log.warn(message, e); - return new AppraisalStatus(ERROR, message + " " + e.getMessage()); - } catch (CertificateExpiredException e) { - message = "The endorsement credential is expired"; - log.warn(message, e); - return new AppraisalStatus(FAIL, message + " " + e.getMessage()); - } catch (CertificateNotYetValidException e) { - message = "The endorsement credential is not yet valid"; - log.warn(message, e); - return new AppraisalStatus(FAIL, message + " " + e.getMessage()); - } - } - - /** - * Attempts to check if the certificate is validated by certificates in a cert chain. The cert - * chain is expected to be stored in a non-ordered KeyStore (trust store). If the signing - * certificate for the target cert is found, but it is an intermediate cert, the validation will - * continue to try to find the signing cert of the intermediate cert. It will continue searching - * until it follows the chain up to a root (self-signed) cert. - * - * @param cert - * certificate to validate - * @param trustStore - * trust store holding trusted root certificates and intermediate certificates - * @return the certificate chain if validation is successful - * @throws SupplyChainValidatorException - * if the verification is not successful - */ - public static String verifyCertificate(final X509AttributeCertificateHolder cert, - final KeyStore trustStore) throws SupplyChainValidatorException { - try { - if (cert == null || trustStore == null) { - throw new SupplyChainValidatorException("Certificate or trust store is null"); - } else if (trustStore.size() == 0) { - throw new SupplyChainValidatorException("Truststore is empty"); - } - } catch (KeyStoreException e) { - log.error("Error accessing trust store: " + e.getMessage()); - } - - try { - Set trustedCerts = new HashSet<>(); - - Enumeration alias = trustStore.aliases(); - - while (alias.hasMoreElements()) { - trustedCerts.add((X509Certificate) trustStore.getCertificate(alias.nextElement())); - } - - String certChainValidated = validateCertChain(cert, trustedCerts); - if (!certChainValidated.isEmpty()) { - log.error("Cert chain could not be validated"); - } - return certChainValidated; - } catch (KeyStoreException e) { - throw new SupplyChainValidatorException("Error with the trust store", e); - } - } - - /** - * Attempts to check if the certificate is validated by certificates in a cert chain. The cert - * chain is expected to be stored in a non-ordered KeyStore (trust store). If the signing - * certificate for the target cert is found, but it is an intermediate cert, the validation will - * continue to try to find the signing cert of the intermediate cert. It will continue searching - * until it follows the chain up to a root (self-signed) cert. - * - * @param cert - * certificate to validate - * @param trustStore - * trust store holding trusted root certificates and intermediate certificates - * @return the certificate chain if validation is successful - * @throws SupplyChainValidatorException - * if the verification is not successful - */ - public static boolean verifyCertificate(final X509Certificate cert, - final KeyStore trustStore) throws SupplyChainValidatorException { - try { - if (cert == null || trustStore == null) { - throw new SupplyChainValidatorException("Certificate or trust store is null"); - } else if (trustStore.size() == 0) { - throw new SupplyChainValidatorException("Truststore is empty"); - } - } catch (KeyStoreException e) { - log.error("Error accessing trust store: " + e.getMessage()); - } - - try { - Set trustedCerts = new HashSet<>(); - - Enumeration alias = trustStore.aliases(); - - while (alias.hasMoreElements()) { - trustedCerts.add((X509Certificate) trustStore.getCertificate(alias.nextElement())); - } - - return validateCertChain(cert, trustedCerts).isEmpty(); - } catch (KeyStoreException e) { - log.error("Error accessing keystore", e); - throw new SupplyChainValidatorException("Error with the trust store", e); - } - - } - - /** - * Attempts to check if an attribute certificate is validated by certificates in a cert chain. - * The cert chain is represented as a Set of X509Certificates. If the signing certificate for - * the target cert is found, but it is an intermediate cert, the validation will continue to try - * to find the signing cert of the intermediate cert. It will continue searching until it - * follows the chain up to a root (self-signed) cert. - * - * @param cert - * certificate to validate - * @param additionalCerts - * Set of certs to validate against - * @return String status of the cert chain validation - - * blank if successful, error message otherwise - * @throws SupplyChainValidatorException tried to validate using null certificates - */ - 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"); - } - final String intCAError = "Intermediate signing cert found, check for CA cert"; - String foundRootOfCertChain = ""; - X509Certificate nextInChain = null; - - do { - for (X509Certificate trustedCert : additionalCerts) { - boolean issuerMatchesSubject = false; - boolean signatureMatchesPublicKey = false; - if (nextInChain != null) { - issuerMatchesSubject = issuerMatchesSubjectDN(nextInChain, trustedCert); - signatureMatchesPublicKey = signatureMatchesPublicKey(nextInChain, - trustedCert); - } else { - issuerMatchesSubject = issuerMatchesSubjectDN(cert, trustedCert); - signatureMatchesPublicKey = signatureMatchesPublicKey(cert, trustedCert); - } - - if (issuerMatchesSubject && signatureMatchesPublicKey) { - if (isSelfSigned(trustedCert)) { - log.info("CA Root found."); - return ""; - } else { - foundRootOfCertChain = intCAError; - nextInChain = trustedCert; - break; - } - } else { - if (!issuerMatchesSubject) { - foundRootOfCertChain = "Issuer DN does not match Subject DN"; - } - if (!signatureMatchesPublicKey) { - foundRootOfCertChain = "Certificate signature failed to verify"; - } - } - } - } while (foundRootOfCertChain.equals(intCAError)); - - log.error(foundRootOfCertChain); - return foundRootOfCertChain; - } - - /** - * Attempts to check if a public-key certificate is validated by certificates in a cert chain. - * The cert chain is represented as a Set of X509Certificates. If the signing certificate for - * the target cert is found, but it is an intermediate cert, the validation will continue to try - * to find the signing cert of the intermediate cert. It will continue searching until it - * follows the chain up to a root (self-signed) cert. - * - * @param cert - * certificate to validate - * @param additionalCerts - * Set of certs to validate against - * @return String status of the cert chain validation - - * blank if successful, error message otherwise - * @throws SupplyChainValidatorException tried to validate using null certificates - */ - 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"); - } - final String intCAError = "Intermediate signing cert found, check for CA cert"; - String foundRootOfCertChain = ""; - X509Certificate startOfChain = cert; - - do { - for (X509Certificate trustedCert : additionalCerts) { - boolean issuerMatchesSubject = issuerMatchesSubjectDN(startOfChain, trustedCert); - boolean signatureMatchesPublicKey = signatureMatchesPublicKey(startOfChain, - trustedCert); - if (issuerMatchesSubject && signatureMatchesPublicKey) { - if (isSelfSigned(trustedCert)) { - log.info("CA Root found."); - return ""; - } else { - foundRootOfCertChain = intCAError; - startOfChain = trustedCert; - break; - } - } else { - if (!issuerMatchesSubject) { - foundRootOfCertChain = "Issuer DN does not match Subject DN"; - } - if (!signatureMatchesPublicKey) { - foundRootOfCertChain = "Certificate signature failed to verify"; - } - } - } - } while (foundRootOfCertChain.equals(intCAError)); - - log.warn(foundRootOfCertChain); - return foundRootOfCertChain; - } - - private static String validateDeltaChain( - final Map deltaMapping, - final List baseCompList, - final List leftOvers, - final List absentSerials, - final List chainCertificates) { - StringBuilder resultMessage = new StringBuilder(); - List noneSerialValues = new ArrayList<>(); - noneSerialValues.add(""); - noneSerialValues.add(null); - noneSerialValues.add("Not Specified"); - noneSerialValues.add("To Be Filled By O.E.M."); - - // map the components throughout the chain - Map chainCiMapping = new HashMap<>(); - baseCompList.stream().forEach((ci) -> { - if (!noneSerialValues.contains(ci.getComponentSerial().toString())) { - chainCiMapping.put(ci.getComponentSerial().toString(), ci); - } else { - absentSerials.add(ci); - } - }); - - String ciSerial; - List certificateList = null; - SupplyChainValidation scv = null; - // go through the leaf and check the changes against the valid components - // forget modifying validOrigPcComponents - for (PlatformCredential delta : chainCertificates) { - StringBuilder failureMsg = new StringBuilder(); - certificateList = new ArrayList<>(); - certificateList.add(delta); - - for (ComponentIdentifier ci : delta.getComponentIdentifiers()) { - if (!noneSerialValues.contains(ci.getComponentSerial().toString())) { - if (ci.isVersion2()) { - ciSerial = ci.getComponentSerial().toString(); - ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) ci; - if (ciV2.isModified()) { - // this won't match - // check it is there - if (chainCiMapping.containsKey(ciSerial)) { - chainCiMapping.put(ciSerial, ci); - } else { - failureMsg.append(String.format( - "%s attempted MODIFIED with no prior instance.%n", - ciSerial)); - delta.setComponentFailures(String.format("%s,%d", - delta.getComponentFailures(), ciV2.hashCode())); - scv = deltaMapping.get(delta); - if (scv != null - && scv.getValidationResult() != PASS) { - failureMsg.append(scv.getMessage()); - } - deltaMapping.put(delta, new SupplyChainValidation( - SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, - FAIL, - certificateList, - failureMsg.toString())); - } - } else if (ciV2.isRemoved()) { - if (!chainCiMapping.containsKey(ciSerial)) { - // error thrown, can't remove if it doesn't exist - failureMsg.append(String.format( - "%s attempted REMOVED with no prior instance.%n", - ciSerial)); - delta.setComponentFailures(String.format("%s,%d", - delta.getComponentFailures(), ciV2.hashCode())); - scv = deltaMapping.get(delta); - if (scv != null - && scv.getValidationResult() != PASS) { - failureMsg.append(scv.getMessage()); - } - deltaMapping.put(delta, new SupplyChainValidation( - SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, - FAIL, - certificateList, - failureMsg.toString())); - } else { - chainCiMapping.remove(ciSerial); - } - } else if (ciV2.isAdded()) { - // ADDED - if (chainCiMapping.containsKey(ciSerial)) { - // error, shouldn't exist - failureMsg.append(String.format( - "%s was ADDED, the serial already exists.%n", - ciSerial)); - delta.setComponentFailures(String.format("%s,%d", - delta.getComponentFailures(), ciV2.hashCode())); - scv = deltaMapping.get(delta); - if (scv != null - && scv.getValidationResult() != PASS) { - failureMsg.append(scv.getMessage()); - } - deltaMapping.put(delta, new SupplyChainValidation( - SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, - FAIL, - certificateList, - failureMsg.toString())); - } else { - // have to add in case later it is removed - chainCiMapping.put(ciSerial, ci); - } - } - } - } else { - if (ci.isVersion2() && ((ComponentIdentifierV2) ci).isModified()) { - ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) ci; - // Look for singular component of same make/model/class - ComponentIdentifier candidate = null; - for (ComponentIdentifier search : absentSerials) { - if (!search.isVersion2()) { - continue; - } - ComponentIdentifierV2 noSerialV2 = (ComponentIdentifierV2) search; - - if (noSerialV2.getComponentClass().getComponentIdentifier().equals( - ciV2.getComponentClass().getComponentIdentifier()) - && isMatch(noSerialV2, ciV2)) { - if (candidate == null) { - candidate = noSerialV2; - } else { - // This only works if there is one matching component - candidate = null; - break; - } - } - } - - if (candidate != null) { - absentSerials.remove(candidate); - absentSerials.add(ciV2); - } else { - leftOvers.add(ci); - } - } else { - // found a delta ci with no serial - // add to list - leftOvers.add(ci); - } - } - } - - resultMessage.append(failureMsg.toString()); - } - baseCompList.clear(); - baseCompList.addAll(chainCiMapping.values()); - baseCompList.addAll(absentSerials); - - return resultMessage.toString(); - } - - /** - * Checks if the issuer info of an attribute cert matches the supposed signing cert's - * distinguished name. - * - * @param cert - * the attribute certificate with the signature to validate - * @param signingCert - * the certificate with the public key to validate - * @return boolean indicating if the names - * @throws SupplyChainValidatorException tried to validate using null certificates - */ - public static boolean issuerMatchesSubjectDN(final X509AttributeCertificateHolder cert, - final X509Certificate signingCert) throws SupplyChainValidatorException { - if (cert == null || signingCert == null) { - throw new SupplyChainValidatorException("Certificate or signing certificate is null"); - } - String signingCertSubjectDN = signingCert.getSubjectX500Principal().getName(); - X500Name namedSubjectDN = new X500Name(signingCertSubjectDN); - - X500Name issuerDN = cert.getIssuer().getNames()[0]; - - // equality check ignore DN component ordering - return issuerDN.equals(namedSubjectDN); - } - - /** - * Checks if the issuer info of a public-key cert matches the supposed signing cert's - * distinguished name. - * - * @param cert - * the public-key certificate with the signature to validate - * @param signingCert - * the certificate with the public key to validate - * @return boolean indicating if the names - * @throws SupplyChainValidatorException tried to validate using null certificates - */ - public static boolean issuerMatchesSubjectDN(final X509Certificate cert, - final X509Certificate signingCert) throws SupplyChainValidatorException { - if (cert == null || signingCert == null) { - throw new SupplyChainValidatorException("Certificate or signing certificate is null"); - } - String signingCertSubjectDN = signingCert.getSubjectX500Principal(). - getName(X500Principal.RFC1779); - X500Name namedSubjectDN = new X500Name(signingCertSubjectDN); - - String certIssuerDN = cert.getIssuerX500Principal().getName(); - X500Name namedIssuerDN = new X500Name(certIssuerDN); - - // equality check ignore DN component ordering - return namedIssuerDN.equals(namedSubjectDN); - } - - /** - * Checks if the signature of an attribute cert is validated against the signing cert's public - * key. - * - * @param cert - * the public-key certificate with the signature to validate - * @param signingCert - * the certificate with the public key to validate - * @return boolean indicating if the validation passed - * @throws SupplyChainValidatorException tried to validate using null certificates - */ - public static boolean signatureMatchesPublicKey(final X509Certificate cert, - final X509Certificate signingCert) throws SupplyChainValidatorException { - if (cert == null || signingCert == null) { - throw new SupplyChainValidatorException("Certificate or signing certificate is null"); - } - try { - cert.verify(signingCert.getPublicKey(), BouncyCastleProvider.PROVIDER_NAME); - return true; - } catch (InvalidKeyException e) { - log.info("Incorrect key given to validate this cert's signature"); - } catch (CertificateException e) { - log.info("Encoding error while validating this cert's signature"); - } catch (NoSuchAlgorithmException e) { - log.info("Unsupported signature algorithm found during validation"); - } catch (NoSuchProviderException e) { - log.info("Incorrect provider for cert signature validation"); - } catch (SignatureException e) { - log.info(String.format("%s.verify(%s)", cert.getSubjectX500Principal(), - signingCert.getSubjectX500Principal())); - } - return false; - - } - - /** - * Checks if the signature of a public-key cert is validated against the signing cert's public - * key. - * - * @param cert - * the attribute certificate with the signature to validate - * @param signingCert - * the certificate with the public key to validate - * @return boolean indicating if the validation passed - * @throws SupplyChainValidatorException tried to validate using null certificates - */ - public static boolean signatureMatchesPublicKey(final X509AttributeCertificateHolder cert, - final X509Certificate signingCert) throws SupplyChainValidatorException { - if (signingCert == null) { - throw new SupplyChainValidatorException("Signing certificate is null"); - } - return signatureMatchesPublicKey(cert, signingCert.getPublicKey()); - } - - /** - * Checks if an X509 Attribute Certificate is valid directly against a public key. - * - * @param cert - * the attribute certificate with the signature to validate - * @param signingKey - * the key to use to check the attribute cert - * @return boolean indicating if the validation passed - * @throws SupplyChainValidatorException tried to validate using null certificates - */ - public static boolean signatureMatchesPublicKey(final X509AttributeCertificateHolder cert, - final PublicKey signingKey) throws SupplyChainValidatorException { - if (cert == null || signingKey == null) { - throw new SupplyChainValidatorException("Certificate or signing certificate is null"); - } - ContentVerifierProvider contentVerifierProvider; - try { - contentVerifierProvider = - new JcaContentVerifierProviderBuilder().setProvider("BC").build(signingKey); - return cert.isSignatureValid(contentVerifierProvider); - } catch (OperatorCreationException | CertException e) { - log.info("Exception thrown while verifying certificate", e); - log.info(String.format("%s.isSignatureValid(%s)", cert.getSerialNumber(), - signingKey.getFormat())); - return false; - } - } - - /** - * Checks whether given X.509 public-key certificate is self-signed. If the cert can be - * verified using its own public key, that means it was self-signed. - * - * @param cert - * X.509 Certificate - * @return boolean indicating if the cert was self-signed - */ - private static boolean isSelfSigned(final X509Certificate cert) - throws SupplyChainValidatorException { - if (cert == null) { - throw new SupplyChainValidatorException("Certificate is null"); - } - try { - PublicKey key = cert.getPublicKey(); - cert.verify(key); - return true; - } catch (SignatureException | InvalidKeyException e) { - return false; - } catch (CertificateException | NoSuchAlgorithmException | NoSuchProviderException e) { - log.error("Exception occurred while checking if cert is self-signed", e); - return false; - } - } -} diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiGuid.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiGuid.java index 7ceecdc0..aa83f937 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiGuid.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiGuid.java @@ -23,7 +23,7 @@ public class UefiGuid { */ private static final int UUID_EPOCH_DIVISOR = 10000; - private static final Path JSON_PATH = FileSystems.getDefault().getPath("/opt", + private static final Path JSON_PATH = FileSystems.getDefault().getPath("/etc", "hirs/aca", "default-properties", "vendor-table.json"); private JsonObject uefiVendorRef; /** From 310102bc8addfc9dcf4055f1c35ccb90ac8306aa Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Thu, 21 Sep 2023 16:13:31 -0400 Subject: [PATCH 03/26] Missed files --- .../persist/service/ValidationManager.java | 338 +++++ .../CertificateAttributeScvValidator.java | 1125 +++++++++++++++++ .../validation/FirmwareScvValidator.java | 258 ++++ 3 files changed, 1721 insertions(+) create mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationManager.java create mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java create mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationManager.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationManager.java new file mode 100644 index 00000000..f1dbaeee --- /dev/null +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationManager.java @@ -0,0 +1,338 @@ +package hirs.attestationca.persist.service; + +import hirs.attestationca.persist.entity.ArchivableEntity; +import hirs.attestationca.persist.entity.manager.CACredentialRepository; +import hirs.attestationca.persist.entity.manager.CertificateRepository; +import hirs.attestationca.persist.entity.manager.ComponentResultRepository; +import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository; +import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository; +import hirs.attestationca.persist.entity.userdefined.Certificate; +import hirs.attestationca.persist.entity.userdefined.Device; +import hirs.attestationca.persist.entity.userdefined.PolicySettings; +import hirs.attestationca.persist.entity.userdefined.SupplyChainValidation; +import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential; +import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult; +import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; +import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; +import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport; +import hirs.attestationca.persist.enums.AppraisalStatus; +import hirs.attestationca.persist.validation.CertificateAttributeScvValidator; +import hirs.attestationca.persist.validation.CredentialValidator; +import hirs.attestationca.persist.validation.FirmwareScvValidator; +import hirs.utils.BouncyCastleUtils; +import lombok.extern.log4j.Log4j2; +import org.apache.logging.log4j.Level; +import org.bouncycastle.util.encoders.Hex; + +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Log4j2 +public class ValidationManager { + + public static SupplyChainValidation evaluateEndorsementCredentialStatus( + final EndorsementCredential ec, + final CACredentialRepository caCredentialRepository, + final boolean acceptExpiredCerts) { + final SupplyChainValidation.ValidationType validationType + = SupplyChainValidation.ValidationType.ENDORSEMENT_CREDENTIAL; + log.info("Validating endorsement credential"); + if (ec == null) { + log.error("No endorsement credential to validate"); + return buildValidationRecord(validationType, + AppraisalStatus.Status.FAIL, "Endorsement credential is missing", + null, Level.ERROR); + } + + KeyStore ecStore = getCaChain(ec, caCredentialRepository); + AppraisalStatus result = CredentialValidator. + validateEndorsementCredential(ec, ecStore, acceptExpiredCerts); + switch (result.getAppStatus()) { + case PASS: + return buildValidationRecord(validationType, AppraisalStatus.Status.PASS, + result.getMessage(), ec, Level.INFO); + case FAIL: + return buildValidationRecord(validationType, AppraisalStatus.Status.FAIL, + result.getMessage(), ec, Level.WARN); + case ERROR: + default: + return buildValidationRecord(validationType, AppraisalStatus.Status.ERROR, + result.getMessage(), ec, Level.ERROR); + } + } + + public static SupplyChainValidation evaluatePlatformCredentialStatus( + final PlatformCredential pc, + final KeyStore trustedCertificateAuthority, final boolean acceptExpiredCerts) { + final SupplyChainValidation.ValidationType validationType + = SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL; + + if (pc == null) { + log.error("No platform credential to validate"); + return buildValidationRecord(validationType, + AppraisalStatus.Status.FAIL, "Empty Platform credential", null, Level.ERROR); + } + log.info("Validating Platform Credential"); + AppraisalStatus result = CredentialValidator.validatePlatformCredential(pc, + trustedCertificateAuthority, acceptExpiredCerts); + switch (result.getAppStatus()) { + case PASS: + return buildValidationRecord(validationType, AppraisalStatus.Status.PASS, + result.getMessage(), pc, Level.INFO); + case FAIL: + return buildValidationRecord(validationType, AppraisalStatus.Status.FAIL, + result.getMessage(), pc, Level.WARN); + case ERROR: + default: + return buildValidationRecord(validationType, AppraisalStatus.Status.ERROR, + result.getMessage(), pc, Level.ERROR); + } + } + + public static SupplyChainValidation evaluatePCAttributesStatus( + final PlatformCredential pc, final DeviceInfoReport deviceInfoReport, + final EndorsementCredential ec, + final CertificateRepository certificateRepository, + final ComponentResultRepository componentResultRepository) { + final SupplyChainValidation.ValidationType validationType + = SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES; + + if (pc == null) { + log.error("No platform credential to validate"); + return buildValidationRecord(validationType, + AppraisalStatus.Status.FAIL, "Platform credential is missing", + null, Level.ERROR); + } + log.info("Validating platform credential attributes"); + AppraisalStatus result = CredentialValidator. + validatePlatformCredentialAttributes(pc, deviceInfoReport, ec); + switch (result.getAppStatus()) { + case PASS: + return buildValidationRecord(validationType, AppraisalStatus.Status.PASS, + result.getMessage(), pc, Level.INFO); + case FAIL: + if (!result.getAdditionalInfo().isEmpty()) { + pc.setComponentFailures(result.getAdditionalInfo()); + pc.setComponentFailureMessage(result.getMessage()); + certificateRepository.save(pc); + for (ComponentResult componentResult + : CertificateAttributeScvValidator.getComponentResultList()) { + componentResultRepository.save(componentResult); + } + } + return buildValidationRecord(validationType, AppraisalStatus.Status.FAIL, + result.getMessage(), pc, Level.WARN); + case ERROR: + default: + return buildValidationRecord(validationType, AppraisalStatus.Status.ERROR, + result.getMessage(), pc, Level.ERROR); + } + } + + public static SupplyChainValidation evaluateDeltaAttributesStatus( + final PlatformCredential delta, + final DeviceInfoReport deviceInfoReport, + final PlatformCredential base, + final Map deltaMapping, + final CertificateRepository certificateRepository) { + final SupplyChainValidation.ValidationType validationType + = SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES; + + if (delta == null) { + log.error("No delta certificate to validate"); + return buildValidationRecord(validationType, + AppraisalStatus.Status.FAIL, "Delta platform certificate is missing", + null, Level.ERROR); + } + log.info("Validating delta platform certificate attributes"); + AppraisalStatus result = CertificateAttributeScvValidator. + validateDeltaPlatformCredentialAttributes(delta, deviceInfoReport, + base, deltaMapping); + switch (result.getAppStatus()) { + case PASS: + return buildValidationRecord(validationType, AppraisalStatus.Status.PASS, + result.getMessage(), delta, Level.INFO); + case FAIL: + if (!result.getAdditionalInfo().isEmpty()) { + base.setComponentFailures(result.getAdditionalInfo()); + base.setComponentFailureMessage(result.getMessage()); + certificateRepository.save(base); + } + // we are adding things to componentFailures + certificateRepository.save(delta); + return buildValidationRecord(validationType, AppraisalStatus.Status.FAIL, + result.getMessage(), delta, Level.WARN); + case ERROR: + default: + return buildValidationRecord(validationType, AppraisalStatus.Status.ERROR, + result.getMessage(), delta, Level.ERROR); + } + } + + public static SupplyChainValidation evaluateFirmwareStatus( + final Device device, + final PolicySettings policySettings, final ReferenceManifestRepository rimRepo, + final ReferenceDigestValueRepository rdvRepo, + final CACredentialRepository caRepo) { + final SupplyChainValidation.ValidationType validationType + = SupplyChainValidation.ValidationType.FIRMWARE; + + AppraisalStatus result = FirmwareScvValidator.validateFirmware(device, policySettings, + rimRepo, rdvRepo, caRepo); + Level logLevel; + + switch (result.getAppStatus()) { + case PASS: + logLevel = Level.INFO; + break; + case FAIL: + logLevel = Level.WARN; + break; + case ERROR: + default: + logLevel = Level.ERROR; + } + return buildValidationRecord(validationType, result.getAppStatus(), + result.getMessage(), null, logLevel); + } + + /** + * Creates a supply chain validation record and logs the validation message + * at the specified log level. + * + * @param validationType the type of validation + * @param result the appraisal status + * @param message the validation message to include in the summary and log + * @param archivableEntity the archivableEntity associated with the + * validation + * @param logLevel the log level + * @return a SupplyChainValidation + */ + public static SupplyChainValidation buildValidationRecord( + final SupplyChainValidation.ValidationType validationType, + final AppraisalStatus.Status result, final String message, + final ArchivableEntity archivableEntity, final Level logLevel) { + List aeList = new ArrayList<>(); + if (archivableEntity != null) { + aeList.add(archivableEntity); + } + + log.log(logLevel, message); + return new SupplyChainValidation(validationType, result, aeList, message); + } + + /** + * This method is used to retrieve the entire CA chain (up to a trusted + * self-signed certificate) for the given certificate. This method will look + * up CA certificates that have a matching issuer organization as the given + * certificate, and will perform that operation recursively until all + * certificates for all relevant organizations have been retrieved. For that + * reason, the returned set of certificates may be larger than the the + * single trust chain for the queried certificate, but is guaranteed to + * include the trust chain if it exists in this class' CertificateManager. + * Returns the certificate authority credentials in a KeyStore. + * + * @param certificate the credential whose CA chain should be retrieved + * @param caCredentialRepository db service to get CA Certs + * @return A keystore containing all relevant CA credentials to the given + * certificate's organization or null if the keystore can't be assembled + */ + public static KeyStore getCaChain(final Certificate certificate, + final CACredentialRepository caCredentialRepository) { + KeyStore caKeyStore = null; + try { + caKeyStore = caCertSetToKeystore(getCaChainRec(certificate, Collections.emptySet(), + caCredentialRepository)); + } catch (KeyStoreException | IOException e) { + log.error("Unable to assemble CA keystore", e); + } + return caKeyStore; + } + + /** + * This is a recursive method which is used to retrieve the entire CA chain + * (up to a trusted self-signed certificate) for the given certificate. This + * method will look up CA certificates that have a matching issuer + * organization as the given certificate, and will perform that operation + * recursively until all certificates for all relevant organizations have + * been retrieved. For that reason, the returned set of certificates may be + * larger than the the single trust chain for the queried certificate, but + * is guaranteed to include the trust chain if it exists in this class' + * CertificateManager. + *

+ * Implementation notes: 1. Queries for CA certs with a subject org matching + * the given (argument's) issuer org 2. Add that org to + * queriedOrganizations, so we don't search for that organization again 3. + * For each returned CA cert, add that cert to the result set, and recurse + * with that as the argument (to go up the chain), if and only if we haven't + * already queried for that organization (which prevents infinite loops on + * certs with an identical subject and issuer org) + * + * @param credential the credential whose CA chain should be retrieved + * @param previouslyQueriedSubjects a list of organizations to refrain + * from querying + * @return a Set containing all relevant CA credentials to the given + * certificate's organization + */ + public static Set getCaChainRec( + final Certificate credential, + final Set previouslyQueriedSubjects, + final CACredentialRepository caCredentialRepository) { + CertificateAuthorityCredential skiCA = null; + List certAuthsWithMatchingIssuer = new LinkedList<>(); + if (credential.getAuthorityKeyIdentifier() != null + && !credential.getAuthorityKeyIdentifier().isEmpty()) { + byte[] bytes = Hex.decode(credential.getAuthorityKeyIdentifier()); + skiCA = caCredentialRepository.findBySubjectKeyIdentifier(bytes); + } + + if (skiCA == null) { + if (credential.getIssuerSorted() == null + || credential.getIssuerSorted().isEmpty()) { + certAuthsWithMatchingIssuer = caCredentialRepository.findBySubject(credential.getIssuer()); + } else { + //Get certificates by subject organization + certAuthsWithMatchingIssuer = caCredentialRepository.findBySubjectSorted(credential.getIssuerSorted()); + } + } else { + certAuthsWithMatchingIssuer.add(skiCA); + } + Set queriedOrganizations = new HashSet<>(previouslyQueriedSubjects); + queriedOrganizations.add(credential.getIssuer()); + + HashSet caCreds = new HashSet<>(); + for (CertificateAuthorityCredential cred : certAuthsWithMatchingIssuer) { + caCreds.add(cred); + if (!BouncyCastleUtils.x500NameCompare(cred.getIssuer(), + cred.getSubject())) { + caCreds.addAll(getCaChainRec(cred, queriedOrganizations, caCredentialRepository)); + } + } + return caCreds; + } + + public static KeyStore caCertSetToKeystore(final Set certs) + throws KeyStoreException, IOException { + KeyStore keyStore = KeyStore.getInstance("JKS"); + try { + keyStore.load(null, "".toCharArray()); + for (Certificate cert : certs) { + keyStore.setCertificateEntry(cert.getId().toString(), cert.getX509Certificate()); + } + } catch (IOException | CertificateException | NoSuchAlgorithmException e) { + throw new IOException("Could not create and populate keystore", e); + } + + return keyStore; + } +} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java new file mode 100644 index 00000000..5140632a --- /dev/null +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CertificateAttributeScvValidator.java @@ -0,0 +1,1125 @@ +package hirs.attestationca.persist.validation; + +import hirs.attestationca.persist.entity.ArchivableEntity; +import hirs.attestationca.persist.entity.userdefined.SupplyChainValidation; +import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult; +import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2; +import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo; +import hirs.attestationca.persist.entity.userdefined.info.HardwareInfo; +import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport; +import hirs.attestationca.persist.enums.AppraisalStatus; +import hirs.attestationca.persist.util.PciIds; +import hirs.utils.enums.DeviceInfoEnums; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.log4j.Log4j2; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.util.Strings; +import org.bouncycastle.asn1.DERUTF8String; + +import java.io.IOException; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +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; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import static hirs.attestationca.persist.enums.AppraisalStatus.Status.ERROR; +import static hirs.attestationca.persist.enums.AppraisalStatus.Status.FAIL; +import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS; + +@Log4j2 +public class CertificateAttributeScvValidator extends SupplyChainCredentialValidator { + + @Setter + @Getter + private static List componentResultList = new LinkedList<>(); + + /** + * Checks if the delta credential's attributes are valid. + * @param deltaPlatformCredential the delta credential to verify + * @param deviceInfoReport The device info report containing + * serial number of the platform to be validated. + * @param basePlatformCredential the base credential from the same identity request + * as the delta credential. + * @param deltaMapping delta certificates associated with the + * delta supply validation. + * @return the result of the validation. + */ + public static AppraisalStatus validateDeltaPlatformCredentialAttributes( + final PlatformCredential deltaPlatformCredential, + final DeviceInfoReport deviceInfoReport, + final PlatformCredential basePlatformCredential, + final Map deltaMapping) { + String message; + + // this needs to be a loop for all deltas, link to issue #110 + // check that they don't have the same serial number + for (PlatformCredential pc : deltaMapping.keySet()) { + if (!basePlatformCredential.getPlatformSerial() + .equals(pc.getPlatformSerial())) { + message = String.format("Base and Delta platform serial " + + "numbers do not match (%s != %s)", + pc.getPlatformSerial(), + basePlatformCredential.getPlatformSerial()); + log.error(message); + return new AppraisalStatus(FAIL, message); + } + // none of the deltas should have the serial number of the base + if (!pc.isPlatformBase() && basePlatformCredential.getSerialNumber() + .equals(pc.getSerialNumber())) { + message = String.format("Delta Certificate with same serial number as base. (%s)", + pc.getSerialNumber()); + log.error(message); + return new AppraisalStatus(FAIL, message); + } + } + + // parse out the provided delta and its specific chain. + List origPcComponents + = new LinkedList<>(basePlatformCredential.getComponentIdentifiers()); + + return validateDeltaAttributesChainV2p0(deltaPlatformCredential.getId(), + deviceInfoReport, deltaMapping, origPcComponents); + } + + public static AppraisalStatus validatePlatformCredentialAttributesV1p2( + final PlatformCredential platformCredential, + final DeviceInfoReport deviceInfoReport) { + + // check the device's board serial number, and compare against this + // platform credential's board serial number. + // Retrieve the various device serial numbers. + String credentialBoardSerialNumber = platformCredential.getPlatformSerial(); + String credentialChassisSerialNumber = platformCredential.getChassisSerialNumber(); + + HardwareInfo hardwareInfo = deviceInfoReport.getHardwareInfo(); + String deviceBaseboardSerialNumber = hardwareInfo.getBaseboardSerialNumber(); + String deviceChassisSerialNumber = hardwareInfo.getChassisSerialNumber(); + String deviceSystemSerialNumber = hardwareInfo.getSystemSerialNumber(); + + // log serial numbers that weren't collected. Force "not specified" serial numbers + // to be ignored in below case checks + Map deviceInfoSerialNumbers = new HashMap<>(); + + if (StringUtils.isEmpty(deviceBaseboardSerialNumber) + || DeviceInfoEnums.NOT_SPECIFIED.equalsIgnoreCase(deviceBaseboardSerialNumber)) { + log.error("Failed to retrieve device baseboard serial number"); + deviceBaseboardSerialNumber = null; + } else { + deviceInfoSerialNumbers.put("board serial number", deviceBaseboardSerialNumber); + log.info("Using device board serial number for validation: " + + deviceBaseboardSerialNumber); + } + + if (StringUtils.isEmpty(deviceChassisSerialNumber) + || DeviceInfoEnums.NOT_SPECIFIED.equalsIgnoreCase(deviceChassisSerialNumber)) { + log.error("Failed to retrieve device chassis serial number"); + } else { + deviceInfoSerialNumbers.put("chassis serial number", deviceChassisSerialNumber); + log.info("Using device chassis serial number for validation: " + + deviceChassisSerialNumber); + } + if (StringUtils.isEmpty(deviceSystemSerialNumber) + || DeviceInfoEnums.NOT_SPECIFIED.equalsIgnoreCase(deviceSystemSerialNumber)) { + log.error("Failed to retrieve device system serial number"); + } else { + deviceInfoSerialNumbers.put("system serial number", deviceSystemSerialNumber); + log.info("Using device system serial number for validation: " + + deviceSystemSerialNumber); + } + + AppraisalStatus status; + + // Test 1: If the board serial number or chassis is set on the PC, + // compare with each of the device serial numbers for any match + if (StringUtils.isNotEmpty(credentialBoardSerialNumber) + || StringUtils.isNotEmpty(credentialChassisSerialNumber)) { + status = validatePlatformSerialsWithDeviceSerials(credentialBoardSerialNumber, + credentialChassisSerialNumber, deviceInfoSerialNumbers); + // Test 2: If the board and chassis serial numbers are not set on the PC, + // compare the SHA1 hash of the device baseboard serial number to + // the certificate serial number + } else { + String message; + log.debug("Credential Serial Number was null"); + if (StringUtils.isEmpty(deviceBaseboardSerialNumber)) { + message = "Device Serial Number was null"; + log.error(message); + status = new AppraisalStatus(FAIL, message); + } else { + // Calculate the SHA1 hash of the UTF8 encoded baseboard serial number + BigInteger baseboardSha1 = new BigInteger(1, + DigestUtils.sha1(deviceBaseboardSerialNumber.getBytes(StandardCharsets.UTF_8))); + BigInteger certificateSerialNumber = platformCredential.getSerialNumber(); + + // compare the SHA1 hash of the baseboard serial number to the certificate SN + if (certificateSerialNumber != null + && certificateSerialNumber.equals(baseboardSha1)) { + log.info("Device Baseboard Serial Number matches " + + "the Certificate Serial Number"); + status = new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID); + } else if (certificateSerialNumber != null + && certificateSerialNumber.equals( + baseboardSha1.clearBit(NUC_VARIABLE_BIT))) { + log.info("Warning! The Certificate serial number had the most significant " + + "bit truncated. 159 bits of it matched the device baseboard " + + "serial number."); + status = new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID); + } else { + message = "The SHA1 hash of the Device Baseboard Serial Number " + + deviceBaseboardSerialNumber + + " did not match the Certificate's Serial Number"; + log.error(message); + status = new AppraisalStatus(FAIL, message); + + } + } + } + + return status; + } + + + /** + * Validates device info report against the new platform credential. + * @param platformCredential the Platform Credential + * @param deviceInfoReport the Device Info Report + * @return either PASS or FAIL + */ + public static AppraisalStatus validatePlatformCredentialAttributesV2p0( + final PlatformCredential platformCredential, + final DeviceInfoReport deviceInfoReport) { + boolean passesValidation = true; + StringBuilder resultMessage = new StringBuilder(); + + HardwareInfo hardwareInfo = deviceInfoReport.getHardwareInfo(); + + boolean fieldValidation; + fieldValidation = requiredPlatformCredentialFieldIsNonEmptyAndMatches( + "PlatformManufacturerStr", + platformCredential.getManufacturer(), + hardwareInfo.getManufacturer()); + + if (!fieldValidation) { + resultMessage.append("Platform manufacturer did not match\n"); + } + + passesValidation &= fieldValidation; + + fieldValidation = requiredPlatformCredentialFieldIsNonEmptyAndMatches( + "PlatformModel", + platformCredential.getModel(), + hardwareInfo.getProductName()); + + if (!fieldValidation) { + resultMessage.append("Platform model did not match\n"); + } + + passesValidation &= fieldValidation; + + fieldValidation = requiredPlatformCredentialFieldIsNonEmptyAndMatches( + "PlatformVersion", + platformCredential.getVersion(), + hardwareInfo.getVersion()); + + if (!fieldValidation) { + resultMessage.append("Platform version did not match\n"); + } + + passesValidation &= fieldValidation; + + // check PlatformSerial against both system-serial-number and baseboard-serial-number + fieldValidation = ( + (optionalPlatformCredentialFieldNullOrMatches( + "PlatformSerial", + platformCredential.getPlatformSerial(), + hardwareInfo.getSystemSerialNumber())) + || (optionalPlatformCredentialFieldNullOrMatches( + "PlatformSerial", + platformCredential.getPlatformSerial(), + hardwareInfo.getBaseboardSerialNumber()))); + + if (!fieldValidation) { + resultMessage.append("Platform serial did not match\n"); + } + + passesValidation &= fieldValidation; + + // Retrieve the list of all components from the Platform Credential + List allPcComponents + = new ArrayList<>(platformCredential.getComponentIdentifiers()); + + // All components listed in the Platform Credential must have a manufacturer and model + for (ComponentIdentifier pcComponent : allPcComponents) { + fieldValidation = !hasEmptyValueForRequiredField("componentManufacturer", + pcComponent.getComponentManufacturer()); + + if (!fieldValidation) { + resultMessage.append("Component manufacturer is empty\n"); + } + + passesValidation &= fieldValidation; + + fieldValidation = !hasEmptyValueForRequiredField("componentModel", + pcComponent.getComponentModel()); + + if (!fieldValidation) { + resultMessage.append("Component model is empty\n"); + } + + passesValidation &= fieldValidation; + } + + // There is no need to do comparisons with components that are invalid because + // they did not have a manufacturer or model. + List validPcComponents = allPcComponents.stream() + .filter(identifier -> identifier.getComponentManufacturer() != null + && identifier.getComponentModel() != null) + .collect(Collectors.toList()); + + String paccorOutputString = deviceInfoReport.getPaccorOutputString(); + String unmatchedComponents; + try { + List componentInfoList + = getComponentInfoFromPaccorOutput(paccorOutputString); + unmatchedComponents = validateV2p0PlatformCredentialComponentsExpectingExactMatch( + platformCredential.getId(), + validPcComponents, componentInfoList); + fieldValidation &= unmatchedComponents.isEmpty(); + } catch (IOException e) { + final String baseErrorMessage = "Error parsing JSON output from PACCOR: "; + log.error(baseErrorMessage + e.toString()); + log.error("PACCOR output string:\n" + paccorOutputString); + return new AppraisalStatus(ERROR, baseErrorMessage + e.getMessage()); + } + + StringBuilder additionalInfo = new StringBuilder(); + if (!fieldValidation) { + resultMessage.append("There are unmatched components:\n"); + resultMessage.append(unmatchedComponents); + + // pass information of which ones failed in additionInfo + int counter = 0; + for (ComponentIdentifier ci : validPcComponents) { + counter++; + additionalInfo.append(String.format("%d;", ci.hashCode())); + } + if (counter > 0) { + additionalInfo.insert(0, "COMPID="); + additionalInfo.append(counter); + } + } + + passesValidation &= fieldValidation; + + if (passesValidation) { + return new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID); + } else { + return new AppraisalStatus(FAIL, resultMessage.toString(), additionalInfo.toString()); + } + } + + /** + * The main purpose of this method, the in process of validation, is to + * pick out the changes that lead to the delta cert and make sure the changes + * are valid. + * + * @param deviceInfoReport The paccor profile of device being validated against. + * @param deltaMapping map of delta certificates to their validated status + * @param origPcComponents The component identifier list associated with the + * base cert for this specific chain + * @return Appraisal Status of delta being validated. + */ + @SuppressWarnings("methodlength") + static AppraisalStatus validateDeltaAttributesChainV2p0( + final UUID certificateId, + final DeviceInfoReport deviceInfoReport, + final Map deltaMapping, + final List origPcComponents) { + boolean fieldValidation = true; + StringBuilder resultMessage = new StringBuilder(); + String tempStringMessage = ""; + List validOrigPcComponents = origPcComponents.stream() + .filter(identifier -> identifier.getComponentManufacturer() != null + && identifier.getComponentModel() != null) + .collect(Collectors.toList()); + List chainCertificates = new LinkedList<>(deltaMapping.keySet()); + + // map the components throughout the chain + List baseCompList = new LinkedList<>(validOrigPcComponents); + + Collections.sort(chainCertificates, new Comparator() { + @Override + public int compare(final PlatformCredential obj1, + final PlatformCredential obj2) { + if (obj1 == null) { + return 0; + } + if (obj2 == null) { + return 0; + } + if (obj1.getBeginValidity() == null || obj2.getBeginValidity() == null) { + return 0; + } + return obj1.getBeginValidity().compareTo(obj2.getBeginValidity()); + } + }); + // start of some changes + resultMessage.append("There are errors with Delta " + + "Component Statuses:\n"); + List leftOverDeltas = new ArrayList<>(); + List absentSerialNum = new ArrayList<>(); + tempStringMessage = validateDeltaChain(deltaMapping, baseCompList, + leftOverDeltas, absentSerialNum, chainCertificates); + + // check if there were any issues + if (!tempStringMessage.isEmpty()) { + resultMessage.append(tempStringMessage); + fieldValidation = false; + } + + // finished up + List certificateList = null; + SupplyChainValidation scv = null; + StringBuilder deltaSb = new StringBuilder(); + + // non-empty serial values + for (ComponentIdentifier deltaCi : leftOverDeltas) { + String classValue; + ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) deltaCi; + ComponentIdentifierV2 baseCiV2; + boolean classFound; + + for (ComponentIdentifier ci : absentSerialNum) { + classValue = ciV2.getComponentClass().getComponentIdentifier(); + baseCiV2 = (ComponentIdentifierV2) ci; + classFound = classValue.equals(baseCiV2.getComponentClass() + .getComponentIdentifier()); + if (classFound) { + if (isMatch(ciV2, baseCiV2)) { + if (ciV2.isAdded() || ciV2.isModified()) { + // since the base list doesn't have this ci + // just add the delta + baseCompList.add(deltaCi); + break; + } + if (ciV2.isRemoved()) { + baseCompList.remove(ciV2); + break; + } + // if it is a remove + // we do nothing because baseCompList doesn't have it + } else { + // it is an add + if (ciV2.isAdded()) { + baseCompList.add(deltaCi); + } + } + } else { + // delta change to a class not there + if (ciV2.isAdded()) { + baseCompList.add(deltaCi); + } + + if (ciV2.isModified()) { + // error because you can't modify something + // that isn't here + resultMessage.append("MODIFIED attempted without prior instance\n"); + deltaSb.append(String.format("%s;", ci.hashCode())); + } + + if (ciV2.isRemoved()) { + // error because you can't remove something + // that isn't here + resultMessage.append("REMOVED attempted without prior instance\n"); + deltaSb.append(String.format("%s;", ci.hashCode())); + } + } + } + } + + if (!fieldValidation || !deltaSb.toString().isEmpty()) { + deltaSb.insert(0, "COMPID="); + return new AppraisalStatus(FAIL, resultMessage.toString(), deltaSb.toString()); + } + + String paccorOutputString = deviceInfoReport.getPaccorOutputString(); + String unmatchedComponents; + try { + // compare based on component class + List componentInfoList = getV2PaccorOutput(paccorOutputString); + // this is what I want to rewrite + unmatchedComponents = validateV2PlatformCredentialAttributes( + certificateId, + baseCompList, + componentInfoList); + fieldValidation &= unmatchedComponents.isEmpty(); + } catch (IOException ioEx) { + final String baseErrorMessage = "Error parsing JSON output from PACCOR: "; + log.error(baseErrorMessage + ioEx.toString()); + log.error("PACCOR output string:\n" + paccorOutputString); + return new AppraisalStatus(ERROR, baseErrorMessage + ioEx.getMessage()); + } + StringBuilder additionalInfo = new StringBuilder(); + if (!fieldValidation) { + resultMessage = new StringBuilder(); + resultMessage.append("There are unmatched components:\n"); + resultMessage.append(unmatchedComponents); + + // pass information of which ones failed in additionInfo + int counter = 0; + for (ComponentIdentifier ci : baseCompList) { + counter++; + additionalInfo.append(String.format("%d;", ci.hashCode())); + } + if (counter > 0) { + additionalInfo.insert(0, "COMPID="); + additionalInfo.append(counter); + } + } + + if (fieldValidation) { + return new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID); + } else { + return new AppraisalStatus(FAIL, resultMessage.toString(), additionalInfo.toString()); + } + } + + private static String validateV2PlatformCredentialAttributes( + final UUID certificateId, + final List fullDeltaChainComponents, + final List allDeviceInfoComponents) { + ComponentIdentifierV2 ciV2; + StringBuilder invalidPcIds = new StringBuilder(); + List subCompIdList = fullDeltaChainComponents + .stream().collect(Collectors.toList()); + List subCompInfoList = allDeviceInfoComponents + .stream().collect(Collectors.toList()); + + // Delta is the baseline + for (ComponentInfo cInfo : allDeviceInfoComponents) { + for (ComponentIdentifier cId : fullDeltaChainComponents) { + ciV2 = (ComponentIdentifierV2) cId; + if (cInfo.getComponentClass().contains( + ciV2.getComponentClass().getComponentIdentifier()) + && isMatch(certificateId, cId, cInfo)) { + subCompIdList.remove(cId); + subCompInfoList.remove(cInfo); + } + } + } + + if (subCompIdList.isEmpty()) { + return Strings.EMPTY; + } else { + // now we return everything that was unmatched + // what is in the component info/device reported components + // is to be displayed as the failure + fullDeltaChainComponents.clear(); + for (ComponentIdentifier ci : subCompIdList) { + if (ci.isVersion2() && PciIds.DB.isReady()) { + ci = PciIds.translate((ComponentIdentifierV2) ci); + } + log.error("Unmatched component: " + ci); + fullDeltaChainComponents.add(ci); + invalidPcIds.append(String.format( + "Manufacturer=%s, Model=%s, Serial=%s, Revision=%s;%n", + ci.getComponentManufacturer(), + ci.getComponentModel(), + ci.getComponentSerial(), + ci.getComponentRevision())); + } + } + + return invalidPcIds.toString(); + } + + private static String validateDeltaChain( + final Map deltaMapping, + final List baseCompList, + final List leftOvers, + final List absentSerials, + final List chainCertificates) { + StringBuilder resultMessage = new StringBuilder(); + List noneSerialValues = new ArrayList<>(); + noneSerialValues.add(""); + noneSerialValues.add(null); + noneSerialValues.add("Not Specified"); + noneSerialValues.add("To Be Filled By O.E.M."); + + // map the components throughout the chain + Map chainCiMapping = new HashMap<>(); + baseCompList.stream().forEach((ci) -> { + if (!noneSerialValues.contains(ci.getComponentSerial().toString())) { + chainCiMapping.put(ci.getComponentSerial().toString(), ci); + } else { + absentSerials.add(ci); + } + }); + + String ciSerial; + List certificateList = null; + SupplyChainValidation scv = null; + // go through the leaf and check the changes against the valid components + // forget modifying validOrigPcComponents + for (PlatformCredential delta : chainCertificates) { + StringBuilder failureMsg = new StringBuilder(); + certificateList = new ArrayList<>(); + certificateList.add(delta); + + for (ComponentIdentifier ci : delta.getComponentIdentifiers()) { + if (!noneSerialValues.contains(ci.getComponentSerial().toString())) { + if (ci.isVersion2()) { + ciSerial = ci.getComponentSerial().toString(); + ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) ci; + if (ciV2.isModified()) { + // this won't match + // check it is there + if (chainCiMapping.containsKey(ciSerial)) { + chainCiMapping.put(ciSerial, ci); + } else { + failureMsg.append(String.format( + "%s attempted MODIFIED with no prior instance.%n", + ciSerial)); + delta.setComponentFailures(String.format("%s,%d", + delta.getComponentFailures(), ciV2.hashCode())); + scv = deltaMapping.get(delta); + if (scv != null + && scv.getValidationResult() != PASS) { + failureMsg.append(scv.getMessage()); + } + deltaMapping.put(delta, new SupplyChainValidation( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + FAIL, + certificateList, + failureMsg.toString())); + } + } else if (ciV2.isRemoved()) { + if (!chainCiMapping.containsKey(ciSerial)) { + // error thrown, can't remove if it doesn't exist + failureMsg.append(String.format( + "%s attempted REMOVED with no prior instance.%n", + ciSerial)); + delta.setComponentFailures(String.format("%s,%d", + delta.getComponentFailures(), ciV2.hashCode())); + scv = deltaMapping.get(delta); + if (scv != null + && scv.getValidationResult() != PASS) { + failureMsg.append(scv.getMessage()); + } + deltaMapping.put(delta, new SupplyChainValidation( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + FAIL, + certificateList, + failureMsg.toString())); + } else { + chainCiMapping.remove(ciSerial); + } + } else if (ciV2.isAdded()) { + // ADDED + if (chainCiMapping.containsKey(ciSerial)) { + // error, shouldn't exist + failureMsg.append(String.format( + "%s was ADDED, the serial already exists.%n", + ciSerial)); + delta.setComponentFailures(String.format("%s,%d", + delta.getComponentFailures(), ciV2.hashCode())); + scv = deltaMapping.get(delta); + if (scv != null + && scv.getValidationResult() != PASS) { + failureMsg.append(scv.getMessage()); + } + deltaMapping.put(delta, new SupplyChainValidation( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + FAIL, + certificateList, + failureMsg.toString())); + } else { + // have to add in case later it is removed + chainCiMapping.put(ciSerial, ci); + } + } + } + } else { + if (ci.isVersion2() && ((ComponentIdentifierV2) ci).isModified()) { + ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) ci; + // Look for singular component of same make/model/class + ComponentIdentifier candidate = null; + for (ComponentIdentifier search : absentSerials) { + if (!search.isVersion2()) { + continue; + } + ComponentIdentifierV2 noSerialV2 = (ComponentIdentifierV2) search; + + if (noSerialV2.getComponentClass().getComponentIdentifier().equals( + ciV2.getComponentClass().getComponentIdentifier()) + && isMatch(noSerialV2, ciV2)) { + if (candidate == null) { + candidate = noSerialV2; + } else { + // This only works if there is one matching component + candidate = null; + break; + } + } + } + + if (candidate != null) { + absentSerials.remove(candidate); + absentSerials.add(ciV2); + } else { + leftOvers.add(ci); + } + } else { + // found a delta ci with no serial + // add to list + leftOvers.add(ci); + } + } + } + + resultMessage.append(failureMsg.toString()); + } + baseCompList.clear(); + baseCompList.addAll(chainCiMapping.values()); + baseCompList.addAll(absentSerials); + + return resultMessage.toString(); + } + + /** + * Compares the component information from the device info report against those of the + * platform credential. All components in the platform credential should exactly match one + * component in the device info report. The device info report is allowed to have extra + * components not represented in the platform credential. + * + * @param untrimmedPcComponents the platform credential components (may contain end whitespace) + * **NEW** this is updated with just the unmatched components + * if there are any failures, otherwise it remains unchanged. + * @param allDeviceInfoComponents the device info report components + * @return true if validation passes + */ + private static String validateV2p0PlatformCredentialComponentsExpectingExactMatch( + final UUID certificateId, + final List untrimmedPcComponents, + final List allDeviceInfoComponents) { + // For each manufacturer listed in the platform credential, create two lists: + // 1. a list of components listed in the platform credential for the manufacturer, and + // 2. a list of components listed in the device info for the same manufacturer + // Then eliminate matches from both lists. Finally, decide if the validation passes based + // on the leftovers in the lists and the policy in place. + final List pcComponents = new ArrayList<>(); + for (ComponentIdentifier component : untrimmedPcComponents) { + if (component.getComponentManufacturer() != null) { + component.setComponentManufacturer(new DERUTF8String( + component.getComponentManufacturer().getString().trim())); + } + if (component.getComponentModel() != null) { + component.setComponentModel(new DERUTF8String( + component.getComponentModel().getString().trim())); + } + if (component.getComponentSerial() != null) { + component.setComponentSerial(new DERUTF8String( + component.getComponentSerial().getString().trim())); + } + if (component.getComponentRevision() != null) { + component.setComponentRevision(new DERUTF8String( + component.getComponentRevision().getString().trim())); + } + pcComponents.add(component); + } + + log.info("Validating the following Platform Cert components..."); + pcComponents.forEach(component -> log.info(component.toString())); + log.info("...against the the following DeviceInfoReport components:"); + allDeviceInfoComponents.forEach(component -> log.info(component.toString())); + Set manufacturerSet = new HashSet<>(); + pcComponents.forEach(pcComp -> manufacturerSet.add(pcComp.getComponentManufacturer())); + + // Create a list for unmatched components across all manufacturers to display at the end. + List pcUnmatchedComponents = new ArrayList<>(); + + for (DERUTF8String derUtf8Manufacturer : manufacturerSet) { + List pcComponentsFromManufacturer + = pcComponents.stream().filter(compIdentifier + -> compIdentifier.getComponentManufacturer().equals(derUtf8Manufacturer)) + .collect(Collectors.toList()); + + String pcManufacturer = derUtf8Manufacturer.getString(); + List deviceInfoComponentsFromManufacturer + = allDeviceInfoComponents.stream().filter(componentInfo + -> componentInfo.getComponentManufacturer().equals(pcManufacturer)) + .collect(Collectors.toList()); + // For each component listed in the platform credential from this manufacturer + // find the ones that specify a serial number so we can match the most specific ones + // first. + List pcComponentsFromManufacturerWithSerialNumber + = pcComponentsFromManufacturer.stream().filter(compIdentifier + -> compIdentifier.getComponentSerial() != null + && StringUtils.isNotEmpty(compIdentifier.getComponentSerial().getString())) + .collect(Collectors.toList()); + // Now match up the components from the device info that are from the same + // manufacturer and have a serial number. As matches are found, remove them from + // both lists. + for (ComponentIdentifier pcComponent + : pcComponentsFromManufacturerWithSerialNumber) { + Optional first + = deviceInfoComponentsFromManufacturer.stream() + .filter(componentInfo + -> StringUtils.isNotEmpty(componentInfo.getComponentSerial())) + .filter(componentInfo -> componentInfo.getComponentSerial() + .equals(pcComponent.getComponentSerial().getString())).findFirst(); + + if (first.isPresent()) { + ComponentInfo potentialMatch = first.get(); + if (isMatch(certificateId, pcComponent, potentialMatch)) { + pcComponentsFromManufacturer.remove(pcComponent); + deviceInfoComponentsFromManufacturer.remove(potentialMatch); + } + } + } + // For each component listed in the platform credential from this manufacturer + // find the ones that specify value for the revision field so we can match the most + // specific ones first. + List pcComponentsFromManufacturerWithRevision + = pcComponentsFromManufacturer.stream().filter(compIdentifier + -> compIdentifier.getComponentRevision() != null + && StringUtils.isNotEmpty(compIdentifier.getComponentRevision().getString())) + .collect(Collectors.toList()); + // Now match up the components from the device info that are from the same + // manufacturer and specify a value for the revision field. As matches are found, + // remove them from both lists. + for (ComponentIdentifier pcComponent + : pcComponentsFromManufacturerWithRevision) { + Optional first + = deviceInfoComponentsFromManufacturer.stream() + .filter(info -> StringUtils.isNotEmpty(info.getComponentRevision())) + .filter(info -> info.getComponentRevision() + .equals(pcComponent.getComponentRevision().getString())) + .findFirst(); + + if (first.isPresent()) { + ComponentInfo potentialMatch = first.get(); + if (isMatch(certificateId, pcComponent, potentialMatch)) { + pcComponentsFromManufacturer.remove(pcComponent); + deviceInfoComponentsFromManufacturer.remove(potentialMatch); + } + } + } + // The remaining components from the manufacturer have only the 2 required fields so + // just match them. + List templist = new ArrayList<>(pcComponentsFromManufacturer); + for (ComponentIdentifier ci : templist) { + Iterator diComponentIter + = deviceInfoComponentsFromManufacturer.iterator(); + while (diComponentIter.hasNext()) { + ComponentInfo potentialMatch = diComponentIter.next(); + if (isMatch(certificateId, ci, potentialMatch)) { + pcComponentsFromManufacturer.remove(ci); + diComponentIter.remove(); + } + } + } + pcUnmatchedComponents.addAll(pcComponentsFromManufacturer); + } + + if (!pcUnmatchedComponents.isEmpty()) { + untrimmedPcComponents.clear(); + StringBuilder sb = new StringBuilder(); + log.error(String.format("Platform Credential contained %d unmatched components:", + pcUnmatchedComponents.size())); + + int unmatchedComponentCounter = 1; + for (ComponentIdentifier unmatchedComponent : pcUnmatchedComponents) { + if (unmatchedComponent.isVersion2() && PciIds.DB.isReady()) { + unmatchedComponent = + PciIds.translate((ComponentIdentifierV2) unmatchedComponent); + } + log.error("Unmatched component " + unmatchedComponentCounter++ + ": " + + unmatchedComponent); + sb.append(String.format("Manufacturer=%s, Model=%s, Serial=%s, Revision=%s;%n", + unmatchedComponent.getComponentManufacturer(), + unmatchedComponent.getComponentModel(), + unmatchedComponent.getComponentSerial(), + unmatchedComponent.getComponentRevision())); + unmatchedComponent.setValidationResult(false); + untrimmedPcComponents.add(unmatchedComponent); + } + return sb.toString(); + } + return Strings.EMPTY; + } + + /** + * Checks if the fields in the potentialMatch match the fields in the pcComponent, + * or if the relevant field in the pcComponent is empty. + * @param certificateId the certificate id + * @param pcComponent the platform credential component + * @param potentialMatch the component info from a device info report + * @return true if the fields match exactly (null is considered the same as an empty string) + */ + private static boolean isMatch(final UUID certificateId, + final ComponentIdentifier pcComponent, + final ComponentInfo potentialMatch) { + boolean matchesSoFar = true; + + matchesSoFar &= isMatchOrEmptyInPlatformCert( + potentialMatch.getComponentManufacturer(), + pcComponent.getComponentManufacturer() + ); + + if (matchesSoFar) { + componentResultList.add(new ComponentResult(certificateId, pcComponent.hashCode(), + potentialMatch.getComponentSerial(), + pcComponent.getComponentSerial().getString())); + } + + matchesSoFar &= isMatchOrEmptyInPlatformCert( + potentialMatch.getComponentModel(), + pcComponent.getComponentModel() + ); + + if (matchesSoFar) { + componentResultList.add(new ComponentResult(certificateId, pcComponent.hashCode(), + potentialMatch.getComponentSerial(), + pcComponent.getComponentSerial().getString())); + } + + matchesSoFar &= isMatchOrEmptyInPlatformCert( + potentialMatch.getComponentSerial(), + pcComponent.getComponentSerial() + ); + + if (matchesSoFar) { + componentResultList.add(new ComponentResult(certificateId, pcComponent.hashCode(), + potentialMatch.getComponentSerial(), + pcComponent.getComponentSerial().getString())); + } + + matchesSoFar &= isMatchOrEmptyInPlatformCert( + potentialMatch.getComponentRevision(), + pcComponent.getComponentRevision() + ); + + if (matchesSoFar) { + componentResultList.add(new ComponentResult(certificateId, pcComponent.hashCode(), + potentialMatch.getComponentSerial(), + pcComponent.getComponentSerial().getString())); + } + + return matchesSoFar; + } + + + /** + * Checks if the fields in the potentialMatch match the fields in the pcComponent, + * or if the relevant field in the pcComponent is empty. + * @param pcComponent the platform credential component + * @param potentialMatch the component info from a device info report + * @return true if the fields match exactly (null is considered the same as an empty string) + */ + private static boolean isMatch(final ComponentIdentifierV2 pcComponent, + final ComponentIdentifierV2 potentialMatch) { + boolean matchesSoFar = true; + + matchesSoFar &= isMatchOrEmptyInPlatformCert( + potentialMatch.getComponentManufacturer(), + pcComponent.getComponentManufacturer()); + + matchesSoFar &= isMatchOrEmptyInPlatformCert( + potentialMatch.getComponentModel(), + pcComponent.getComponentModel()); + + return matchesSoFar; + } + + private static boolean isMatchOrEmptyInPlatformCert( + final String evidenceFromDevice, + final DERUTF8String valueInPlatformCert) { + if (valueInPlatformCert == null || StringUtils.isEmpty(valueInPlatformCert.getString())) { + return true; + } + return valueInPlatformCert.getString().equals(evidenceFromDevice); + } + + private static boolean isMatchOrEmptyInPlatformCert( + final DERUTF8String evidenceFromDevice, + final DERUTF8String valueInPlatformCert) { + return evidenceFromDevice.equals(valueInPlatformCert); + } + + /** + * Validates the platform credential's serial numbers with the device info's set of + * serial numbers. + * @param credentialBoardSerialNumber the PC board S/N + * @param credentialChassisSerialNumber the PC chassis S/N + * @param deviceInfoSerialNumbers the map of device info serial numbers with descriptions. + * @return the changed validation status + */ + private static AppraisalStatus validatePlatformSerialsWithDeviceSerials( + final String credentialBoardSerialNumber, final String credentialChassisSerialNumber, + final Map deviceInfoSerialNumbers) { + boolean boardSerialNumberFound = false; + boolean chassisSerialNumberFound = false; + + if (StringUtils.isNotEmpty(credentialBoardSerialNumber)) { + boardSerialNumberFound = deviceInfoContainsPlatformSerialNumber( + credentialBoardSerialNumber, "board serial number", deviceInfoSerialNumbers); + } + if (StringUtils.isNotEmpty(credentialChassisSerialNumber)) { + chassisSerialNumberFound = deviceInfoContainsPlatformSerialNumber( + credentialChassisSerialNumber, + "chassis serial number", deviceInfoSerialNumbers); + } + + if (boardSerialNumberFound || chassisSerialNumberFound) { + log.info("The platform credential's board or chassis serial number matched" + + " with a serial number from the client's device information"); + return new AppraisalStatus(PASS, PLATFORM_ATTRIBUTES_VALID); + } + log.error("The platform credential's board and chassis serial numbers did" + + " not match with any device info's serial numbers"); + + return new AppraisalStatus(FAIL, "Platform serial did not match device info"); + } + + /** + * Checks if a platform credential's serial number matches ANY of the device information's + * set of serial numbers. + * @param platformSerialNumber the platform serial number to compare + * @param platformSerialNumberDescription description of the serial number for logging purposes. + * @param deviceInfoSerialNumbers the map of device info serial numbers + * (key = description, value = serial number) + * @return true if the platform serial number was found (case insensitive search), + * false otherwise + */ + private static boolean deviceInfoContainsPlatformSerialNumber( + final String platformSerialNumber, final String platformSerialNumberDescription, + final Map deviceInfoSerialNumbers) { + // check to see if the platform serial number is contained in the map of device info's + // serial numbers + for (Map.Entry entry : deviceInfoSerialNumbers.entrySet()) { + if (entry.getValue().equalsIgnoreCase(platformSerialNumber)) { + log.info("Device info contained platform {} {}" + + " in the device info's {}", platformSerialNumberDescription, + platformSerialNumber, entry.getKey()); + return true; + } + } + + log.warn("Platform {}, {}, did not match any device info serial numbers", + platformSerialNumberDescription, platformSerialNumber); + return false; + } + + /** + * Validates the information supplied for the Platform Credential. This + * method checks if the field is required and therefore if the value is + * present then verifies that the values match. + * @param platformCredentialFieldName name of field to be compared + * @param platformCredentialFieldValue first value to compare + * @param otherValue second value to compare + * @return true if values match + */ + private static boolean requiredPlatformCredentialFieldIsNonEmptyAndMatches( + final String platformCredentialFieldName, + final String platformCredentialFieldValue, + final String otherValue) { + if (hasEmptyValueForRequiredField(platformCredentialFieldName, + platformCredentialFieldValue)) { + return false; + } + + return platformCredentialFieldMatches(platformCredentialFieldName, + platformCredentialFieldValue, otherValue); + } + + /** + * Validates the information supplied for the Platform Credential. This + * method checks if the value is present then verifies that the values match. + * If not present, then returns true. + * @param platformCredentialFieldName name of field to be compared + * @param platformCredentialFieldValue first value to compare + * @param otherValue second value to compare + * @return true if values match or null + */ + private static boolean optionalPlatformCredentialFieldNullOrMatches( + final String platformCredentialFieldName, + final String platformCredentialFieldValue, + final String otherValue) { + if (platformCredentialFieldValue == null) { + return true; + } + + return platformCredentialFieldMatches(platformCredentialFieldName, + platformCredentialFieldValue, otherValue); + } + + /** + * Returns true if fieldValue is null or empty. + * @param description description of the value + * @param fieldValue value of the field + * @return true if fieldValue is null or empty; false otherwise + */ + private static boolean hasEmptyValueForRequiredField(final String description, + final String fieldValue) { + if (StringUtils.isEmpty(fieldValue)) { + log.error("Required field was empty or null in Platform Credential: " + + description); + return true; + } + return false; + } + + private static boolean platformCredentialFieldMatches( + final String platformCredentialFieldName, + final String platformCredentialFieldValue, + final String otherValue) { + String trimmedFieldValue = platformCredentialFieldValue.trim(); + String trimmedOtherValue = otherValue.trim(); + + if (!trimmedFieldValue.equals(trimmedOtherValue)) { + log.debug(String.format("%s field in Platform Credential (%s) does not match " + + "a related field in the DeviceInfoReport (%s)", + platformCredentialFieldName, trimmedFieldValue, trimmedOtherValue)); + return false; + } + + log.debug(String.format("%s field in Platform Credential matches " + + "a related field in the DeviceInfoReport (%s)", + platformCredentialFieldName, trimmedFieldValue) + ); + + return true; + } + + /** + * Returns true if fieldValue is null or empty. + * @param description description of the value + * @param fieldValue value of the field + * @return true if fieldValue is null or empty; false otherwise + */ + private static boolean hasEmptyValueForRequiredField(final String description, + final DERUTF8String fieldValue) { + if (fieldValue == null || StringUtils.isEmpty(fieldValue.getString().trim())) { + log.error("Required field was empty or null in Platform Credential: " + + description); + return true; + } + return false; + } +} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java new file mode 100644 index 00000000..d34b8233 --- /dev/null +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java @@ -0,0 +1,258 @@ +package hirs.attestationca.persist.validation; + +import hirs.attestationca.persist.entity.manager.CACredentialRepository; +import hirs.attestationca.persist.entity.manager.CertificateRepository; +import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository; +import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository; +import hirs.attestationca.persist.entity.userdefined.Device; +import hirs.attestationca.persist.entity.userdefined.PolicySettings; +import hirs.attestationca.persist.entity.userdefined.ReferenceManifest; +import hirs.attestationca.persist.entity.userdefined.SupplyChainValidation; +import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential; +import hirs.attestationca.persist.entity.userdefined.rim.BaseReferenceManifest; +import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements; +import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue; +import hirs.attestationca.persist.enums.AppraisalStatus; +import hirs.attestationca.persist.service.ValidationManager; +import hirs.utils.SwidResource; +import hirs.utils.tpm.eventlog.TCGEventLog; +import hirs.utils.tpm.eventlog.TpmPcrEvent; +import lombok.extern.log4j.Log4j2; +import org.apache.logging.log4j.Level; + +import java.io.IOException; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; + +import static hirs.attestationca.persist.enums.AppraisalStatus.Status.FAIL; +import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS; + +@Log4j2 +public class FirmwareScvValidator extends SupplyChainCredentialValidator { + + private static PcrValidator pcrValidator; + + @SuppressWarnings("methodlength") + public static AppraisalStatus validateFirmware( + final Device device, final PolicySettings policySettings, + final ReferenceManifestRepository referenceManifestRepository, + final ReferenceDigestValueRepository referenceDigestValueRepository, + final CACredentialRepository caCredentialRepository) { + boolean passed = true; + String[] baseline = new String[Integer.SIZE]; + AppraisalStatus fwStatus = null; + String manufacturer = device.getDeviceInfo() + .getHardwareInfo().getManufacturer(); + String model = device.getDeviceInfo() + .getHardwareInfo().getProductName(); + ReferenceManifest validationObject; + List baseReferenceManifests = null; + BaseReferenceManifest baseReferenceManifest = null; + ReferenceManifest supportReferenceManifest = null; + EventLogMeasurements measurement = null; + + baseReferenceManifests = referenceManifestRepository.findAllBaseRims(); + + for (BaseReferenceManifest bRim : baseReferenceManifests) { + if (bRim.getPlatformManufacturer().equals(manufacturer) + && !bRim.isSwidSupplemental() && !bRim.isSwidPatch()) { + baseReferenceManifest = bRim; + } + } + + String failedString = ""; + if (baseReferenceManifest == null) { + failedString = "Base Reference Integrity Manifest\n"; + passed = false; + } else { + measurement = (EventLogMeasurements) referenceManifestRepository.findByHexDecHash( + baseReferenceManifest.getEventLogHash()); + + if (measurement == null) { + measurement = referenceManifestRepository.getLogByModel( + baseReferenceManifest.getPlatformModel()); + } + } + + if (measurement == null) { + failedString += "Bios measurement"; + passed = false; + } + validationObject = measurement; + + if (passed) { + List resources = + ((BaseReferenceManifest) baseReferenceManifest).getFileResources(); + fwStatus = new AppraisalStatus(PASS, + SupplyChainCredentialValidator.FIRMWARE_VALID); + + // verify signatures + ReferenceManifestValidator referenceManifestValidator = + new ReferenceManifestValidator(); + referenceManifestValidator.setRim(baseReferenceManifest); + + //Validate signing cert + List allCerts = caCredentialRepository.findAll(); + CertificateAuthorityCredential signingCert = null; + for (CertificateAuthorityCredential cert : allCerts) { + signingCert = cert; + KeyStore keyStore = ValidationManager.getCaChain(signingCert, + caCredentialRepository); + if (referenceManifestValidator.validateXmlSignature(signingCert)) { + try { + if (!SupplyChainCredentialValidator.verifyCertificate( + signingCert.getX509Certificate(), keyStore)) { + passed = false; + fwStatus = new AppraisalStatus(FAIL, + "Firmware validation failed: invalid certificate path."); + validationObject = baseReferenceManifest; + } + } catch (IOException e) { + log.error("Error getting X509 cert from manager: " + e.getMessage()); + } catch (SupplyChainValidatorException e) { + log.error("Error validating cert against keystore: " + e.getMessage()); + fwStatus = new AppraisalStatus(FAIL, + "Firmware validation failed: invalid certificate path."); + } + break; + } + } + + for (SwidResource swidRes : resources) { + supportReferenceManifest = referenceManifestRepository.findByHexDecHash( + swidRes.getHashValue()); + if (supportReferenceManifest != null) { + // Removed the filename check from this if statement + referenceManifestValidator.validateSupportRimHash( + supportReferenceManifest.getRimBytes(), swidRes.getHashValue()); + } + } + + if (passed && signingCert == null) { + passed = false; + fwStatus = new AppraisalStatus(FAIL, + "Firmware validation failed: signing cert not found."); + } + + if (passed && supportReferenceManifest == null) { + fwStatus = new AppraisalStatus(FAIL, + "Support Reference Integrity Manifest can not be found"); + passed = false; + } + + if (passed && !referenceManifestValidator.isSignatureValid()) { + passed = false; + fwStatus = new AppraisalStatus(FAIL, + "Firmware validation failed: Signature validation " + + "failed for Base RIM."); + } + + if (passed && !referenceManifestValidator.isSupportRimValid()) { + passed = false; + fwStatus = new AppraisalStatus(FAIL, + "Firmware validation failed: Hash validation " + + "failed for Support RIM."); + } + + if (passed) { + TCGEventLog logProcessor; + try { + logProcessor = new TCGEventLog(supportReferenceManifest.getRimBytes()); + baseline = logProcessor.getExpectedPCRValues(); + } catch (CertificateException cEx) { + log.error(cEx); + } catch (NoSuchAlgorithmException noSaEx) { + log.error(noSaEx); + } catch (IOException ioEx) { + log.error(ioEx); + } + + // part 1 of firmware validation check: PCR baseline match + pcrValidator = new PcrValidator(baseline); + + if (baseline.length > 0) { + String pcrContent = ""; + pcrContent = new String(device.getDeviceInfo().getTpmInfo().getPcrValues()); + + if (pcrContent.isEmpty()) { + fwStatus = new AppraisalStatus(FAIL, + "Firmware validation failed: Client did not " + + "provide pcr values."); + log.warn(String.format( + "Firmware validation failed: Client (%s) did not " + + "provide pcr values.", device.getName())); + } else { + // we have a full set of PCR values + //int algorithmLength = baseline[0].length(); + //String[] storedPcrs = buildStoredPcrs(pcrContent, algorithmLength); + //pcrPolicy.validatePcrs(storedPcrs); + + // part 2 of firmware validation check: bios measurements + // vs baseline tcg event log + // find the measurement + TCGEventLog tcgMeasurementLog; + LinkedList tpmPcrEvents = new LinkedList<>(); + List eventValue; + HashMap eventValueMap = new HashMap<>(); + try { + if (measurement.getPlatformManufacturer().equals(manufacturer)) { + tcgMeasurementLog = new TCGEventLog(measurement.getRimBytes()); + eventValue = referenceDigestValueRepository + .findValuesByBaseRimId(baseReferenceManifest.getId()); + for (ReferenceDigestValue rdv : eventValue) { + eventValueMap.put(rdv.getDigestValue(), rdv); + } + + tpmPcrEvents.addAll(pcrValidator.validateTpmEvents( + tcgMeasurementLog, eventValueMap, policySettings)); + } + } catch (CertificateException cEx) { + log.error(cEx); + } catch (NoSuchAlgorithmException noSaEx) { + log.error(noSaEx); + } catch (IOException ioEx) { + log.error(ioEx); + } + + if (!tpmPcrEvents.isEmpty()) { + StringBuilder sb = new StringBuilder(); + validationObject = measurement; + sb.append(String.format("%d digest(s) were not found:%n", + tpmPcrEvents.size())); + for (TpmPcrEvent tpe : tpmPcrEvents) { + sb.append(String.format("PCR Index %d - %s%n", + tpe.getPcrIndex(), + tpe.getEventTypeStr())); + } + if (fwStatus.getAppStatus().equals(FAIL)) { + fwStatus = new AppraisalStatus(FAIL, String.format("%s%n%s", + fwStatus.getMessage(), sb.toString())); + } else { + fwStatus = new AppraisalStatus(FAIL, sb.toString()); + } + } + } + } else { + fwStatus = new AppraisalStatus(FAIL, "The RIM baseline could not be found."); + } + } + + EventLogMeasurements eventLog = measurement; + eventLog.setOverallValidationResult(fwStatus.getAppStatus()); + referenceManifestRepository.save(eventLog); + } else { + fwStatus = new AppraisalStatus(FAIL, String.format("Firmware Validation failed: " + + "%s for %s can not be found", failedString, manufacturer)); + if (measurement != null) { + measurement.setOverallValidationResult(fwStatus.getAppStatus()); + referenceManifestRepository.save(measurement); + } + } + + return fwStatus; + } +} From cb5b281d03b24c75f72f4710117151aa4229c498 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Thu, 21 Sep 2023 16:25:01 -0400 Subject: [PATCH 04/26] Missed updated constructor for Device --- .../persist/entity/userdefined/Device.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/Device.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/Device.java index b01c0bbb..118cd3d7 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/Device.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/Device.java @@ -58,6 +58,16 @@ public class Device extends AbstractEntity { @Column(name = "summary_id") private String summaryId; + public Device(final DeviceInfoReport deviceInfoReport) { + super(); + if (deviceInfoReport != null) { + this.name = deviceInfoReport.getNetworkInfo().getHostname(); + this.deviceInfo = deviceInfoReport; + } else { + name = ""; + } + } + public String toString() { return String.format("Device Name: %s%nStatus: %s%nSummary: %s", name, healthStatus.getStatus(), From a08c007bba104c2ffebfca997f72e46944d98ab6 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Fri, 22 Sep 2023 11:50:28 -0400 Subject: [PATCH 05/26] Some additional updates and changes while debugging --- .../persist/entity/AbstractEntity.java | 2 +- .../attributes/ComponentClass.java | 2 +- .../provision/AbstractRequestHandler.java | 5 ++-- .../service/SupplyChainValidationService.java | 9 +++--- .../validation/CredentialValidator.java | 13 +++++++++ .../SupplyChainCredentialValidator.java | 4 --- .../ValidationReportsPageController.java | 29 ------------------- .../utils/tpm/eventlog/uefi/UefiGuid.java | 4 +-- 8 files changed, 24 insertions(+), 44 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/AbstractEntity.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/AbstractEntity.java index a647b1da..204b6dfd 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/AbstractEntity.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/AbstractEntity.java @@ -40,7 +40,7 @@ public abstract class AbstractEntity implements Serializable { @Column (name = "create_time") @ColumnDefault(value = "CURRENT_TIMESTAMP") @Generated(GenerationTime.INSERT) - private Date createTime; + private Date createTime = new Date(); /** * Default empty constructor is required for Hibernate. It is protected to diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java index a666f4e3..40d9a5cc 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java @@ -30,7 +30,7 @@ public class ComponentClass { private static final String TCG_COMPONENT_REGISTRY = "2.23.133.18.3.1"; private static final String SMBIOS_COMPONENT_REGISTRY = "2.23.133.18.3.3"; private static final Path JSON_PATH = FileSystems.getDefault() - .getPath("/etc", "hirs/aca", "default-properties", "component-class.json"); + .getPath("/opt", "hirs", "default-properties", "component-class.json"); private static final String OTHER_STRING = "Other"; private static final String UNKNOWN_STRING = "Unknown"; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractRequestHandler.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractRequestHandler.java index 18bb3f54..14ed80ba 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractRequestHandler.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractRequestHandler.java @@ -233,8 +233,8 @@ public class AbstractRequestHandler { final Device device) { IssuedAttestationCertificate issuedAc; boolean generateCertificate = true; - PolicyRepository scp = this.getPolicyRepository(); - PolicySettings policySettings = scp.findByName("Default"); + PolicyRepository scp = getPolicyRepository(); + PolicySettings policySettings; Date currentDate = new Date(); int days; try { @@ -243,6 +243,7 @@ public class AbstractRequestHandler { derEncodedAttestationCertificate, endorsementCredential, platformCredentials); if (scp != null) { + policySettings = scp.findByName("Default"); issuedAc = certificateRepository.findByDeviceId(device.getId()); generateCertificate = policySettings.isIssueAttestationCertificate(); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java index 1c6e9ec1..1ef73d12 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java @@ -105,9 +105,9 @@ public class SupplyChainValidationService { .ValidationType.PLATFORM_CREDENTIAL; log.info("Beginning Supply Chain Validation..."); - log.info("Beginning Endorsement Credential Validation..."); // Validate the Endorsement Credential if (getPolicySettings().isEcValidationEnabled()) { + log.info("Beginning Endorsement Credential Validation..."); validations.add(ValidationManager.evaluateEndorsementCredentialStatus(ec, this.caCredentialRepository, acceptExpiredCerts)); // store the device with the credential if (ec != null) { @@ -116,9 +116,9 @@ public class SupplyChainValidationService { } } - log.info("Beginning Platform Credential Validation..."); // Validate Platform Credential signatures if (getPolicySettings().isPcValidationEnabled()) { + log.info("Beginning Platform Credential Validation..."); // Ensure there are platform credentials to validate if (pcs == null || pcs.isEmpty()) { log.error("There were no Platform Credentials to validate."); @@ -143,7 +143,6 @@ public class SupplyChainValidationService { } pc.setDeviceId(device.getId()); this.certificateRepository.save(pc); - } // check that the delta certificates validity date is after @@ -179,10 +178,10 @@ public class SupplyChainValidationService { } } - log.info("Beginning Platform Attributes Validation..."); // Validate Platform Credential attributes if (getPolicySettings().isPcAttributeValidationEnabled() && pcErrorMessage.isEmpty()) { + log.info("Beginning Platform Attributes Validation..."); // Ensure there are platform credentials to validate SupplyChainValidation attributeScv = null; String attrErrorMessage = ""; @@ -233,8 +232,8 @@ public class SupplyChainValidationService { } } - log.info("Beginning Firmware Validation..."); if (getPolicySettings().isFirmwareValidationEnabled()) { + log.info("Beginning Firmware Validation..."); // may need to associated with device to pull the correct info // compare tpm quote with what is pulled from RIM associated file validations.add(ValidationManager.evaluateFirmwareStatus(device, getPolicySettings(), diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java index 2084cfe9..52e75efe 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java @@ -47,6 +47,19 @@ public class CredentialValidator extends SupplyChainCredentialValidator { return new AppraisalStatus(FAIL, message); } + boolean keyInStore = false; + try { + keyInStore = trustStore.size() < 1; + } catch (KeyStoreException ksEx) { + log.error(ksEx.getMessage()); + } + + if (keyInStore) { + message = baseErrorMessage + "keys in the trust store"; + log.error(message); + return new AppraisalStatus(FAIL, message); + } + try { X509Certificate verifiableCert = ec.getX509Certificate(); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java index bcdc9d92..d951fe54 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java @@ -3,15 +3,11 @@ package hirs.attestationca.persist.validation; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult; -import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier; -import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2; import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo; import lombok.NoArgsConstructor; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.util.Strings; -import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.CertException; import org.bouncycastle.cert.X509AttributeCertificateHolder; 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 590a5030..e2a5f5db 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 @@ -2,13 +2,11 @@ package hirs.attestationca.portal.page.controllers; import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import hirs.attestationca.persist.CriteriaModifier; import hirs.attestationca.persist.FilteredRecordsList; import hirs.attestationca.persist.entity.manager.CertificateRepository; import hirs.attestationca.persist.entity.manager.DeviceRepository; import hirs.attestationca.persist.entity.manager.PlatformCertificateRepository; import hirs.attestationca.persist.entity.manager.SupplyChainValidationSummaryRepository; -import hirs.attestationca.persist.entity.userdefined.Certificate; import hirs.attestationca.persist.entity.userdefined.Device; import hirs.attestationca.persist.entity.userdefined.SupplyChainValidationSummary; import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; @@ -16,18 +14,13 @@ import hirs.attestationca.persist.entity.userdefined.certificate.attributes.Comp import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2; import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableResponse; -import hirs.attestationca.portal.datatables.OrderedListQueryDataTableAdapter; import hirs.attestationca.portal.page.Page; import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.params.NoPageParams; import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Root; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.log4j.Log4j2; -import org.hibernate.Session; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -43,7 +36,6 @@ import org.springframework.web.servlet.ModelAndView; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; -import java.lang.ref.Reference; import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.LocalDateTime; @@ -52,7 +44,6 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; -import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -128,20 +119,6 @@ public class ValidationReportsPageController extends PageController scvRoot = criteriaQuery.from(Reference.class); - - criteriaQuery.select(scvRoot).distinct(true).where(cb.isNull(scvRoot.get(Certificate.ARCHIVE_FIELD))); - } - }; - FilteredRecordsList records = new FilteredRecordsList<>(); int currentPage = input.getStart() / input.getLength(); Pageable paging = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName)); @@ -153,12 +130,6 @@ public class ValidationReportsPageController extends PageController records = -// OrderedListQueryDataTableAdapter.getOrderedList( -// SupplyChainValidationSummary.class, -// supplyChainValidatorSummaryRepository, input, orderColumnName, -// criteriaModifier); - return new DataTableResponse<>(records, input); } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiGuid.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiGuid.java index aa83f937..5530258c 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiGuid.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiGuid.java @@ -23,8 +23,8 @@ public class UefiGuid { */ private static final int UUID_EPOCH_DIVISOR = 10000; - private static final Path JSON_PATH = FileSystems.getDefault().getPath("/etc", - "hirs/aca", "default-properties", "vendor-table.json"); + private static final Path JSON_PATH = FileSystems.getDefault().getPath("/opt", + "hirs", "default-properties", "vendor-table.json"); private JsonObject uefiVendorRef; /** * guid byte array. From b3481f166858a4362466bd07699eae24a9fdecb8 Mon Sep 17 00:00:00 2001 From: iadgovuser29 <33426478+iadgovuser29@users.noreply.github.com> Date: Sun, 24 Sep 2023 11:59:32 -0400 Subject: [PATCH 06/26] Use protobuf-gradle-plugin to replace a system dependency --- HIRS_AttestationCA/build.gradle | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/HIRS_AttestationCA/build.gradle b/HIRS_AttestationCA/build.gradle index 31806ddd..04a80074 100644 --- a/HIRS_AttestationCA/build.gradle +++ b/HIRS_AttestationCA/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id 'io.spring.dependency-management' version '1.1.0' + id 'com.google.protobuf' version '0.9.4' } java { @@ -50,13 +51,18 @@ dependencies { annotationProcessor libs.lombok } -task generateProtoBuf(type:Exec) { - workingDir 'config' - - commandLine './genJavaProtoBuf.sh' +protobuf { + protoc { + artifact = 'com.google.protobuf:protoc:3.24.3' + } +} +sourceSets { + main { + proto { + srcDir '../HIRS_ProvisionerTPM2/src' + } + } } - -compileJava.dependsOn generateProtoBuf test { useJUnitPlatform() From 9c0d934331ea1de9ff29477de3926b963a968638 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Mon, 25 Sep 2023 10:38:33 -0400 Subject: [PATCH 07/26] Fixed icon display issue. The validationResult name changed --- .../src/main/webapp/WEB-INF/jsp/validation-reports.jsp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp index a42b1336..f74fdbe8 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/validation-reports.jsp @@ -68,17 +68,17 @@ // create status icon var result = full.overallValidationResult; - var ovallMessage = full.message; + var overallMessage = full.message; if (result) { switch (result) { case "PASS": html += ''; break; case "FAIL": - html += ''; + html += ''; break; case "ERROR": - html += ''; + html += ''; break; default: html += unknownStatus; @@ -183,7 +183,7 @@ // the validation_type. for (var i = 0; i < full.validations.length; i++) { var curValidation = full.validations[i]; - var curResult = curValidation.result; + var curResult = curValidation.validationResult; var curMessage = curValidation.message; if (curValidation.validationType === validation_type) { From 5c31e52828c1a177f20dba63b3472eabe9dcf63c Mon Sep 17 00:00:00 2001 From: iadgovuser26 Date: Wed, 27 Sep 2023 14:40:18 -0400 Subject: [PATCH 08/26] moved connector uri to application.properties --- 10 | 0 HIRS_AttestationCAPortal/build.gradle | 13 ++++++- .../src/main/resources/hibernate.properties | 2 +- package/scripts/aca/aca_bootRun.sh | 10 +++-- package/scripts/aca/aca_remove_setup.sh | 6 ++- package/scripts/aca/aca_setup.sh | 27 ++++++++++---- package/scripts/aca/check_for_aca.sh | 19 ++++++++++ package/scripts/db/db_create.sh | 37 ++++++++++++++++++- package/scripts/db/mysql_util.sh | 32 ++++++++-------- package/scripts/pki/pki_setup.sh | 3 ++ 10 files changed, 117 insertions(+), 32 deletions(-) create mode 100644 10 create mode 100644 package/scripts/aca/check_for_aca.sh diff --git a/10 b/10 new file mode 100644 index 00000000..e69de29b diff --git a/HIRS_AttestationCAPortal/build.gradle b/HIRS_AttestationCAPortal/build.gradle index 386074e2..94868efa 100644 --- a/HIRS_AttestationCAPortal/build.gradle +++ b/HIRS_AttestationCAPortal/build.gradle @@ -73,6 +73,15 @@ ospackage { addParentDirs = true createDirectoryEntry true + // copy json tables + into ('/etc/hirs/aca/default-properties') { + from '../HIRS_AttestationCA/src/main/resources/component-class.json' + from '../HIRS_AttestationCA/src/main/resources/vendor-table.json' + } + // copy springboot property file + into ('/etc/hirs/aca/') { + from '../HIRS_AttestationCAPortal/src/main/resources/application.properties' + } // copy setup scripts to /opt/hirs/aca into ('/opt/hirs/aca/scripts/') { from '../package/scripts/' @@ -89,11 +98,13 @@ ospackage { // add chrontab to run ACA at boot postInstall 'echo "@reboot root /opt/hirs/aca/scripts/aca/aca_bootRun.sh -w" >> /etc/crontab' // run ACA after install - postInstall '/opt/hirs/aca/scripts/aca/aca_bootRun.sh -w' + postInstall '/opt/hirs/aca/scripts/aca/aca_bootRun.sh -w &' postInstall 'chmod +x /opt/hirs/aca/scripts/aca/*' + postInstall 'sh /opt/hirs/aca/scripts/aca/check_for_aca.sh' // Uninstall preUninstall 'sh /opt/hirs/aca/scripts/aca/aca_remove_setup.sh' + postUninstall 'rm -rf /etc/hirs' buildRpm { arch = X86_64 diff --git a/HIRS_AttestationCAPortal/src/main/resources/hibernate.properties b/HIRS_AttestationCAPortal/src/main/resources/hibernate.properties index 6cca0a71..e19198d2 100644 --- a/HIRS_AttestationCAPortal/src/main/resources/hibernate.properties +++ b/HIRS_AttestationCAPortal/src/main/resources/hibernate.properties @@ -1,4 +1,4 @@ -#hibernate.connection.url=jdbc:mariadb://localhost:3306/hirs_db?autoReconnect=true&useSSL=false +hibernate.connection.url=jdbc:mariadb://localhost:3306/hirs_db?autoReconnect=true&sslMode=DISABLED #hibernate.connection.username=hirs_db #hibernate.connection.password=hirs_db hibernate.connection.driver_class=org.mariadb.jdbc.Driver diff --git a/package/scripts/aca/aca_bootRun.sh b/package/scripts/aca/aca_bootRun.sh index 2d2fba01..441b010d 100755 --- a/package/scripts/aca/aca_bootRun.sh +++ b/package/scripts/aca/aca_bootRun.sh @@ -6,7 +6,7 @@ # ##################################################################################### -CONFIG_FILE="/etc/hirs/aca/application.properties" +SPRING_PROP_FILE="/etc/hirs/aca/application.properties" ALG=RSA RSA_PATH=rsa_3k_sha384_certs ECC_PATH=ecc_512_sha384_certs @@ -108,7 +108,7 @@ source /etc/hirs/aca/aca.properties; # Run the embedded tomcat server with Web TLS enabled and database client TLS enabled by overrding critical parameters # Note "&" is a sub parameter continuation, space represents a new parameter. Spaces and quotes matter. -# hibernate.connection.url is used for the DB connector which established DB TLS connectivity +# hibernate.connection.url is used fo r the DB connector which established DB TLS connectivity # server.ssl arguments support the embeded tomcats use of TLS for the ACA Portal CONNECTOR_PARAMS="--hibernate.connection.url=jdbc:mariadb://localhost:3306/hirs_db?autoReconnect=true&\ user=$hirs_db_username&\ @@ -127,8 +127,10 @@ WEB_TLS_PARAMS="--server.ssl.key-store-password=$hirs_pki_password \ if [ -z "$USE_WAR" ]; then echo "Booting the ACA from local build..." - ./gradlew bootRun --args="$CONNECTOR_PARAMS$WEB_TLS_PARAMS" + # ./gradlew bootRun --args="$CONNECTOR_PARAMS$WEB_TLS_PARAMS" + ./gradlew bootRun --args="--spring.config.location=$SPRING_PROP_FILE" else echo "Booting the ACA from a war file..." - java -jar $WAR_PATH $CONNECTOR_PARAMS$WEB_TLS_PARAMS & + # java -jar $WAR_PATH $CONNECTOR_PARAMS$WEB_TLS_PARAMS & +java -jar $WAR_PATH --spring.config.location=$SPRING_PROP_FILE fi diff --git a/package/scripts/aca/aca_remove_setup.sh b/package/scripts/aca/aca_remove_setup.sh index 0282069e..6cb473e5 100755 --- a/package/scripts/aca/aca_remove_setup.sh +++ b/package/scripts/aca/aca_remove_setup.sh @@ -25,9 +25,11 @@ pushd $SCRIPT_DIR/../db/ &>/dev/null sh db_drop.sh $DB_ADMIN_PWD popd &>/dev/null -# remove pki files and config files +# remove pki files and config files if not installed by rpm echo "Removing certificates and config files..." -rm -rf /etc/hirs +if [ ! -d /opt/hirs/aca ]; then + rm -rf /etc/hirs +fi # Remove crontab and current ACA process echo "Removing the ACA crontab" diff --git a/package/scripts/aca/aca_setup.sh b/package/scripts/aca/aca_setup.sh index 253647f9..d3561c32 100755 --- a/package/scripts/aca/aca_setup.sh +++ b/package/scripts/aca/aca_setup.sh @@ -1,12 +1,20 @@ #!/bin/bash +##################################################################################### +# +# Script to create ACA setup files and configure the hirs_db database. +# +# +##################################################################################### # Capture location of the script to allow from invocation from any location SCRIPT_DIR=$( dirname -- "$( readlink -f -- "$0"; )"; ) HIRS_CONF_DIR=/etc/hirs/aca LOG_FILE_NAME="hirs_aca_install_"$(date +%Y-%m-%d).log LOG_DIR="/var/log/hirs/" LOG_FILE="$LOG_DIR$LOG_FILE_NAME" -HIRS_PROP_DIR="/opt/hirs/default-properties" HIRS_JSON_DIR="/etc/hirs/aca/default-properties" +ACA_PROP_FILE="/etc/hirs/aca/aca.properties" +SPRING_PROP_FILE="/etc/hirs/aca/application.properties" +PROP_FILE='../../../HIRS_AttestationCAPortal/src/main/resources/application.properties' COMP_JSON='../../../HIRS_AttestationCA/src/main/resources/component-class.json' VENDOR_TABLE='../../../HIRS_AttestationCA/src/main/resources/vendor-table.json' @@ -58,10 +66,16 @@ done set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters -mkdir -p $HIRS_CONF_DIR $LOG_DIR $HIRS_PROP_DIR $HIRS_JSON_DIR +mkdir -p $HIRS_CONF_DIR $LOG_DIR $HIRS_JSON_DIR +touch "$LOG_FILE" -cp -n $COMP_JSON $HIRS_JSON_DIR/ -cp -n $VENDOR_TABLE $HIRS_JSON_DIR/ +pushd $SCRIPT_DIR &>/dev/null +# Check if build environment is being used and set up property files +if [ -f $PROP_FILE ]; then + cp -n $PROP_FILE $HIRS_CONF_DIR/ + cp -n $COMP_JSON $HIRS_JSON_DIR/ + cp -n $VENDOR_TABLE $HIRS_JSON_DIR/ +fi echo "ACA setup log file is $LOG_FILE" @@ -70,11 +84,8 @@ if [ "$EUID" -ne 0 ] exit 1 fi -touch "$LOG_FILE" echo "HIRS ACA Setup initiated on $(date +%Y-%m-%d)" >> "$LOG_FILE" -pushd $SCRIPT_DIR &>/dev/null - # Set HIRS PKI password if [ -z $HIRS_PKI_PWD ]; then # Create a 32 character random password @@ -98,7 +109,7 @@ if [ -z "${ARG_SKIP_PKI}" ]; then fi if [ -z "${ARG_SKIP_DB}" ]; then - sh ../db/db_create.sh $LOG_FILE $ARG_UNATTEND + sh ../db/db_create.sh $LOG_FILE $PKI_PASS $ARG_UNATTEND if [ $? -eq 0 ]; then echo "ACA database setup complete" | tee -a "$LOG_FILE" else diff --git a/package/scripts/aca/check_for_aca.sh b/package/scripts/aca/check_for_aca.sh new file mode 100644 index 00000000..62c57378 --- /dev/null +++ b/package/scripts/aca/check_for_aca.sh @@ -0,0 +1,19 @@ +#!/bin/bash +######################################################################################## +# Checks for ACA portal page on the local device +# Waits for tomcat (ACA) to respond or times out after 20 seconds +# +######################################################################################### + +ACA_URL="https://localhost:8443/HIRS_AttestationCAPortal/portal/index" +echo "Waiting for tomcat..." + count=0 + until [ "`curl --silent --connect-timeout 1 --insecure -I $ACA_URL | grep -c 'Date'`" == 1 ] || [[ $count -gt 20 ]]; do + ((count++)) + sleep 1 + done + if [[ $count -gt 20 ]]; then + echo "Timed out waiting for tomcat to respond" + else + echo "Tomcat (ACA) started" + fi \ No newline at end of file diff --git a/package/scripts/db/db_create.sh b/package/scripts/db/db_create.sh index a57644ba..e723ec9f 100755 --- a/package/scripts/db/db_create.sh +++ b/package/scripts/db/db_create.sh @@ -8,7 +8,10 @@ ################################################################################ LOG_FILE=$1 -UNATTENDED=$2 +PKI_PASS=$2 +UNATTENDED=$3 +RSA_PATH=rsa_3k_sha384_certs +ECC_PATH=ecc_512_sha384_certs # Capture location of the script to allow from invocation from any location SCRIPT_DIR=$( dirname -- "$( readlink -f -- "$0"; )"; ) SPRING_PROP_FILE="/etc/hirs/aca/application.properties" @@ -128,6 +131,8 @@ set_hirs_db_pwd () { echo "hirs_db_username=hirs_db" >> $ACA_PROP_FILE echo "hirs_db_password=$HIRS_DB_PWD" >> $ACA_PROP_FILE + echo "hibernate.connection.username=hirs_db" >> $SPRING_PROP_FILE + echo "hibernate.connection.password=$HIRS_DB_PWD" >> $SPRING_PROP_FILE fi } @@ -145,6 +150,35 @@ create_hirs_db_with_tls () { fi } +# Create a JDBC connector used by hibernate and place in Springs application.properties +create_hibernate_url () { + ALG=$1 + db_username=$2 + + if [ $ALG = "RSA" ]; then + CERT_PATH="/etc/hirs/certificates/HIRS/$RSA_PATH" + CERT_CHAIN="$CERT_PATH/HIRS_rsa_3k_sha384_Cert_Chain.pem" + CLIENT_DB_P12=$CERT_PATH/HIRS_db_client_rsa_3k_sha384.p12 + ALIAS="hirs_aca_tls_rsa_3k_sha384" + else + CERT_PATH="/etc/hirs/certificates/HIRS/$ECC_PATH" + CERT_CHAIN="$CERT_PATH/HIRS_ecc_512_sha384_Cert_Chain.pem" + CLIENT_DB_P12=$CERT_PATH/HIRS_db_client_ecc_512_sha384.p12 + ALIAS="hirs_aca_tls_ecc_512_sha384" + fi + +CONNECTOR_URL="hibernate.connection.url=jdbc:mariadb://localhost:3306/hirs_db?autoReconnect=true&\ +user=$db_username&\ +password=$HIRS_DB_PWD&\ +sslMode=VERIFY_CA&\ +serverSslCert=$CERT_CHAIN&\ +keyStoreType=PKCS12&\ +keyStorePassword=$PKI_PASS&\ +keyStore="$CLIENT_DB_P12" " + +echo $CONNECTOR_URL >> $SPRING_PROP_FILE + +} # HIRS ACA Mysqld processing ... check_mariadb_install check_for_container -p @@ -154,4 +188,5 @@ start_mysqlsd check_mysql_root_pwd set_hirs_db_pwd create_hirs_db_with_tls +create_hibernate_url "RSA" "hirs_db" mysqld_reboot diff --git a/package/scripts/db/mysql_util.sh b/package/scripts/db/mysql_util.sh index df8bf860..f2eefeb7 100755 --- a/package/scripts/db/mysql_util.sh +++ b/package/scripts/db/mysql_util.sh @@ -48,27 +48,28 @@ start_mysqlsd () { # Check if mariadb is setup if [ ! -d "/var/lib/mysql/mysql/" ]; then echo "Installing mariadb" - /usr/bin/mysql_install_db & >> "$LOG_FILE" - chown -R mysql:mysql /var/lib/mysql/ & >> "$LOG_FILE" + /usr/bin/mysql_install_db >> "$LOG_FILE" + chown -R mysql:mysql /var/lib/mysql/ >> "$LOG_FILE" + fi + if [[ $PRINT_STATUS == "-p" ]]; then echo "Starting mysql..."; fi + touch /var/log/mariadb/mariadb.log + chown mysql:mysql /var/log/mariadb/mariadb.log >> "$LOG_FILE"; + /usr/bin/mysqld_safe & >> "$LOG_FILE"; + echo "Attempting to start mariadb" + else #not a container + systemctl enable $SQL_SERVICE & >> "$LOG_FILE"; + systemctl start $SQL_SERVICE & >> "$LOG_FILE"; fi - if [[ $PRINT_STATUS == "-p" ]]; then echo "Starting mysql..."; fi - chown -R mysql:mysql /var/log/mariadb >> "$LOG_FILE"; - /usr/bin/mysqld_safe & >> "$LOG_FILE"; - else #not a container - systemctl enable $SQL_SERVICE & >> "$LOG_FILE"; - systemctl start $SQL_SERVICE & >> "$LOG_FILE"; - fi else # mysql process is running - # check if mysql service is running + # check if mysql service is running if [ ! $DOCKER_CONTAINER = true ]; then - DB_STATUS=$(systemctl status mysql |grep 'running' | wc -l ) + DB_STATUS=$(systemctl status mysql |grep 'running' | wc -l ) if [ $DB_STATUS -eq 0 ]; then echo "mariadb not running , attempting to restart" - systemctl start mariadb & >> "$LOG_FILE"; + systemctl start mariadb >> "$LOG_FILE"; fi - fi + fi # non contanier mysql start fi - # Wait for mysql to start before continuing. if [[ $PRINT_STATUS == "-p" ]]; then echo "Checking mysqld status..."| tee -a "$LOG_FILE"; fi while ! mysqladmin ping -h "$localhost" --silent; do @@ -142,7 +143,7 @@ check_db_cleared () { echo " Mysql Root password is not empty" fi HIRS_DB_USER_EXISTS="$(mysql -uroot -sse "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'hirs_db')")" - if [ $HIRS_DB_USER_EXISTS = 1 ]; then + if [[ $HIRS_DB_USER_EXISTS == 1 ]]; then echo " hirs_db user exists" else echo " hirs_db user does not exist" @@ -155,6 +156,7 @@ check_db_cleared () { echo " hirs_db database does not exists" fi } + # restart maraidb mysqld_reboot () { # reboot mysql server diff --git a/package/scripts/pki/pki_setup.sh b/package/scripts/pki/pki_setup.sh index db16f0a1..5a28142b 100755 --- a/package/scripts/pki/pki_setup.sh +++ b/package/scripts/pki/pki_setup.sh @@ -8,6 +8,7 @@ #PROP_FILE=/etc/hirs/aca/application.properties ACA_PROP=/etc/hirs/aca/aca.properties +SPRING_PROP_FILE="/etc/hirs/aca/application.properties" LOG_FILE=$1 PKI_PASS=$2 UNATTENDED=$3 @@ -56,6 +57,8 @@ if [ ! -d "/etc/hirs/certificates" ]; then popd &> /dev/null echo "hirs_pki_password="$PKI_PASS >> $ACA_PROP + echo "server.ssl.key-store-password="$PKI_PASS >> $SPRING_PROP_FILE + echo "server.ssl.trust-store-password="$PKI_PASS >> $SPRING_PROP_FILE else echo "/etc/hirs/certificates exists, skipping" | tee -a "$LOG_FILE" fi From c046851e07a98d91a977c39f3017aa5837d4d631 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Thu, 28 Sep 2023 06:47:43 -0400 Subject: [PATCH 09/26] Latest changes that fixes little issues --- .../persist/entity/AbstractEntity.java | 3 ++ .../service/SupplyChainValidationService.java | 5 +++ ...eferenceManifestDetailsPageController.java | 8 ++--- .../ReferenceManifestPageController.java | 31 +++---------------- .../src/main/webapp/WEB-INF/jsp/error.jsp | 18 +++++++++-- .../src/main/webapp/WEB-INF/jsp/help.jsp | 6 +++- 6 files changed, 37 insertions(+), 34 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/AbstractEntity.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/AbstractEntity.java index 204b6dfd..e89249c6 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/AbstractEntity.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/AbstractEntity.java @@ -67,6 +67,9 @@ public abstract class AbstractEntity implements Serializable { * @return creation time */ public Date getCreateTime() { + if (createTime == null) { + createTime = new Date(); + } return (Date) createTime.clone(); } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java index 1ef73d12..c3ac6a91 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java @@ -8,6 +8,7 @@ import hirs.attestationca.persist.entity.manager.ComponentResultRepository; import hirs.attestationca.persist.entity.manager.PolicyRepository; import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository; import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository; +import hirs.attestationca.persist.entity.manager.SupplyChainValidationRepository; import hirs.attestationca.persist.entity.manager.SupplyChainValidationSummaryRepository; import hirs.attestationca.persist.entity.userdefined.Device; import hirs.attestationca.persist.entity.userdefined.PolicySettings; @@ -47,6 +48,7 @@ public class SupplyChainValidationService { private ReferenceDigestValueRepository referenceDigestValueRepository; private ComponentResultRepository componentResultRepository; private CertificateRepository certificateRepository; + private SupplyChainValidationRepository supplyChainValidationRepository; private SupplyChainValidationSummaryRepository supplyChainValidationSummaryRepository; /** @@ -57,6 +59,7 @@ public class SupplyChainValidationService { * @param certificateRepository the cert manager * @param componentResultRepository the comp result manager * @param referenceManifestRepository the RIM manager + * @param supplyChainValidationRepository the scv manager * @param supplyChainValidationSummaryRepository the summary manager * @param referenceDigestValueRepository the even manager */ @@ -68,6 +71,7 @@ public class SupplyChainValidationService { final CertificateRepository certificateRepository, final ComponentResultRepository componentResultRepository, final ReferenceManifestRepository referenceManifestRepository, + final SupplyChainValidationRepository supplyChainValidationRepository, final SupplyChainValidationSummaryRepository supplyChainValidationSummaryRepository, final ReferenceDigestValueRepository referenceDigestValueRepository) { this.caCredentialRepository = caCredentialRepository; @@ -75,6 +79,7 @@ public class SupplyChainValidationService { this.certificateRepository = certificateRepository; this.componentResultRepository = componentResultRepository; this.referenceManifestRepository = referenceManifestRepository; + this.supplyChainValidationRepository = supplyChainValidationRepository; this.supplyChainValidationSummaryRepository = supplyChainValidationSummaryRepository; this.referenceDigestValueRepository = referenceDigestValueRepository; } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java index 110bbd00..cd07a8a1 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java @@ -266,8 +266,8 @@ public class ReferenceManifestDetailsPageController extends PageController rimRoot = criteriaQuery.from(Reference.class); - - criteriaQuery.select(rimRoot).distinct(true).where(cb.isNull(rimRoot.get(Certificate.ARCHIVE_FIELD))); - } - }; - log.info("Querying with the following dataTableInput: " + input.toString()); FilteredRecordsList records = new FilteredRecordsList<>(); @@ -144,15 +124,14 @@ public class ReferenceManifestPageController extends PageController pagedResult = referenceManifestRepository.findAll(paging); if (pagedResult.hasContent()) { - records.addAll(pagedResult.getContent()); + for (ReferenceManifest manifest : pagedResult.getContent()) { + if (!manifest.getRimType().equals(ReferenceManifest.MEASUREMENT_RIM)) { + records.add(manifest); + } + } } records.setRecordsTotal(input.getLength()); records.setRecordsFiltered(referenceManifestRepository.count()); -// FilteredRecordsList records -// = OrderedListQueryDataTableAdapter.getOrderedList( -// ReferenceManifest.class, -// this.referenceManifestRepository, -// input, orderColumnName, criteriaModifier); log.debug("Returning list of size: " + records.size()); return new DataTableResponse<>(records, input); diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/error.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/error.jsp index da7f58f9..88bb8877 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/error.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/error.jsp @@ -1,3 +1,15 @@ -

-Page Not Found! Devices -
\ No newline at end of file +<%@page contentType="text/html" pageEncoding="UTF-8"%> + +<%-- JSP TAGS --%> +<%@taglib prefix="c" uri="jakarta.tags.core" %> +<%@taglib prefix="my" tagdir="/WEB-INF/tags"%> + +<%-- CONTENT --%> + + Error - 404 + + + + + \ No newline at end of file diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/help.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/help.jsp index 4ec2a763..c6d478a3 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/help.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/help.jsp @@ -10,12 +10,16 @@

Documentation

+ -

For more documentation on the project, you may visit the wiki section of our code repository.

+

+ For more documentation on the project, you may visit the wiki section of our code repository. +

\ No newline at end of file From 8be945035dde8118956653074a9efd219de7873d Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Thu, 28 Sep 2023 17:11:34 -0400 Subject: [PATCH 10/26] Some additional updates to fix visual changes on the screen. This one is mainly with deviceName --- .../provision/AbstractRequestHandler.java | 4 +++- .../provision/IdentityClaimHandler.java | 2 +- .../provision/IdentityRequestHandler.java | 2 +- .../helper/CredentialManagementHelper.java | 4 +++- .../validation/CredentialValidator.java | 4 ++-- .../validation/FirmwareScvValidator.java | 21 +++++++++---------- .../controllers/DevicePageController.java | 6 +++--- .../jsp/endorsement-key-credentials.jsp | 8 +------ .../WEB-INF/jsp/issued-certificates.jsp | 7 +------ .../WEB-INF/jsp/platform-credentials.jsp | 8 +------ 10 files changed, 26 insertions(+), 40 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractRequestHandler.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractRequestHandler.java index 14ed80ba..c7c7e27c 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractRequestHandler.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractRequestHandler.java @@ -137,7 +137,8 @@ public class AbstractRequestHandler { if (identityClaim.hasEndorsementCredential()) { endorsementCredential = CredentialManagementHelper.storeEndorsementCredential( certificateRepository, - identityClaim.getEndorsementCredential().toByteArray()); + identityClaim.getEndorsementCredential().toByteArray(), + identityClaim.getDv().getNw().getHostname()); } else if (ekPub != null) { log.warn("Endorsement Cred was not in the identity claim from the client." + " Checking for uploads."); @@ -261,6 +262,7 @@ public class AbstractRequestHandler { } } if (generateCertificate) { + attCert.setDeviceId(device.getId()); attCert.setDeviceName(device.getName()); certificateRepository.save(attCert); } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimHandler.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimHandler.java index 4dc3458c..07fc0f52 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimHandler.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimHandler.java @@ -105,7 +105,7 @@ public class IdentityClaimHandler extends AbstractRequestHandler { * @return an identity claim response for the specified request containing a wrapped blob */ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) { - log.error("Identity Claim received..."); + log.info("Identity Claim received..."); if (ArrayUtils.isEmpty(identityClaim)) { log.error("Identity claim empty throwing exception."); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityRequestHandler.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityRequestHandler.java index 142179e4..b2188d56 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityRequestHandler.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityRequestHandler.java @@ -110,7 +110,7 @@ public class IdentityRequestHandler extends AbstractRequestHandler { byte[] ecBytesFromIdentityRequest = proof.getEndorsementCredential(); if (ArrayUtils.isNotEmpty(ecBytesFromIdentityRequest)) { endorsementCredential = CredentialManagementHelper.storeEndorsementCredential( - this.certificateRepository, ecBytesFromIdentityRequest); + this.certificateRepository, ecBytesFromIdentityRequest, ""); try { BigInteger publicKeyModulus = Certificate.getPublicKeyModulus( endorsementCredential.getX509Certificate()); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java index 1b99e2e2..4d684665 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java @@ -27,12 +27,13 @@ public final class CredentialManagementHelper { * it is unarchived. * @param certificateRepository the certificate manager used for storage * @param endorsementBytes the raw EK bytes used for parsing + * @param deviceName the host name * @return the parsed, valid EK * @throws IllegalArgumentException if the provided bytes are not a valid EK. */ public static EndorsementCredential storeEndorsementCredential( final CertificateRepository certificateRepository, - final byte[] endorsementBytes) throws IllegalArgumentException { + final byte[] endorsementBytes, final String deviceName) throws IllegalArgumentException { if (certificateRepository == null) { throw new IllegalArgumentException("null certificate manager"); @@ -64,6 +65,7 @@ public final class CredentialManagementHelper { .findByCertificateHash(certificateHash); if (existingCredential == null) { log.info("No Endorsement Credential found with hash: " + certificateHash); + endorsementCredential.setDeviceName(deviceName); return (EndorsementCredential) certificateRepository.save(endorsementCredential); } else if (existingCredential.isArchived()) { // if the EK is stored in the DB and it's archived, unarchive. diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java index 52e75efe..be48a5e7 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java @@ -109,13 +109,13 @@ public class CredentialValidator extends SupplyChainCredentialValidator { String message; String certVerifyMsg; if (pc == null) { - message = baseErrorMessage + "a platform credential\n"; + message = baseErrorMessage + "a platform credential"; log.error(message); return new AppraisalStatus(FAIL, message); } try { if (trustStore == null || trustStore.size() == 0) { - message = baseErrorMessage + "an Issuer Cert in the Trust Store\n"; + message = baseErrorMessage + "an Issuer Cert in the Trust Store"; log.error(message); return new AppraisalStatus(FAIL, message); } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java index d34b8233..fb1778c0 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java @@ -45,10 +45,9 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator { boolean passed = true; String[] baseline = new String[Integer.SIZE]; AppraisalStatus fwStatus = null; + String hostName = device.getDeviceInfo().getNetworkInfo().getHostname(); String manufacturer = device.getDeviceInfo() .getHardwareInfo().getManufacturer(); - String model = device.getDeviceInfo() - .getHardwareInfo().getProductName(); ReferenceManifest validationObject; List baseReferenceManifests = null; BaseReferenceManifest baseReferenceManifest = null; @@ -58,7 +57,7 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator { baseReferenceManifests = referenceManifestRepository.findAllBaseRims(); for (BaseReferenceManifest bRim : baseReferenceManifests) { - if (bRim.getPlatformManufacturer().equals(manufacturer) + if (bRim.getDeviceName().equals(hostName) && !bRim.isSwidSupplemental() && !bRim.isSwidPatch()) { baseReferenceManifest = bRim; } @@ -73,8 +72,8 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator { baseReferenceManifest.getEventLogHash()); if (measurement == null) { - measurement = referenceManifestRepository.getLogByModel( - baseReferenceManifest.getPlatformModel()); + measurement = referenceManifestRepository.byMeasurementDeviceName( + baseReferenceManifest.getDeviceName()); } } @@ -111,10 +110,10 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator { "Firmware validation failed: invalid certificate path."); validationObject = baseReferenceManifest; } - } catch (IOException e) { - log.error("Error getting X509 cert from manager: " + e.getMessage()); - } catch (SupplyChainValidatorException e) { - log.error("Error validating cert against keystore: " + e.getMessage()); + } catch (IOException ioEx) { + log.error("Error getting X509 cert from manager: " + ioEx.getMessage()); + } catch (SupplyChainValidatorException scvEx) { + log.error("Error validating cert against keystore: " + scvEx.getMessage()); fwStatus = new AppraisalStatus(FAIL, "Firmware validation failed: invalid certificate path."); } @@ -199,7 +198,7 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator { List eventValue; HashMap eventValueMap = new HashMap<>(); try { - if (measurement.getPlatformManufacturer().equals(manufacturer)) { + if (measurement.getDeviceName().equals(hostName)) { tcgMeasurementLog = new TCGEventLog(measurement.getRimBytes()); eventValue = referenceDigestValueRepository .findValuesByBaseRimId(baseReferenceManifest.getId()); @@ -246,7 +245,7 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator { referenceManifestRepository.save(eventLog); } else { fwStatus = new AppraisalStatus(FAIL, String.format("Firmware Validation failed: " - + "%s for %s can not be found", failedString, manufacturer)); + + "%s for %s can not be found", failedString, hostName)); if (measurement != null) { measurement.setOverallValidationResult(fwStatus.getAppStatus()); referenceManifestRepository.save(measurement); diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java index a7a479da..693e85a2 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java @@ -131,10 +131,11 @@ public class DevicePageController extends PageController { issuedCertificateList.addAll(issuedCertificateRepository.findByDeviceId(id)); } + HashMap> certificatePropertyMap; // loop all the devices for (Device device : deviceList) { // hashmap containing the list of certificates based on the certificate type - HashMap> certificatePropertyMap = new HashMap<>(); + certificatePropertyMap = new HashMap<>(); deviceCertMap.put("device", device); String deviceName; @@ -179,8 +180,7 @@ public class DevicePageController extends PageController { } for (IssuedAttestationCertificate ic : issuedCertificateList) { - deviceName = deviceRepository.findById(ic.getDeviceId()).get().getName(); - + deviceName = ic.getDeviceName(); // set the certificate if it's the same ID if (device.getName().equals(deviceName)) { String certificateId = IssuedAttestationCertificate.class.getSimpleName(); diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/endorsement-key-credentials.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/endorsement-key-credentials.jsp index 75706028..e31d10ed 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/endorsement-key-credentials.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/endorsement-key-credentials.jsp @@ -52,13 +52,7 @@ data: 'deviceName', render: function (data, type, full, meta) { // if there's a device, display its name, otherwise - // display nothing - if (full.device) { - // TODO render a link to a device details page, - // passing the device.id - return full.deviceName; - } - return ''; + return full.deviceName; } }, {data: 'issuer'}, diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/issued-certificates.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/issued-certificates.jsp index 0ed637bb..4e2be128 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/issued-certificates.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/issued-certificates.jsp @@ -48,12 +48,7 @@ render: function (data, type, full, meta) { // if there's a device, display its name, otherwise // display nothing - if (full.device) { - // TODO render a link to a device details page, - // passing the device.id - return full.deviceName; - } - return ''; + return full.deviceName; } }, {data: 'issuer'}, diff --git a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/platform-credentials.jsp b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/platform-credentials.jsp index defb07e1..178c0391 100644 --- a/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/platform-credentials.jsp +++ b/HIRS_AttestationCAPortal/src/main/webapp/WEB-INF/jsp/platform-credentials.jsp @@ -57,13 +57,7 @@ data: 'deviceName', render: function (data, type, full, meta) { // if there's a device, display its name, otherwise - // display nothing - if (full.device) { - // TODO render a link to a device details page, - // passing the device.id - return full.deviceName; - } - return ''; + return full.deviceName; } }, {data: 'issuer'}, From 31066694eee24c7168fbf81d8b816d84d9cf598a Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Fri, 29 Sep 2023 08:18:54 -0400 Subject: [PATCH 11/26] Updates to the location of default property files and setting the deviceName --- .../attributes/ComponentClass.java | 2 +- .../service/SupplyChainValidationService.java | 2 ++ .../CertificatePageController.java | 24 +++++++++---------- .../utils/tpm/eventlog/uefi/UefiGuid.java | 9 +++---- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java index 40d9a5cc..21509339 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/attributes/ComponentClass.java @@ -30,7 +30,7 @@ public class ComponentClass { private static final String TCG_COMPONENT_REGISTRY = "2.23.133.18.3.1"; private static final String SMBIOS_COMPONENT_REGISTRY = "2.23.133.18.3.3"; private static final Path JSON_PATH = FileSystems.getDefault() - .getPath("/opt", "hirs", "default-properties", "component-class.json"); + .getPath("/etc", "hirs", "aca", "default-properties", "component-class.json"); private static final String OTHER_STRING = "Other"; private static final String UNKNOWN_STRING = "Unknown"; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java index c3ac6a91..e9e44d77 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java @@ -117,6 +117,7 @@ public class SupplyChainValidationService { // store the device with the credential if (ec != null) { ec.setDeviceId(device.getId()); + ec.setDeviceName(device.getDeviceInfo().getNetworkInfo().getHostname()); this.certificateRepository.save(ec); } } @@ -147,6 +148,7 @@ public class SupplyChainValidationService { deltaMapping.put(pc, null); } pc.setDeviceId(device.getId()); + pc.setDeviceName(device.getDeviceInfo().getNetworkInfo().getHostname()); this.certificateRepository.save(pc); } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java index f6f6a59a..60a81689 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java @@ -832,11 +832,11 @@ public class CertificatePageController extends PageController { log.error(failMessage, dEx); messages.addError(failMessage + dEx.getMessage()); return null; - } catch (IllegalArgumentException e) { + } catch (IllegalArgumentException iaEx) { final String failMessage = String.format( "Certificate format not recognized(%s): ", fileName); - log.error(failMessage, e); - messages.addError(failMessage + e.getMessage()); + log.error(failMessage, iaEx); + messages.addError(failMessage + iaEx.getMessage()); return null; } } @@ -864,11 +864,11 @@ public class CertificatePageController extends PageController { existingCertificate = getCertificateByHash( certificateType, certificate.getCertificateHash()); - } catch (DBServiceException e) { + } catch (DBServiceException dbsEx) { final String failMessage = "Querying for existing certificate failed (" + fileName + "): "; - messages.addError(failMessage + e.getMessage()); - log.error(failMessage, e); + messages.addError(failMessage + dbsEx.getMessage()); + log.error(failMessage, dbsEx); return; } @@ -924,11 +924,11 @@ public class CertificatePageController extends PageController { log.info(successMsg); return; } - } catch (DBServiceException e) { + } catch (DBServiceException dbsEx) { final String failMessage = String.format("Storing new certificate failed (%s): ", fileName); - messages.addError(failMessage + e.getMessage()); - log.error(failMessage, e); + messages.addError(failMessage + dbsEx.getMessage()); + log.error(failMessage, dbsEx); return; } @@ -946,12 +946,12 @@ public class CertificatePageController extends PageController { log.info(successMsg); return; } - } catch (DBServiceException e) { + } catch (DBServiceException dbsEx) { final String failMessage = String.format("Found an identical" + " pre-existing certificate in the " + "archive, but failed to unarchive it (%s): ", fileName); - messages.addError(failMessage + e.getMessage()); - log.error(failMessage, e); + messages.addError(failMessage + dbsEx.getMessage()); + log.error(failMessage, dbsEx); return; } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiGuid.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiGuid.java index 5530258c..6c63ee2e 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiGuid.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiGuid.java @@ -23,8 +23,8 @@ public class UefiGuid { */ private static final int UUID_EPOCH_DIVISOR = 10000; - private static final Path JSON_PATH = FileSystems.getDefault().getPath("/opt", - "hirs", "default-properties", "vendor-table.json"); + private static final Path JSON_PATH = FileSystems.getDefault().getPath("/etc", + "hirs", "aca", "default-properties", "vendor-table.json"); private JsonObject uefiVendorRef; /** * guid byte array. @@ -175,10 +175,7 @@ public class UefiGuid { * @return true if the uuid is the Empty UUID, false if not */ public boolean isUnknownUUID() { - if (getVendorTableReference().equals("Unknown GUID reference")) { - return true; - } - return false; + return getVendorTableReference().equals("Unknown GUID reference"); } /** From 4de125c0f81a6d278c98c1b2e8996d03a549cddd Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Tue, 3 Oct 2023 09:53:48 -0400 Subject: [PATCH 12/26] After some code review, there are changes and removals for the provisioning process. IdentityRequest is an old structure for the provisioner and it has been removed and some preliminary code file renames. --- .../AttestationCertificateAuthority.java | 20 +- ...estfulAttestationCertificateAuthority.java | 22 -- .../persist/RestfulInterface.java | 2 - .../persist/enums/AppraisalStatus.java | 1 - ...estHandler.java => AbstractProcessor.java} | 6 +- ....java => CertificateRequestProcessor.java} | 16 +- ...ndler.java => IdentityClaimProcessor.java} | 4 +- .../provision/IdentityRequestHandler.java | 345 ------------------ .../service/SupplyChainValidationService.java | 19 +- ...ionManager.java => ValidationService.java} | 2 +- .../validation/FirmwareScvValidator.java | 7 +- .../CertificatePageController.java | 4 +- ...eferenceManifestDetailsPageController.java | 4 +- 13 files changed, 36 insertions(+), 416 deletions(-) rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/{AbstractRequestHandler.java => AbstractProcessor.java} (98%) rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/{CertificateRequestHandler.java => CertificateRequestProcessor.java} (94%) rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/{IdentityClaimHandler.java => IdentityClaimProcessor.java} (99%) delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityRequestHandler.java rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/{ValidationManager.java => ValidationService.java} (99%) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java index c480a7b9..ede7b733 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java @@ -8,9 +8,8 @@ import hirs.attestationca.persist.entity.manager.PolicyRepository; import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository; import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository; import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository; -import hirs.attestationca.persist.provision.CertificateRequestHandler; -import hirs.attestationca.persist.provision.IdentityClaimHandler; -import hirs.attestationca.persist.provision.IdentityRequestHandler; +import hirs.attestationca.persist.provision.CertificateRequestProcessor; +import hirs.attestationca.persist.provision.IdentityClaimProcessor; import hirs.attestationca.persist.service.SupplyChainValidationService; import hirs.structs.converters.StructConverter; import lombok.extern.log4j.Log4j2; @@ -62,9 +61,8 @@ public abstract class AttestationCertificateAuthority { private final PolicyRepository policyRepository; private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository; - private CertificateRequestHandler certificateRequestHandler; - private IdentityClaimHandler identityClaimHandler; - private IdentityRequestHandler identityRequestHandler; + private CertificateRequestProcessor certificateRequestHandler; + private IdentityClaimProcessor identityClaimHandler; /** * Constructor. @@ -109,19 +107,13 @@ public abstract class AttestationCertificateAuthority { this.policyRepository = policyRepository; this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository; - this.certificateRequestHandler = new CertificateRequestHandler(supplyChainValidationService, + this.certificateRequestHandler = new CertificateRequestProcessor(supplyChainValidationService, certificateRepository, deviceRepository, privateKey, acaCertificate, validDays, tpm2ProvisionerStateRepository); - this.identityClaimHandler = new IdentityClaimHandler(supplyChainValidationService, + this.identityClaimHandler = new IdentityClaimProcessor(supplyChainValidationService, certificateRepository, referenceManifestRepository, referenceDigestValueRepository, deviceRepository, tpm2ProvisionerStateRepository, policyRepository); - this.identityRequestHandler = new IdentityRequestHandler(structConverter, certificateRepository, - deviceRepository, supplyChainValidationService, privateKey, validDays, acaCertificate); - } - - byte[] processIdentityRequest(final byte[] identityRequest) { - return this.identityRequestHandler.processIdentityRequest(identityRequest); } byte[] processIdentityClaimTpm2(final byte[] identityClaim) { diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java index ced6614d..18bb0458 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java @@ -71,28 +71,6 @@ public class RestfulAttestationCertificateAuthority extends AttestationCertifica referenceDigestValueRepository, policyRepository, tpm2ProvisionerStateRepository); } - /** - * Processes a given IdentityRequestEnvelope and - * generates a IdentityResponseEnvelope. In most cases, - * a client will generate the request using the TPM "Collate Identity" process. - * - * Wrap the {@link AttestationCertificateAuthority#processIdentityRequest(byte[])} - * with a Spring {@link org.springframework.web.bind.annotation.RequestMapping}. Effectively, this method then will allow spring to - * serialize and deserialize the request and responses on method invocation and - * return, respectively. - * - * @param identityRequest generated during the collate identity process with a Tpm - * @return response for the request - */ - @Override - @ResponseBody - @RequestMapping(value = "/identity-request/process", - method = RequestMethod.POST, - consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE) - public byte[] processIdentityRequest(@RequestBody final byte[] identityRequest) { - return super.processIdentityRequest(identityRequest); - } - /** * Listener for identity requests from TPM 2.0 provisioning. * diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulInterface.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulInterface.java index 10e63b9f..e6c8eeaf 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulInterface.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulInterface.java @@ -5,8 +5,6 @@ package hirs.attestationca.persist; */ public interface RestfulInterface { - byte[] processIdentityRequest(byte[] identityRequest); - byte[] processIdentityClaimTpm2(byte[] identityClaim); byte[] processCertificateRequest(byte[] certificateRequest); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/AppraisalStatus.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/AppraisalStatus.java index 37431f5f..0988656c 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/AppraisalStatus.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/AppraisalStatus.java @@ -60,5 +60,4 @@ public class AppraisalStatus { this.message = message; this.additionalInfo = additionalInfo; } - } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractRequestHandler.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java similarity index 98% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractRequestHandler.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java index c7c7e27c..cca14eca 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractRequestHandler.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java @@ -41,7 +41,7 @@ import java.util.List; @Log4j2 @NoArgsConstructor -public class AbstractRequestHandler { +public class AbstractProcessor { @Getter private int validDays; @@ -51,8 +51,8 @@ public class AbstractRequestHandler { @Getter private PolicyRepository policyRepository; - public AbstractRequestHandler(final PrivateKey privateKey, - final int validDays) { + public AbstractProcessor(final PrivateKey privateKey, + final int validDays) { this.privateKey = privateKey; this.validDays = validDays; } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestHandler.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java similarity index 94% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestHandler.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java index 5eb42b76..f3c59ad1 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestHandler.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java @@ -27,7 +27,7 @@ import java.security.interfaces.RSAPublicKey; import java.util.List; @Log4j2 -public class CertificateRequestHandler extends AbstractRequestHandler { +public class CertificateRequestProcessor extends AbstractProcessor { private SupplyChainValidationService supplyChainValidationService; private CertificateRepository certificateRepository; @@ -42,13 +42,13 @@ public class CertificateRequestHandler extends AbstractRequestHandler { * @param validDays int for the time in which a certificate is valid. * @param tpm2ProvisionerStateRepository db connector for provisioner state. */ - public CertificateRequestHandler(final SupplyChainValidationService supplyChainValidationService, - final CertificateRepository certificateRepository, - final DeviceRepository deviceRepository, - final PrivateKey privateKey, - final X509Certificate acaCertificate, - final int validDays, - final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository) { + public CertificateRequestProcessor(final SupplyChainValidationService supplyChainValidationService, + final CertificateRepository certificateRepository, + final DeviceRepository deviceRepository, + final PrivateKey privateKey, + final X509Certificate acaCertificate, + final int validDays, + final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository) { super(privateKey, validDays); this.supplyChainValidationService = supplyChainValidationService; this.certificateRepository = certificateRepository; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimHandler.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java similarity index 99% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimHandler.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java index 07fc0f52..d969114c 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimHandler.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java @@ -57,7 +57,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; @Log4j2 -public class IdentityClaimHandler extends AbstractRequestHandler { +public class IdentityClaimProcessor extends AbstractProcessor { private static final String PCR_QUOTE_MASK = "0,1,2,3,4,5,6,7,8,9,10,11,12,13," + "14,15,16,17,18,19,20,21,22,23"; @@ -78,7 +78,7 @@ public class IdentityClaimHandler extends AbstractRequestHandler { /** * Constructor */ - public IdentityClaimHandler( + public IdentityClaimProcessor( final SupplyChainValidationService supplyChainValidationService, final CertificateRepository certificateRepository, final ReferenceManifestRepository referenceManifestRepository, diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityRequestHandler.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityRequestHandler.java deleted file mode 100644 index b2188d56..00000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityRequestHandler.java +++ /dev/null @@ -1,345 +0,0 @@ -package hirs.attestationca.persist.provision; - -import hirs.attestationca.persist.entity.manager.CertificateRepository; -import hirs.attestationca.persist.entity.manager.DeviceRepository; -import hirs.attestationca.persist.entity.userdefined.Certificate; -import hirs.attestationca.persist.entity.userdefined.Device; -import hirs.attestationca.persist.entity.userdefined.SupplyChainValidationSummary; -import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; -import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; -import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport; -import hirs.attestationca.persist.enums.AppraisalStatus; -import hirs.attestationca.persist.exceptions.IdentityProcessingException; -import hirs.attestationca.persist.provision.helper.CredentialManagementHelper; -import hirs.attestationca.persist.provision.helper.ProvisionUtils; -import hirs.attestationca.persist.service.SupplyChainValidationService; -import hirs.structs.converters.SimpleStructBuilder; -import hirs.structs.converters.StructConverter; -import hirs.structs.elements.aca.IdentityRequestEnvelope; -import hirs.structs.elements.aca.IdentityResponseEnvelope; -import hirs.structs.elements.aca.SymmetricAttestation; -import hirs.structs.elements.tpm.EncryptionScheme; -import hirs.structs.elements.tpm.IdentityProof; -import hirs.structs.elements.tpm.IdentityRequest; -import hirs.structs.elements.tpm.SymmetricKey; -import hirs.structs.elements.tpm.SymmetricKeyParams; -import lombok.extern.log4j.Log4j2; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.SerializationUtils; - -import java.io.IOException; -import java.math.BigInteger; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.cert.X509Certificate; -import java.util.LinkedList; -import java.util.List; - -@Log4j2 -public class IdentityRequestHandler extends AbstractRequestHandler { - - /** - * Container wired ACA private key. - */ - private final PrivateKey privateKey; - private int validDays; - private StructConverter structConverter; - private CertificateRepository certificateRepository; - private DeviceRepository deviceRepository; - private SupplyChainValidationService supplyChainValidationService; - private X509Certificate acaCertificate; - - /** - * Constructor. - * @param structConverter the struct converter - * @param certificateRepository - * @param deviceRepository - * @param supplyChainValidationService the supply chain service - * @param privateKey - * @param validDays int for the time in which a certificate is valid. - * @param acaCertificate object holding the x509 certificate - */ - public IdentityRequestHandler(final StructConverter structConverter, - final CertificateRepository certificateRepository, - final DeviceRepository deviceRepository, - final SupplyChainValidationService supplyChainValidationService, - final PrivateKey privateKey, - final int validDays, final X509Certificate acaCertificate) { - super(privateKey, validDays); - this.structConverter = structConverter; - this.certificateRepository = certificateRepository; - this.deviceRepository = deviceRepository; - this.supplyChainValidationService = supplyChainValidationService; - this.privateKey = privateKey; - this.acaCertificate = acaCertificate; - } - - /** - * Basic implementation of the ACA processIdentityRequest method. - * - * @param identityRequest cannot be null - * @return an identity response for the specified request - */ - public byte[] processIdentityRequest(final byte[] identityRequest) { - log.info("Identity Request Received..."); - if (ArrayUtils.isEmpty(identityRequest)) { - throw new IllegalArgumentException("The IdentityRequest sent by the client" - + " cannot be null or empty."); - } - - log.debug("received request to process identity request"); - - // translate the bytes into the challenge - IdentityRequestEnvelope challenge = - structConverter.convert(identityRequest, IdentityRequestEnvelope.class); - - byte[] identityProof = unwrapIdentityRequest(structConverter.convert(challenge.getRequest(), - IdentityRequest.class)); - // the decrypted symmetric blob should be in the format of an IdentityProof. Use the - // struct converter to generate it. - IdentityProof proof = structConverter.convert(identityProof, IdentityProof.class); - - // convert the credential into an actual key. - log.debug("assembling public endorsement key"); - PublicKey ekPublicKey = null; - - // attempt to find an endorsement credential to validate - EndorsementCredential endorsementCredential = null; - - // first check the identity request for the endorsement credential - byte[] ecBytesFromIdentityRequest = proof.getEndorsementCredential(); - if (ArrayUtils.isNotEmpty(ecBytesFromIdentityRequest)) { - endorsementCredential = CredentialManagementHelper.storeEndorsementCredential( - this.certificateRepository, ecBytesFromIdentityRequest, ""); - try { - BigInteger publicKeyModulus = Certificate.getPublicKeyModulus( - endorsementCredential.getX509Certificate()); - if (publicKeyModulus != null) { - ekPublicKey = ProvisionUtils.assemblePublicKey(publicKeyModulus.toByteArray()); - } else { - throw new IdentityProcessingException("TPM 1.2 Provisioning requires EK " - + "Credentials to be created with RSA"); - } - } catch (IOException ioEx) { - log.error("Could not retrieve the public key modulus from the EK cert"); - } - } else if (ArrayUtils.isNotEmpty(challenge.getEndorsementCredentialModulus())) { - log.warn("EKC was not in the identity proof from the client. Checking for uploads."); - // Check if the EC was uploaded - ekPublicKey = - ProvisionUtils.assemblePublicKey(new String(challenge.getEndorsementCredentialModulus())); - endorsementCredential = getEndorsementCredential(ekPublicKey); - } else { - log.warn("Zero-length endorsement credential received in identity request."); - } - - // get platform credential from the identity request - List platformCredentials = new LinkedList<>(); - byte[] pcBytesFromIdentityRequest = proof.getPlatformCredential(); - if (ArrayUtils.isNotEmpty(pcBytesFromIdentityRequest)) { - platformCredentials.add(CredentialManagementHelper.storePlatformCredential( - this.certificateRepository, pcBytesFromIdentityRequest)); - } else if (endorsementCredential != null) { - // if none in the identity request, look for uploaded platform credentials - log.warn("PC was not in the identity proof from the client. Checking for uploads."); - platformCredentials.addAll(getPlatformCredentials(endorsementCredential)); - } else { - // if none in the identity request, look for uploaded platform credentials - log.warn("Zero-length platform credential received in identity request."); - } - - log.debug("Processing serialized device info report structure of length {}", - challenge.getDeviceInfoReportLength()); - - DeviceInfoReport deviceInfoReport = (DeviceInfoReport) - SerializationUtils.deserialize(challenge.getDeviceInfoReport()); - - if (deviceInfoReport == null) { - log.error("Failed to deserialize Device Info Report"); - throw new IdentityProcessingException("Device Info Report failed to deserialize " - + "from Identity Request"); - } - - log.info("Processing Device Info Report"); - // store device and device info report. - String deviceName = deviceInfoReport.getNetworkInfo().getHostname(); - Device device = this.deviceRepository.findByName(deviceName); - device.setDeviceInfo(deviceInfoReport); - - // perform supply chain validation. Note: It's possible that this should be done earlier - // in this method. - SupplyChainValidationSummary summary = - supplyChainValidationService.validateSupplyChain(endorsementCredential, - platformCredentials, device); - - // update the validation result in the device - device.setSupplyChainValidationStatus(summary.getOverallValidationResult()); - deviceRepository.save(device); - // check if supply chain validation succeeded. - // If it did not, do not provide the IdentityResponseEnvelope - if (summary.getOverallValidationResult() == AppraisalStatus.Status.PASS) { - IdentityResponseEnvelope identityResponse = - generateIdentityResponseEnvelopeAndStoreIssuedCert(challenge, - ekPublicKey, endorsementCredential, platformCredentials, device); - - return structConverter.convert(identityResponse); - } else { - log.error("Supply chain validation did not succeed. Result is: " - + summary.getOverallValidationResult()); - return new byte[]{}; - } - } - - /** - * Given a successful supply chain validation, generate an Identity Response envelope and - * the issued certificate. The issued cert is stored in the database. The identity response - * envelope is returned, and sent back to the client using the struct converter. - * @param challenge the identity request envelope - * @param ekPublicKey the EK public key - * @param endorsementCredential the endorsement credential - * @param platformCredentials the set of platform credentials - * @param device the device associated - * @return the identity response envelope - */ - private IdentityResponseEnvelope generateIdentityResponseEnvelopeAndStoreIssuedCert( - final IdentityRequestEnvelope challenge, final PublicKey ekPublicKey, - final EndorsementCredential endorsementCredential, - final List platformCredentials, final Device device) { - // decrypt the asymmetric / symmetric blobs - log.debug("unwrapping identity request"); - byte[] identityProof = unwrapIdentityRequest( - structConverter.convert(challenge.getRequest(), IdentityRequest.class)); - - // the decrypted symmetric blob should be in the format of an IdentityProof. Use the - // struct converter to generate it. - IdentityProof proof = structConverter.convert(identityProof, IdentityProof.class); - - // generate a session key and convert to byte array - log.debug("generating symmetric key for response"); - SymmetricKey sessionKey = ProvisionUtils.generateSymmetricKey(); - - // generate the asymmetric contents for the identity response - log.debug("generating asymmetric contents for response"); - byte[] asymmetricContents = ProvisionUtils.generateAsymmetricContents( - structConverter.convert(proof.getIdentityKey()), - structConverter.convert(sessionKey), ekPublicKey); - - // generate the identity credential - log.debug("generating credential from identity proof"); - - // transform the public key struct into a public key - PublicKey publicKey = ProvisionUtils.assemblePublicKey(proof.getIdentityKey().getStorePubKey().getKey()); - X509Certificate credential = generateCredential(publicKey, endorsementCredential, - platformCredentials, device.getDeviceInfo() - .getNetworkInfo() - .getIpAddress() - .getHostName(), acaCertificate); - - // generate the attestation using the credential and the key for this session - log.debug("generating symmetric response"); - SymmetricAttestation attestation = ProvisionUtils.generateAttestation(credential, sessionKey); - - // construct the response with the both the asymmetric contents and the CA attestation - IdentityResponseEnvelope identityResponse = - new SimpleStructBuilder<>(IdentityResponseEnvelope.class) - .set("asymmetricContents", asymmetricContents) - .set("symmetricAttestation", attestation).build(); - - // save new attestation certificate - byte[] derEncodedAttestationCertificate = ProvisionUtils.getDerEncodedCertificate(credential); - saveAttestationCertificate(this.certificateRepository, derEncodedAttestationCertificate, - endorsementCredential, platformCredentials, device); - - return identityResponse; - } - - /** - * Unwraps a given identityRequest. That is to say, decrypt the asymmetric portion of a data - * structure to determine the method to decrypt the symmetric portion. - * - * @param request - * to be decrypted - * @return the decrypted symmetric portion of an identity request. - */ - private byte[] unwrapIdentityRequest(final IdentityRequest request) { - // in case the TPM did not specify the IV, it must be extracted from the symmetric blob. - // the IV will then be the the first block of the cipher text. - final byte[] iv; - SymmetricKeyParams symmetricKeyParams = request.getSymmetricAlgorithm(); - if (symmetricKeyParams != null && symmetricKeyParams.getParams() != null) { - iv = symmetricKeyParams.getParams().getIv(); - } else { - iv = ProvisionUtils.extractInitialValue(request); - } - - // determine the encryption scheme from the algorithm - EncryptionScheme asymmetricScheme = - EncryptionScheme.fromInt(request.getAsymmetricAlgorithm().getEncryptionScheme()); - - // decrypt the asymmetric blob - byte[] decryptedAsymmetricBlob = - ProvisionUtils.decryptAsymmetricBlob(request.getAsymmetricBlob(), asymmetricScheme, getPrivateKey()); - - // construct our symmetric key structure from the decrypted asymmetric blob - SymmetricKey symmetricKey = - structConverter.convert(decryptedAsymmetricBlob, SymmetricKey.class); - - byte[] decryptedSymmetricBlob = - ProvisionUtils.decryptSymmetricBlob(request.getSymmetricBlob(), symmetricKey.getKey(), iv, - "AES/CBC/PKCS5Padding"); - - // decrypt the symmetric blob - return decryptedSymmetricBlob; - } - - /** - * Gets the Endorsement Credential from the DB given the EK public key. - * @param ekPublicKey the EK public key - * @return the Endorsement credential, if found, otherwise null - */ - private EndorsementCredential getEndorsementCredential(final PublicKey ekPublicKey) { - log.debug("Searching for endorsement credential based on public key: " + ekPublicKey); - - if (ekPublicKey == null) { - throw new IllegalArgumentException("Cannot look up an EC given a null public key"); - } - - EndorsementCredential credential = null; - - try { - credential = certificateRepository.findByPublicKeyModulusHexValue(Certificate - .getPublicKeyModulus(ekPublicKey) - .toString()); - } catch (IOException ioEx) { - log.error("Could not extract public key modulus", ioEx); - } - - if (credential == null) { - log.warn("Unable to find endorsement credential for public key."); - } else { - log.debug("Endorsement credential found."); - } - - return credential; - } - - private List getPlatformCredentials(final EndorsementCredential ec) { - List credentials = null; - - if (ec == null) { - log.warn("Cannot look for platform credential(s). Endorsement credential was null."); - } else { - log.debug("Searching for platform credential(s) based on holder serial number: " - + ec.getSerialNumber()); - credentials = this.certificateRepository.getByHolderSerialNumber(ec.getSerialNumber()); - if (credentials == null || credentials.isEmpty()) { - log.warn("No platform credential(s) found"); - } else { - log.debug("Platform Credential(s) found: " + credentials.size()); - } - } - - return credentials; - } - -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java index e9e44d77..9e6f5d4c 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java @@ -113,7 +113,7 @@ public class SupplyChainValidationService { // Validate the Endorsement Credential if (getPolicySettings().isEcValidationEnabled()) { log.info("Beginning Endorsement Credential Validation..."); - validations.add(ValidationManager.evaluateEndorsementCredentialStatus(ec, this.caCredentialRepository, acceptExpiredCerts)); + validations.add(ValidationService.evaluateEndorsementCredentialStatus(ec, this.caCredentialRepository, acceptExpiredCerts)); // store the device with the credential if (ec != null) { ec.setDeviceId(device.getId()); @@ -131,8 +131,8 @@ public class SupplyChainValidationService { pcErrorMessage = "Platform credential(s) missing\n"; } else { for (PlatformCredential pc : pcs) { - KeyStore trustedCa = ValidationManager.getCaChain(pc, caCredentialRepository); - platformScv = ValidationManager.evaluatePlatformCredentialStatus( + KeyStore trustedCa = ValidationService.getCaChain(pc, caCredentialRepository); + platformScv = ValidationService.evaluatePlatformCredentialStatus( pc, trustedCa, acceptExpiredCerts); if (platformScv.getValidationResult() == AppraisalStatus.Status.FAIL) { @@ -147,6 +147,7 @@ public class SupplyChainValidationService { chkDeltas = true; deltaMapping.put(pc, null); } + pc.setEndorsementCredential(ec); pc.setDeviceId(device.getId()); pc.setDeviceName(device.getDeviceInfo().getNetworkInfo().getHostname()); this.certificateRepository.save(pc); @@ -196,7 +197,7 @@ public class SupplyChainValidationService { // need to check if there are deltas, if not then just verify // components of the base if (baseCredential == null) { - validations.add(ValidationManager.buildValidationRecord( + validations.add(ValidationService.buildValidationRecord( SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, AppraisalStatus.Status.FAIL, "Base Platform credential missing." @@ -209,7 +210,7 @@ public class SupplyChainValidationService { while (it.hasNext()) { PlatformCredential pc = it.next(); if (pc != null && !pc.isPlatformBase()) { - attributeScv = ValidationManager.evaluateDeltaAttributesStatus( + attributeScv = ValidationService.evaluateDeltaAttributesStatus( pc, device.getDeviceInfo(), baseCredential, deltaMapping, certificateRepository); if (attributeScv.getValidationResult() == AppraisalStatus.Status.FAIL) { @@ -222,7 +223,7 @@ public class SupplyChainValidationService { aes.add(baseCredential); validations.remove(platformScv); // if there are no deltas, just check base credential - platformScv = ValidationManager.evaluatePCAttributesStatus( + platformScv = ValidationService.evaluatePCAttributesStatus( baseCredential, device.getDeviceInfo(), ec, certificateRepository, componentResultRepository); validations.add(new SupplyChainValidation( @@ -243,7 +244,7 @@ public class SupplyChainValidationService { log.info("Beginning Firmware Validation..."); // may need to associated with device to pull the correct info // compare tpm quote with what is pulled from RIM associated file - validations.add(ValidationManager.evaluateFirmwareStatus(device, getPolicySettings(), + validations.add(ValidationService.evaluateFirmwareStatus(device, getPolicySettings(), referenceManifestRepository, referenceDigestValueRepository, caCredentialRepository)); } @@ -329,7 +330,7 @@ public class SupplyChainValidationService { log.error(ex); } - quoteScv = ValidationManager.buildValidationRecord(SupplyChainValidation + quoteScv = ValidationService.buildValidationRecord(SupplyChainValidation .ValidationType.FIRMWARE, fwStatus.getAppStatus(), fwStatus.getMessage(), eventLog, level); @@ -339,7 +340,7 @@ public class SupplyChainValidationService { = this.supplyChainValidationSummaryRepository.findByDevice(deviceName); for (SupplyChainValidation scv : previous.getValidations()) { if (scv.getValidationType() != SupplyChainValidation.ValidationType.FIRMWARE) { - validations.add(ValidationManager.buildValidationRecord(scv.getValidationType(), + validations.add(ValidationService.buildValidationRecord(scv.getValidationType(), scv.getValidationResult(), scv.getMessage(), scv.getCertificatesUsed().get(0), Level.INFO)); } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationManager.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java similarity index 99% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationManager.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java index f1dbaeee..1fe060b5 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationManager.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java @@ -38,7 +38,7 @@ import java.util.Map; import java.util.Set; @Log4j2 -public class ValidationManager { +public class ValidationService { public static SupplyChainValidation evaluateEndorsementCredentialStatus( final EndorsementCredential ec, diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java index fb1778c0..6c07353c 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java @@ -1,24 +1,21 @@ package hirs.attestationca.persist.validation; import hirs.attestationca.persist.entity.manager.CACredentialRepository; -import hirs.attestationca.persist.entity.manager.CertificateRepository; import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository; import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository; import hirs.attestationca.persist.entity.userdefined.Device; import hirs.attestationca.persist.entity.userdefined.PolicySettings; import hirs.attestationca.persist.entity.userdefined.ReferenceManifest; -import hirs.attestationca.persist.entity.userdefined.SupplyChainValidation; import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential; import hirs.attestationca.persist.entity.userdefined.rim.BaseReferenceManifest; import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements; import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue; import hirs.attestationca.persist.enums.AppraisalStatus; -import hirs.attestationca.persist.service.ValidationManager; +import hirs.attestationca.persist.service.ValidationService; import hirs.utils.SwidResource; import hirs.utils.tpm.eventlog.TCGEventLog; import hirs.utils.tpm.eventlog.TpmPcrEvent; import lombok.extern.log4j.Log4j2; -import org.apache.logging.log4j.Level; import java.io.IOException; import java.security.KeyStore; @@ -99,7 +96,7 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator { CertificateAuthorityCredential signingCert = null; for (CertificateAuthorityCredential cert : allCerts) { signingCert = cert; - KeyStore keyStore = ValidationManager.getCaChain(signingCert, + KeyStore keyStore = ValidationService.getCaChain(signingCert, caCredentialRepository); if (referenceManifestValidator.validateXmlSignature(signingCert)) { try { diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java index 60a81689..7a58df69 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java @@ -389,14 +389,14 @@ public class CertificatePageController extends PageController { for (PlatformCredential pc : sharedCertificates) { if (!pc.isPlatformBase()) { pc.archive(); - certificateRepository.delete(pc); + certificateRepository.save(pc); } } } } certificate.archive(); - certificateRepository.delete(certificate); + certificateRepository.save(certificate); String deleteCompletedMessage = "Certificate successfully deleted"; messages.addInfo(deleteCompletedMessage); diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java index cd07a8a1..5d1cddba 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java @@ -11,7 +11,7 @@ import hirs.attestationca.persist.entity.userdefined.rim.BaseReferenceManifest; import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements; import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue; import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest; -import hirs.attestationca.persist.service.ValidationManager; +import hirs.attestationca.persist.service.ValidationService; import hirs.attestationca.persist.validation.ReferenceManifestValidator; import hirs.attestationca.persist.validation.SupplyChainCredentialValidator; import hirs.attestationca.persist.validation.SupplyChainValidatorException; @@ -298,7 +298,7 @@ public class ReferenceManifestDetailsPageController extends PageController Date: Wed, 4 Oct 2023 13:28:48 -0400 Subject: [PATCH 13/26] Added check for existing aca.properties in the ACA setup files --- package/scripts/db/db_create.sh | 13 ++++++++++++- package/scripts/pki/pki_setup.sh | 19 ++++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/package/scripts/db/db_create.sh b/package/scripts/db/db_create.sh index e723ec9f..3c67601d 100755 --- a/package/scripts/db/db_create.sh +++ b/package/scripts/db/db_create.sh @@ -41,8 +41,19 @@ source $SCRIPT_DIR/mysql_util.sh source $ACA_PROP_FILE check_mysql_root_pwd () { - # Check if DB root password needs to be obtained + # Check if DB root password needs to be obtained via env variable or existing property file + if [ -z "$HIRS_MYSQL_ROOT_PWD" ]; then + # Check if property file exists and look for properties + if [ -f $ACA_PROP_FILE ]; then + echo "Found existing aca.properties, using existing variables..." + source $ACA_PROP_FILE + if [ ! -z $hirs_pki_password ]; then PKI_PASS=$hirs_pki_password; fi + if [ ! -z $mysql_admin_password ]; then HIRS_MYSQL_ROOT_PWD=$mysql_admin_password; fi + if [ ! -z $hirs_db_password ]; then HIRS_DB_PWD=$hirs_db_password; fi + fi + fi + if [ -z $HIRS_MYSQL_ROOT_PWD ]; then # Create a 32 character random password echo "Using randomly generated password for the DB admin" | tee -a "$LOG_FILE" diff --git a/package/scripts/pki/pki_setup.sh b/package/scripts/pki/pki_setup.sh index 5a28142b..5ad18e68 100755 --- a/package/scripts/pki/pki_setup.sh +++ b/package/scripts/pki/pki_setup.sh @@ -21,15 +21,24 @@ SCRIPT_DIR=$( dirname -- "$( readlink -f -- "$0"; )"; ) mkdir -p $HIRS_CONF_DIR $LOG_DIR echo "SCRIPT_DIR is $SCRIPT_DIR" | tee -a "$LOG_FILE" -if [ -z "$1" ]; then +if [ -z "$LOG_FILE" ]; then LOG_FILE="$LOG_DIR$LOG_FILE_NAME" echo "using log file $LOG_FILE" | tee -a "$LOG_FILE" fi -if [ -z "$2" ]; then - PKI_PASS=$(head -c 64 /dev/urandom | md5sum | tr -dc 'a-zA-Z0-9') - echo "Using randomly generated password for the PKI key password" | tee -a "$LOG_FILE" - echo "Using pki password=$PKI_PASS" +if [ -z "$PKI_PASS" ]; then + if [ -f $ACA_PROP ]; then + source $ACA_PROP + if [ ! -z $hirs_pki_password ]; then + PKI_PASS=$hirs_pki_password + fi + fi +fi + +if [ -z "$PKI_PASS" ]; then + PKI_PASS=$(head -c 64 /dev/urandom | md5sum | tr -dc 'a-zA-Z0-9') + echo "Using randomly generated password for the PKI key password" | tee -a "$LOG_FILE" + echo "Using pki password=$PKI_PASS" fi # Check for sudo or root user From 65a1105ff59399638488e6af1ad630393bc0786b Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Thu, 5 Oct 2023 10:54:25 -0400 Subject: [PATCH 14/26] Minor changes, mostly syntax and log message removals --- .../validation/CredentialValidator.java | 20 +++---------------- ...eferenceManifestDetailsPageController.java | 15 ++++++++------ 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java index be48a5e7..5fb76a7c 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java @@ -38,12 +38,10 @@ public class CredentialValidator extends SupplyChainCredentialValidator { String message; if (ec == null) { message = baseErrorMessage + "an endorsement credential"; - log.error(message); return new AppraisalStatus(FAIL, message); } if (trustStore == null) { message = baseErrorMessage + "a trust store"; - log.error(message); return new AppraisalStatus(FAIL, message); } @@ -56,7 +54,6 @@ public class CredentialValidator extends SupplyChainCredentialValidator { if (keyInStore) { message = baseErrorMessage + "keys in the trust store"; - log.error(message); return new AppraisalStatus(FAIL, message); } @@ -77,19 +74,15 @@ public class CredentialValidator extends SupplyChainCredentialValidator { } } catch (IOException e) { message = "Couldn't retrieve X509 certificate from endorsement credential"; - log.error(message, e); return new AppraisalStatus(ERROR, message + " " + e.getMessage()); } catch (SupplyChainValidatorException e) { message = "An error occurred indicating the credential is not valid"; - log.warn(message, e); return new AppraisalStatus(ERROR, message + " " + e.getMessage()); } catch (CertificateExpiredException e) { message = "The endorsement credential is expired"; - log.warn(message, e); return new AppraisalStatus(FAIL, message + " " + e.getMessage()); } catch (CertificateNotYetValidException e) { message = "The endorsement credential is not yet valid"; - log.warn(message, e); return new AppraisalStatus(FAIL, message + " " + e.getMessage()); } } @@ -110,18 +103,15 @@ public class CredentialValidator extends SupplyChainCredentialValidator { String certVerifyMsg; if (pc == null) { message = baseErrorMessage + "a platform credential"; - log.error(message); return new AppraisalStatus(FAIL, message); } try { if (trustStore == null || trustStore.size() == 0) { message = baseErrorMessage + "an Issuer Cert in the Trust Store"; - log.error(message); return new AppraisalStatus(FAIL, message); } } catch (KeyStoreException e) { message = baseErrorMessage + "an initialized trust store"; - log.error(message); return new AppraisalStatus(FAIL, message); } @@ -139,7 +129,7 @@ public class CredentialValidator extends SupplyChainCredentialValidator { if (!acceptExpired && !pc.isValidOn(new Date())) { message = "Platform credential has expired"; // if not valid at the current time - log.warn(message); + log.debug(message); return new AppraisalStatus(FAIL, message); } @@ -148,12 +138,12 @@ public class CredentialValidator extends SupplyChainCredentialValidator { certVerifyMsg = verifyCertificate(attributeCert, trustStore); if (certVerifyMsg.isEmpty()) { message = PLATFORM_VALID; - log.info(message); + log.debug(message); return new AppraisalStatus(PASS, message); } else { message = String.format("Platform credential failed verification%n%s", certVerifyMsg); - log.error(message); + log.debug(message); return new AppraisalStatus(FAIL, message); } } catch (SupplyChainValidatorException scvEx) { @@ -180,17 +170,14 @@ public class CredentialValidator extends SupplyChainCredentialValidator { String message; if (platformCredential == null) { message = baseErrorMessage + "a platform credential"; - log.error(message); return new AppraisalStatus(FAIL, message); } if (deviceInfoReport == null) { message = baseErrorMessage + "a device info report"; - log.error(message); return new AppraisalStatus(FAIL, message); } if (endorsementCredential == null) { message = baseErrorMessage + "an endorsement credential"; - log.error(message); return new AppraisalStatus(FAIL, message); } @@ -199,7 +186,6 @@ public class CredentialValidator extends SupplyChainCredentialValidator { .equals(platformCredential.getHolderSerialNumber())) { message = "Platform Credential holder serial number does not match " + "the Endorsement Credential's serial number"; - log.error(message); return new AppraisalStatus(FAIL, message); } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java index 5d1cddba..a86c48ef 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java @@ -32,6 +32,7 @@ import org.springframework.web.servlet.ModelAndView; import java.io.IOException; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.Arrays; @@ -306,17 +307,19 @@ public class ReferenceManifestDetailsPageController extends PageController Date: Thu, 5 Oct 2023 14:31:29 -0400 Subject: [PATCH 15/26] [#593] HIRS_Utils Unit Tests (#603) * Added test path to HIRS_AttestationCA, including PortalInfoTest. Also added testImplementation lines to the subproject's build.gradle to give those classes access to JUnit5. * Adding PlatformCredentialTest and CertificateTest, along with necessary resources in test path of HIR_AttestationCA * Adding SupplyChainValidationTest --- HIRS_AttestationCA/build.gradle | 6 +- .../entity/userdefined/CertificateTest.java | 605 +++++++++++++ .../SupplyChainValidationTest.java | 121 +++ .../certificate/PlatformCredentialTest.java | 809 ++++++++++++++++++ .../userdefined/info/PortalInfoTest.java | 127 +++ .../IntelSigningKey_20April2017.pem | 19 + .../resources/certificates/Intel_nuc_pc.pem | 16 + .../resources/certificates/Intel_nuc_pc2.pem | 16 + .../certificates/ab21ccf2-tpmcert.pem | 26 + .../ek_cert_with_padded_bytes.cer | Bin 0 -> 1100 bytes .../ek_cert_with_security_assertions.cer | Bin 0 -> 1704 bytes .../test/resources/certificates/fakeCA.pem | 18 + .../certificates/fakeIntelIntermediateCA.cer | 19 + .../certificates/fakeIntelIntermediateCA.pem | 19 + .../fakeIntel_S2600KP_F00F00F00F00-Att.pem | 20 + .../fakeIntel_S2600KP_F00F00F00F00.pem | 20 + .../resources/certificates/fakeRootCA.cer | 18 + .../certificates/fakeSGIIntermediateCA.cer | 19 + .../certificates/fakeSGIIntermediateCA.pem | 19 + .../certificates/fakeSGI_J2_F00F00F0.pem | 22 + .../resources/certificates/fakeSelfSigned.cer | 21 + .../certificates/fakestmtpmekint02.pem | 22 + .../test/resources/certificates/gstpmroot.pem | 23 + .../resources/certificates/nuc-1/tpmcert.pem | 26 + .../resources/certificates/nuc-2/tpmcert.pem | 26 + .../certificates/stMicroCaCerts/gstpmroot.crt | Bin 0 -> 987 bytes .../stMicroCaCerts/stmtpmekint02.crt | Bin 0 -> 976 bytes .../stMicroCaCerts/stmtpmekroot.crt | Bin 0 -> 1040 bytes .../resources/certificates/stmtpmekint02.pem | 23 + .../platform_credentials/Intel_nuc1.cer | Bin 0 -> 1899 bytes .../platform_credentials/Intel_pc1.cer | Bin 0 -> 834 bytes .../platform_credentials/Intel_pc2.cer | Bin 0 -> 772 bytes .../platform_credentials/Intel_pc3.cer | Bin 0 -> 772 bytes .../platform_credentials/Intel_pc4.pem | Bin 0 -> 914 bytes .../platform_credentials/Intel_pc5.pem | Bin 0 -> 914 bytes .../TPM_INTC_Platform_Cert_RSA.txt | Bin 0 -> 2144 bytes .../validation/platform_credentials/ca.pub | 9 + .../intel_chain/root/intermediate1.crt | 46 + .../intel_chain/root/intermediate1.key | 27 + .../intel_chain/root/intermediate2.cer | Bin 0 -> 1645 bytes .../intel_chain/root/rootca.crt | 53 ++ .../intel_chain/root/rootca.key | 99 +++ .../platform_credentials/plat_base_cert1.pem | 54 ++ .../platform_credentials/plat_cert1.pem | 33 + .../platform_credentials/plat_cert2.pem | 31 + .../platform_credentials/plat_cert3.pem | 30 + .../platform_credentials/plat_delta_cert1.pem | 59 ++ .../basic_plat_cert.pem | 42 + .../flawed_attribute_cert_2187.pem | 3 + .../large_attribute_cert_2187.pem | 3 + .../large_attribute_spec2.txt | Bin 0 -> 2144 bytes .../large_plat_cert.pem | 43 + .../larger_attribute_cert_2187.pem | 3 + .../medium_attribute_cert_2187.pem | 3 + .../medium_plat_cert.pem | 37 + .../paccor_platform_cert.crt | Bin 0 -> 1102 bytes .../small_attribute_cert_2187.pem | 3 + .../small_plat_cert.pem | 31 + 58 files changed, 2668 insertions(+), 1 deletion(-) create mode 100644 HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/CertificateTest.java create mode 100644 HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/SupplyChainValidationTest.java create mode 100644 HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredentialTest.java create mode 100644 HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/info/PortalInfoTest.java create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/IntelSigningKey_20April2017.pem create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/Intel_nuc_pc.pem create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/Intel_nuc_pc2.pem create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/ab21ccf2-tpmcert.pem create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/ek_cert_with_padded_bytes.cer create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/ek_cert_with_security_assertions.cer create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/fakeCA.pem create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/fakeIntelIntermediateCA.cer create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/fakeIntelIntermediateCA.pem create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/fakeIntel_S2600KP_F00F00F00F00-Att.pem create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/fakeIntel_S2600KP_F00F00F00F00.pem create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/fakeRootCA.cer create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/fakeSGIIntermediateCA.cer create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/fakeSGIIntermediateCA.pem create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/fakeSGI_J2_F00F00F0.pem create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/fakeSelfSigned.cer create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/fakestmtpmekint02.pem create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/gstpmroot.pem create mode 100755 HIRS_AttestationCA/src/test/resources/certificates/nuc-1/tpmcert.pem create mode 100755 HIRS_AttestationCA/src/test/resources/certificates/nuc-2/tpmcert.pem create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/stMicroCaCerts/gstpmroot.crt create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/stMicroCaCerts/stmtpmekint02.crt create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/stMicroCaCerts/stmtpmekroot.crt create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/stmtpmekint02.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/Intel_nuc1.cer create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/Intel_pc1.cer create mode 100755 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/Intel_pc2.cer create mode 100755 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/Intel_pc3.cer create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/Intel_pc4.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/Intel_pc5.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/TPM_INTC_Platform_Cert_RSA.txt create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/ca.pub create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/intel_chain/root/intermediate1.crt create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/intel_chain/root/intermediate1.key create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/intel_chain/root/intermediate2.cer create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/intel_chain/root/rootca.crt create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/intel_chain/root/rootca.key create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/plat_base_cert1.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/plat_cert1.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/plat_cert2.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/plat_cert3.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials/plat_delta_cert1.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/basic_plat_cert.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/flawed_attribute_cert_2187.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/large_attribute_cert_2187.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/large_attribute_spec2.txt create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/large_plat_cert.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/larger_attribute_cert_2187.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/medium_attribute_cert_2187.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/medium_plat_cert.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/paccor_platform_cert.crt create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/small_attribute_cert_2187.pem create mode 100644 HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/small_plat_cert.pem diff --git a/HIRS_AttestationCA/build.gradle b/HIRS_AttestationCA/build.gradle index 04a80074..b934a26c 100644 --- a/HIRS_AttestationCA/build.gradle +++ b/HIRS_AttestationCA/build.gradle @@ -44,7 +44,11 @@ dependencies { implementation libs.protobuf.java implementation 'org.apache.logging.log4j:log4j-core:2.19.0' implementation 'org.apache.logging.log4j:log4j-api:2.19.0' - + + testImplementation 'org.junit.jupiter:junit-jupiter:5.9.3' + testImplementation 'org.junit.platform:junit-platform-launcher:1.9.3' + testImplementation 'org.hamcrest:hamcrest:2.2' + // spring management compileOnly libs.lombok implementation libs.lombok diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/CertificateTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/CertificateTest.java new file mode 100644 index 00000000..b9a0d916 --- /dev/null +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/CertificateTest.java @@ -0,0 +1,605 @@ +package hirs.attestationca.persist.entity.userdefined; + +import hirs.attestationca.persist.entity.ArchivableEntity; + +import java.io.FileInputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.NoSuchProviderException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.List; + +import hirs.attestationca.persist.entity.userdefined.certificate.*; +import org.bouncycastle.cert.X509AttributeCertificateHolder; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * This class tests functionality of the {@link Certificate} class. + */ +public class CertificateTest { + /** + * Location of a test (fake) root CA certificate. + */ + public static final String FAKE_ROOT_CA_FILE = "/certificates/fakeRootCA.cer"; + + /** + * Location of a test (fake) Intel intermediate CA certificate. + */ + public static final String FAKE_INTEL_INT_CA_FILE = + "/certificates/fakeIntelIntermediateCA.cer"; + + /** + * Location of a test (fake) Intel intermediate CA certificate. + */ + public static final String INTEL_INT_CA_FILE = + "/validation/platform_credentials/intel_chain/root/intermediate2.cer"; + + /** + * Location of a test (fake) SGI intermediate CA certificate. + */ + public static final String FAKE_SGI_INT_CA_FILE = "/certificates/fakeSGIIntermediateCA.cer"; + + /** + * Location of another test self-signed certificate. + */ + public static final String ANOTHER_SELF_SIGNED_FILE = + "/certificates/fakeSelfSigned.cer"; + + /** + * Location of the NUC EC. + */ + public static final String STM_NUC1_EC = "/certificates/nuc-1/tpmcert.pem"; + + /** + * Location of the ST Micro Intermediate 02 CA certificate. + */ + public static final String STM_INT_02_CA = "/certificates/stMicroCaCerts/stmtpmekint02.crt"; + + /** + * Location of the ST Micro Root CA certificate. + */ + public static final String STM_ROOT_CA = "/certificates/stMicroCaCerts/stmtpmekroot.crt"; + + /** + * Location of the GlobalSign Root CA certificate. + */ + public static final String GS_ROOT_CA = "/certificates/stMicroCaCerts/gstpmroot.crt"; + + /** + * Hex-encoded subject key identifier for the FAKE_ROOT_CA_FILE. + */ + public static final String FAKE_ROOT_CA_SUBJECT_KEY_IDENTIFIER_HEX = + "58ec313a1699f94c1c8c4e2c6412402b258f0177"; + + /** + * Location of a test STM endorsement credential. + */ + public static final String TEST_EC = "/certificates/ab21ccf2-tpmcert.pem"; + + /** + * Location of a test client cert. + */ + public static final String ISSUED_CLIENT_CERT = + "/tpm/sample_identity_cert.cer"; + + private static final String INT_CA_CERT02 = "/certificates/fakestmtpmekint02.pem"; + + private static final String RDN_COMMA_SEPARATED = + "CN=STM TPM EK Intermediate CA 02, O=STMicroelectronics NV, C=CH"; + private static final String RDN_MULTIVALUE = + "CN=Nuvoton TPM Root CA 2010+O=Nuvoton Technology Corporation+C=TW"; + + private static final String RDN_COMMA_SEPARATED_ORGANIZATION = "STMicroelectronics NV"; + private static final String RDN_MULTIVALUE_ORGANIZATION = "Nuvoton Technology Corporation"; + + private static final String EK_CERT_WITH_PADDED_BYTES = + "/certificates/ek_cert_with_padded_bytes.cer"; + + + /** + * Tests that a certificate can be constructed from a byte array. + * + * @throws IOException if there is a problem reading the cert file into a byte array + * @throws URISyntaxException if there is a problem constructing the URI + */ + @Test + public void testConstructCertFromByteArray() throws IOException, URISyntaxException { + Certificate certificate = new CertificateAuthorityCredential( + Files.readAllBytes( + Paths.get(this.getClass().getResource(FAKE_ROOT_CA_FILE).toURI()) + ) + ); + assertEquals( + certificate.getX509Certificate().getIssuerDN().getName(), + "CN=Fake Root CA" + ); + } + + /** + * Ensure that a Certificate cannot be created from a null byte array. + * + * @throws IOException if the certificate could not be constructed properly + * @throws CertificateException if there is a problem de/serializing the certificate + */ + @Test + public void testConstructCertFromNullByteArray() + throws IOException, CertificateException { + assertThrows(IllegalArgumentException.class, () -> + new CertificateAuthorityCredential((byte[]) null)); + } + + /** + * Ensure that a Certificate cannot be created from an empty byte array. + * + * @throws IOException if the certificate could not be constructed properly + * @throws CertificateException if there is a problem de/serializing the certificate + */ + @Test + public void testConstructCertFromEmptyByteArray() + throws IOException, CertificateException { + assertThrows(IllegalArgumentException.class, () -> + new CertificateAuthorityCredential(new byte[]{})); + } + + /** + * Tests that a certificate can be constructed from a path. + * + * @throws IOException if there is a problem reading the cert file at the given path + * @throws URISyntaxException if there is a problem constructing the URI + */ + @Test + public void testConstructCertFromPath() throws URISyntaxException, IOException { + Certificate certificate = new CertificateAuthorityCredential( + Paths.get(this.getClass().getResource(FAKE_ROOT_CA_FILE).toURI()) + ); + assertEquals( + certificate.getX509Certificate().getIssuerDN().getName(), + "CN=Fake Root CA" + ); + } + + /** + * Tests that a certificate cannot be constructed from a null path. + * + * @throws IOException if there is a problem reading the cert file at the given path + * @throws URISyntaxException if there is a problem constructing the URI + */ + @Test + public void testConstructCertFromNullPath() throws URISyntaxException, IOException { + assertThrows(IllegalArgumentException.class, () -> + new CertificateAuthorityCredential((Path) null)); + } + + /** + * Tests that Certificate correctly reports whether a certificate is a regular X509 cert or + * an X509 attribute certificate. + * + * @throws IOException if there is a problem reading the cert file at the given path + */ + @Test + public void testGetCertificateType() throws IOException { + assertEquals(getTestCertificate(FAKE_ROOT_CA_FILE).getCertificateType(), + Certificate.CertificateType.X509_CERTIFICATE); + assertNotEquals(getTestCertificate(FAKE_ROOT_CA_FILE).getCertificateType(), + Certificate.CertificateType.ATTRIBUTE_CERTIFICATE); + + assertNotEquals(getTestCertificate( + PlatformCredential.class, + PlatformCredentialTest.TEST_PLATFORM_CERT_3).getCertificateType(), + Certificate.CertificateType.X509_CERTIFICATE); + assertEquals(getTestCertificate( + PlatformCredential.class, + PlatformCredentialTest.TEST_PLATFORM_CERT_3).getCertificateType(), + Certificate.CertificateType.ATTRIBUTE_CERTIFICATE); + + } + + /** + * Ensures a certificate can be parsed from a PEM file. + * Tests both standard and attribute certificate headers. + * + * @throws IOException if there is a problem reading the test certificate + */ + @Test + public void testImportPem() throws IOException { + Certificate platformCredential = getTestCertificate( + PlatformCredential.class, PlatformCredentialTest.TEST_PLATFORM_CERT_4 + ); + + assertEquals(platformCredential.getCertificateType(), + Certificate.CertificateType.ATTRIBUTE_CERTIFICATE); + assertEquals( + ((PlatformCredential) platformCredential).getPlatformSerial(), + "GETY421001GV" + ); + + platformCredential = getTestCertificate( + PlatformCredential.class, PlatformCredentialTest.TEST_PLATFORM_CERT_5 + ); + + assertEquals(platformCredential.getCertificateType(), + Certificate.CertificateType.ATTRIBUTE_CERTIFICATE); + assertEquals( + ((PlatformCredential) platformCredential).getPlatformSerial(), + "GETY42100160" + ); + + } + + /** + * Tests that Certificate correctly parses out standard fields from an X509 Certificate. + * + * @throws IOException if there is a problem reading the cert file at the given path + */ + @Test + public void testX509CertificateParsing() throws IOException { + Certificate rootCert = getTestCertificate(FAKE_ROOT_CA_FILE); + X509Certificate certificate = readX509Certificate(FAKE_ROOT_CA_FILE); + + assertEquals(rootCert.getSerialNumber(), certificate.getSerialNumber()); + assertEquals(rootCert.getIssuer(), + certificate.getIssuerX500Principal().getName()); + assertEquals(rootCert.getSubject(), + certificate.getSubjectX500Principal().getName()); + assertArrayEquals(rootCert.getEncodedPublicKey(), + certificate.getPublicKey().getEncoded()); + assertArrayEquals(rootCert.getSignature(), certificate.getSignature()); + assertEquals(rootCert.getBeginValidity(), certificate.getNotBefore()); + assertEquals(rootCert.getEndValidity(), certificate.getNotAfter()); + } + + /** + * Tests that Certificate correctly parses out non standard fields from an X509 Certificate. + * + * @throws IOException if there is a problem reading the cert file at the given path + */ + @Test + public void testX509CertificateParsingExtended() throws IOException { + Certificate rootCert = getTestCertificate(INTEL_INT_CA_FILE); + assertEquals(rootCert.getAuthorityInfoAccess(), + "https://trustedservices.intel.com/" + + "content/TSC/certs/TSC_SS_RootCA_Certificate.cer\n"); + assertEquals(rootCert.getAuthorityKeyIdentifier(), + "b56f72cdfd66ce839e1fdb40498f07291f5b99b7"); + } + + /** + * Tests that Certificate correctly parses out standard fields from an X509 attribute + * certificate. + * + * @throws IOException if there is a problem reading the cert file at the given path + * @throws URISyntaxException if there is a problem constructing the file's URI + */ + @Test + public void testX509AttributeCertificateParsing() throws IOException, URISyntaxException { + Certificate platformCert = getTestCertificate( + PlatformCredential.class, + PlatformCredentialTest.TEST_PLATFORM_CERT_3 + ); + + X509AttributeCertificateHolder attrCertHolder = new X509AttributeCertificateHolder( + Files.readAllBytes(Paths.get(this.getClass().getResource( + PlatformCredentialTest.TEST_PLATFORM_CERT_3 + ).toURI())) + ); + + assertEquals( + platformCert.getSerialNumber(), + attrCertHolder.getSerialNumber() + ); + assertEquals( + platformCert.getIssuer(), + attrCertHolder.getIssuer().getNames()[0].toString() + ); + assertEquals(platformCert.getSubject(), null); + assertArrayEquals(platformCert.getEncodedPublicKey(), null); + assertArrayEquals(platformCert.getSignature(), attrCertHolder.getSignature()); + assertEquals(platformCert.getBeginValidity(), attrCertHolder.getNotBefore()); + assertEquals(platformCert.getEndValidity(), attrCertHolder.getNotAfter()); + } + + /** + * Tests that Certificate correctly parses out non-standard fields from an X509 attribute + * certificate. + * + * @throws IOException if there is a problem reading the cert file at the given path + * @throws URISyntaxException if there is a problem constructing the file's URI + */ + @Test + public void testX509AttributeCertificateParsingExtended() + throws IOException, URISyntaxException { + Certificate platformCert = getTestCertificate( + PlatformCredential.class, PlatformCredentialTest.TEST_PLATFORM_CERT_6); + + assertEquals(platformCert.getAuthorityInfoAccess(), + "https://trustedservices.intel.com/" + + "content/TSC/certs/TSC_IssuingCAIKGF_TEST.cer\n"); + assertEquals(platformCert.getAuthorityKeyIdentifier(), + "a5ecc6c07da02c6af8764d4e5c16483610a0b040"); + } + + /** + * Tests that Certificate correctly trims out additional padding from a given certificate. + * + * @throws IOException if there is a problem reading the cert file at the given path + * @throws URISyntaxException if there is a problem constructing the file's URI + */ + @Test + public void testCertificateTrim() throws IOException, URISyntaxException { + byte[] rawFileBytes = Files.readAllBytes(Paths.get(CertificateTest.class + .getResource(EK_CERT_WITH_PADDED_BYTES).toURI())); + byte[] expectedCertBytes = Arrays.copyOfRange(rawFileBytes, 0, 908); + Certificate ekCert = getTestCertificate(EndorsementCredential.class, + EK_CERT_WITH_PADDED_BYTES); + assertEquals(ekCert.getSerialNumber(), new BigInteger("16842032579184247954")); + assertEquals(ekCert.getIssuer(), + "CN=Nuvoton TPM Root CA 2010+O=Nuvoton Technology Corporation+C=TW"); + assertEquals(ekCert.getSubject(), ""); + assertArrayEquals(ekCert.getRawBytes(), expectedCertBytes); + } + + /** + * Tests that Certificate correctly throws IllegalArgumentException when no length field is + * found in the provided byte array. + * + * @throws IOException if there is a problem reading the cert file at the given path + * @throws URISyntaxException if there is a problem constructing the file's URI + */ + @Test + public void testCertificateTrimThrowsWhenNoLengthFieldFound() throws IOException, + URISyntaxException { + byte[] rawFileBytes = Files.readAllBytes(Paths.get(CertificateTest.class + .getResource(EK_CERT_WITH_PADDED_BYTES).toURI())); + assertThrows(IllegalArgumentException.class, () -> + new EndorsementCredential(Arrays.copyOfRange(rawFileBytes, 0, 2)), + ".* No certificate length field could be found\\."); + } + + /** + * Tests that Certificate correctly throws IllegalArgumentException when the byte array only + * contains a header for an ASN.1 Sequence. + * + * @throws IOException if there is a problem reading the cert file at the given path + * @throws URISyntaxException if there is a problem constructing the file's URI + */ + @Test + public void testCertificateTrimThrowsWhenOnlyASN1Sequence() throws IOException, + URISyntaxException { + byte[] rawFileBytes = Files.readAllBytes(Paths.get(CertificateTest.class + .getResource(EK_CERT_WITH_PADDED_BYTES).toURI())); + assertThrows(IllegalArgumentException.class, () -> + new EndorsementCredential(Arrays.copyOfRange(rawFileBytes, 0, 4)), + ".* Certificate is nothing more than ASN.1 Sequence\\\\."); + } + + /** + * Tests that Certificate correctly throws IllegalArgumentException when the provided + * Certificate has a length that extends beyond the byte array as a whole. + * + * @throws IOException if there is a problem reading the cert file at the given path + * @throws URISyntaxException if there is a problem constructing the file's URI + */ + @Test + public void testCertificateTrimThrowsWhenLengthIsTooLarge() throws IOException, + URISyntaxException { + byte[] rawFileBytes = Files.readAllBytes(Paths.get(CertificateTest.class + .getResource(EK_CERT_WITH_PADDED_BYTES).toURI())); + assertThrows(IllegalArgumentException.class, () -> + new EndorsementCredential(Arrays.copyOfRange(rawFileBytes, 0, 42)), + ".* Value of certificate length field extends beyond" + + " length of provided certificate\\."); + } + + /** + * Tests that the equals method on {@link Certificate} works as expected. + * + * @throws IOException if the certificate could not be constructed properly + * @throws CertificateException if there is a problem with the KeyStore or de/serializing the + * certificate + * @throws URISyntaxException if there is a problem constructing the path to the certificate + */ + @Test + public void testEquals() throws CertificateException, IOException, URISyntaxException { + assertEquals( + getTestCertificate(FAKE_ROOT_CA_FILE), + getTestCertificate(FAKE_ROOT_CA_FILE) + ); + + assertEquals( + new CertificateAuthorityCredential( + Paths.get(this.getClass().getResource(FAKE_ROOT_CA_FILE).toURI()) + ), + new CertificateAuthorityCredential( + Files.readAllBytes( + Paths.get(this.getClass().getResource(FAKE_ROOT_CA_FILE).toURI()) + ) + ) + ); + + assertNotEquals( + getTestCertificate(CertificateAuthorityCredential.class, FAKE_ROOT_CA_FILE), + getTestCertificate(CertificateAuthorityCredential.class, FAKE_INTEL_INT_CA_FILE) + ); + + assertNotEquals( + getTestCertificate(CertificateAuthorityCredential.class, FAKE_ROOT_CA_FILE), + getTestCertificate(ConformanceCredential.class, FAKE_ROOT_CA_FILE) + ); + + assertNotEquals( + getTestCertificate(CertificateAuthorityCredential.class, FAKE_ROOT_CA_FILE), + null + ); + } + + /** + * Tests that the isIssuer method on {@link Certificate} works as expected. + * + * @throws IOException if the certificate could not be constructed properly + * @throws CertificateException if there is a problem with the KeyStore or de/serializing the + * certificate + * @throws NoSuchProviderException if the Bouncy Castle security provider is unavailable + * @throws URISyntaxException if there is a problem constructing the path to the certificate + */ + @Test + public void testIsIssuer() throws CertificateException, IOException, NoSuchProviderException, + URISyntaxException { + Certificate issuerCert = getTestCertificate(FAKE_ROOT_CA_FILE); + Certificate cert = getTestCertificate(INT_CA_CERT02); + + assertEquals(issuerCert.isIssuer(cert), "Certificate signature failed to verify"); + assertTrue(cert.isIssuer(issuerCert).isEmpty()); + } + + /** + * Tests that the hashCode method on {@link Certificate} works as expected. + * + * @throws IOException if the certificate could not be constructed properly + * @throws CertificateException if there is a problem with the KeyStore or de/serializing the + * certificate + * @throws URISyntaxException if there is a problem constructing the path to the certificate + */ + @Test + public void testHashCode() throws CertificateException, IOException, URISyntaxException { + assertEquals( + getTestCertificate(FAKE_ROOT_CA_FILE).hashCode(), + getTestCertificate(FAKE_ROOT_CA_FILE).hashCode() + ); + + assertEquals( + new CertificateAuthorityCredential( + Paths.get(this.getClass().getResource(FAKE_ROOT_CA_FILE).toURI()) + ).hashCode(), + new CertificateAuthorityCredential( + Files.readAllBytes( + Paths.get(this.getClass().getResource(FAKE_ROOT_CA_FILE).toURI()) + ) + ).hashCode() + ); + + assertNotEquals( + getTestCertificate( + CertificateAuthorityCredential.class, FAKE_ROOT_CA_FILE + ).hashCode(), + getTestCertificate( + CertificateAuthorityCredential.class, FAKE_INTEL_INT_CA_FILE + ).hashCode() + ); + } + + /** + * Construct a CertificateAuthorityCredential from the given parameters. + * + * @param filename the location of the certificate to be used + * @return the newly-constructed Certificate + * @throws IOException if there is a problem constructing the test certificate + */ + public static Certificate getTestCertificate( + final String filename) throws IOException { + return getTestCertificate(CertificateAuthorityCredential.class, filename); + } + + + /** + * Construct a test certificate from the given parameters. + * + * @param the type of Certificate that will be created + * @param certificateClass the class of certificate to generate + * @param filename the location of the certificate to be used + * @return the newly-constructed Certificate + * @throws IOException if there is a problem constructing the test certificate + */ + public static Certificate getTestCertificate( + final Class certificateClass, final String filename) + throws IOException { + return getTestCertificate(certificateClass, filename, null, null); + } + + /** + * Construct a test certificate from the given parameters. + * + * @param the type of Certificate that will be created + * @param certificateClass the class of certificate to generate + * @param filename the location of the certificate to be used + * @param endorsementCredential the endorsement credentials (can be null) + * @param platformCredentials the platform credentials (can be null) + * @return the newly-constructed Certificate + * @throws IOException if there is a problem constructing the test certificate + */ + public static Certificate getTestCertificate( + final Class certificateClass, final String filename, + final EndorsementCredential endorsementCredential, + final List platformCredentials) + throws IOException { + + Path certPath; + try { + certPath = Paths.get(CertificateTest.class.getResource(filename).toURI()); + } catch (URISyntaxException e) { + throw new IOException("Could not resolve path URI", e); + } + + switch (certificateClass.getSimpleName()) { + case "CertificateAuthorityCredential": + return new CertificateAuthorityCredential(certPath); + case "ConformanceCredential": + return new ConformanceCredential(certPath); + case "EndorsementCredential": + return new EndorsementCredential(certPath); + case "PlatformCredential": + return new PlatformCredential(certPath); + case "IssuedAttestationCertificate": + return new IssuedAttestationCertificate(certPath, + endorsementCredential, platformCredentials); + default: + throw new IllegalArgumentException( + String.format("Unknown certificate class %s", certificateClass.getName()) + ); + } + } + + /** + * Return a list of all test certificates. + * + * @return a list of all test certificates + * @throws IOException if there is a problem deserializing certificates + */ + public static List getAllTestCertificates() throws IOException { + return Arrays.asList( + getTestCertificate(CertificateAuthorityCredential.class, FAKE_SGI_INT_CA_FILE), + getTestCertificate(CertificateAuthorityCredential.class, FAKE_INTEL_INT_CA_FILE), + getTestCertificate(CertificateAuthorityCredential.class, FAKE_ROOT_CA_FILE) + ); + } + + private static X509Certificate readX509Certificate(final String resourceName) + throws IOException { + + CertificateFactory cf; + try { + cf = CertificateFactory.getInstance("X.509"); + } catch (CertificateException e) { + throw new IOException("Cannot get X509 CertificateFactory instance", e); + } + + try (FileInputStream certInputStream = new FileInputStream( + Paths.get(CertificateTest.class.getResource(resourceName).toURI()).toFile() + )) { + return (X509Certificate) cf.generateCertificate(certInputStream); + } catch (CertificateException | URISyntaxException e) { + throw new IOException("Cannot read certificate", e); + } + } +} \ No newline at end of file diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/SupplyChainValidationTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/SupplyChainValidationTest.java new file mode 100644 index 00000000..95c35a64 --- /dev/null +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/SupplyChainValidationTest.java @@ -0,0 +1,121 @@ +package hirs.attestationca.persist.entity.userdefined; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import hirs.attestationca.persist.entity.ArchivableEntity; +import hirs.attestationca.persist.enums.AppraisalStatus; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.List; + +/** + * Simple tests for the {@link SupplyChainValidation} class. Tests for the persistence of this + * class are located in { SupplyChainValidationSummaryTest}. + */ +class SupplyChainValidationTest { + private static final String MESSAGE = "Some message."; + + /** + * Test that this class' getter methods work properly. + * + * @throws IOException if there is a problem deserializing certificates + */ + @Test + public void testGetters() throws IOException { + SupplyChainValidation validation = getTestSupplyChainValidation(); + assertEquals( + validation.getValidationType(), + SupplyChainValidation.ValidationType.ENDORSEMENT_CREDENTIAL + ); + assertEquals( + validation.getCertificatesUsed(), + CertificateTest.getAllTestCertificates() + ); + assertEquals(validation.getMessage(), MESSAGE); + } + + /** + * Test that a SupplyChainValidation can't be instantiated with a null validation type. + * + * @throws IOException if there is a problem deserializing certificates + */ + @Test + public void testNullValidationType() throws IOException { + assertThrows(IllegalArgumentException.class, () -> + new SupplyChainValidation( + null, + AppraisalStatus.Status.PASS, + CertificateTest.getAllTestCertificates(), + MESSAGE + )); + } + + /** + * Test that a SupplyChainValidation can't be instantiated with a null certificate list. + * + * @throws IOException if there is a problem deserializing certificates + */ + @Test + public void testNullCertificates() throws IOException { + assertThrows(IllegalArgumentException.class, () -> + new SupplyChainValidation( + SupplyChainValidation.ValidationType.ENDORSEMENT_CREDENTIAL, + AppraisalStatus.Status.PASS, + null, + MESSAGE + )); + } + + /** + * Test that a SupplyChainValidation can be instantiated with a null message. + * + * @throws IOException if there is a problem deserializing certificates + */ + @Test + public void testNullMessage() throws IOException { + new SupplyChainValidation( + SupplyChainValidation.ValidationType.ENDORSEMENT_CREDENTIAL, + AppraisalStatus.Status.PASS, + CertificateTest.getAllTestCertificates(), + MESSAGE + ); + } + + /** + * Construct a SupplyChainValidation for use in tests. It will have a validation + * type of ENDORSEMENT_CREDENTIAL, will represent a successful validation, and will use + * multiple test certificates. + * + * @return the test SupplyChainValidation + * @throws IOException if there si + */ + public static SupplyChainValidation getTestSupplyChainValidation() throws IOException { + return getTestSupplyChainValidation( + SupplyChainValidation.ValidationType.ENDORSEMENT_CREDENTIAL, + AppraisalStatus.Status.PASS, + CertificateTest.getAllTestCertificates() + ); + } + + /** + * Construct a SupplyChainValidation for use in tests according to the provided parameters. + * + * @param type the type of validation + * @param result the appraisal result + * @param certificates the certificates related to this validation + * @return the resulting SupplyChainValidation object + */ + public static SupplyChainValidation getTestSupplyChainValidation( + final SupplyChainValidation.ValidationType type, + final AppraisalStatus.Status result, + final List certificates) { + return new SupplyChainValidation( + type, + result, + certificates, + MESSAGE + ); + } +} \ No newline at end of file diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredentialTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredentialTest.java new file mode 100644 index 00000000..43b06ae4 --- /dev/null +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/certificate/PlatformCredentialTest.java @@ -0,0 +1,809 @@ +package hirs.attestationca.persist.entity.userdefined.certificate; + +import hirs.attestationca.persist.entity.userdefined.Certificate; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformConfiguration; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.PlatformProperty; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.TBBSecurityAssertion; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.URIReference; +import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.PlatformConfigurationV2; +import org.apache.commons.codec.binary.Hex; +import org.bouncycastle.util.encoders.Base64; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Calendar; +import java.util.List; +import java.util.TimeZone; + +/** + * Tests that a PlatformCredential parses its fields correctly. + */ +public class PlatformCredentialTest { + /** + * Location of a test platform attribute cert. + */ + public static final String TEST_PLATFORM_CERT_1 = + "/validation/platform_credentials/Intel_pc1.cer"; + + /** + * Location of another, slightly different platform attribute cert. + */ + public static final String TEST_PLATFORM_CERT_2 = + "/validation/platform_credentials/Intel_pc2.cer"; + + /** + * Location of another, slightly different platform attribute cert. + */ + public static final String TEST_PLATFORM_CERT_3 = + "/validation/platform_credentials/Intel_pc3.cer"; + + /** + * Platform cert with comma separated baseboard and chassis serial number. + */ + public static final String TEST_PLATFORM_CERT_4 = + "/validation/platform_credentials/Intel_pc4.pem"; + + /** + * Another platform cert with comma separated baseboard and chassis serial number. + */ + public static final String TEST_PLATFORM_CERT_5 = + "/validation/platform_credentials/Intel_pc5.pem"; + + /** + * Location of another, slightly different platform attribute cert. + */ + public static final String TEST_PLATFORM_CERT_6 = + "/validation/platform_credentials/TPM_INTC_Platform_Cert_RSA.txt"; + + /** + * Platform Certificate 2.0 with all the expected data. + */ + static final String TEST_PLATFORM_CERT2_1 = + "/validation/platform_credentials_2/basic_plat_cert.pem"; + + /** + * Platform Certificate spec 2. + */ + static final String TEST_PLATFORM_CERT2_SPEC2 = + "/validation/platform_credentials_2/large_attribute_spec2.txt"; + + /** + * Platform Certificate 2.0 with all the expected data. + */ + static final String TEST_PLATFORM_CERT2_2 = + "/validation/platform_credentials_2/small_plat_cert.pem"; + + /** + * Platform Certificate 2.0 with all the expected data. + */ + static final String TEST_PLATFORM_CERT2_3 = + "/validation/platform_credentials_2/medium_plat_cert.pem"; + + /** + * words. + */ + static final String TEST_BASE_PLATFORM_CERT_1 = + "/validation/platform_credentials/plat_base_cert1.pem"; + + /** + * words. + */ + static final String TEST_DELTA_PLATFORM_CERT_1 = + "/validation/platform_credentials/plat_delta_cert1.pem"; + + /** + * Platform Certificate 2.0 with all the expected data. + */ + static final String TEST_PLATFORM_CERT2_4 = + "/validation/platform_credentials_2/large_plat_cert.pem"; + + private static final String EXPECTED_CERT_SIGNATURE_FOR_CERTS_1 = + "425F6B2203EC6C651F3DA38416A39DB9B4D954A45FB1D1396D079ABE7" + + "29E6299297CFB57A971559BB29E13E1AABBF5E99C11968FED7B53CE3F" + + "4C71A889E893168A90C05F0F0D936B8D7E87531C616749DB647684DD2" + + "E430B6FB3B62F286407E99B7EC2D20860528C4E4DB3C7617BC321DF1E" + + "0E5F8DF601CB257BDE941E43CB0A8ED2B9EF1E95872C3FAE5A7195E16" + + "9D14C05BD6051BA1AEED482E5322CA58D09CD9979EF8C166198C83BA7" + + "243A2C79B9346B92ABB8C14E3AE950D5EB2E23CBEF1F124981949A413" + + "7EBE52DB0F4C1E8DD515E9FF0A22CE852FA85C7648D160F39F391E868" + + "74660B7FAA9ED150A36F0210B28AB6F840FCC61D81CD4F6FFF11B2A8"; + + private static final String EXPECTED_CERT_SIGNATURE_FOR_CERT_2 = + "67ABFBB91E0F061CA8CCE5DAA45104978D1020DE11DA65FD7DFD0E7C5" + + "1B84218B033C32D82ACA0C14A48C39EE1603A5939F84711B1" + + "95092ACB33FBA35B198019002C2326894ED0F7D17FA90450E" + + "7ABDEEFD098C12838BEB4595B8A6B3E20D1164D4EF3D580AC" + + "C16B8654B6E743B2A1D0397523870D0125EA90C3198C1C981" + + "FFD5687EF8343EBC083388EC59301665677B05848CC5FABB1" + + "E65C30F118DF391757D297BEA0197A4889A75969B4B3C1A52" + + "D4AD7DB115D86D58513A512A2B771E8EC606D0485A3A6B334" + + "88FC85CE84B40BEA7B73E7B56BA739344FCB6E7ADD6016623" + + "F1680F2E021A6F5888197572BE226623262A0736AEE6E6724" + + "BBD33AF8A068F6"; + + private static final String EXPECTED_CERT_SIGNATURE_FOR_CERT_3 = + "17342F73AB2B008707DE08CAD5C7974C0036004E4AABE6AA266823043" + + "D0B9852A3E5B6BCB632F6363A025D0B6CA382512C04281432" + + "D0B370D681804456ADF30B34EA4A8BA556110D3977D01B05B" + + "3227E420CF7487AB133EE43CE6EA0C98BE10E6101DF9BFA71" + + "61A464914530CB2A2F0BEB3E6CB7B9102816206B4CDB179CD" + + "9B6C70B95F5CBABD225780B7F4164650F613A8BEAE4AA96DD" + + "BFD60AA3CDFCD00753E9F70A08A7CDC69AF674C415836F6A8" + + "73D5D481862029479AA73A275C9224D400115CF1C7DA64E57" + + "9C0BD39D27671A1F2C9B241DB06353D54CF68C34A8935C6CD" + + "E3C5D9D0847D3CFEB7EDA51DD31FBB77607CEE194C9B33BF5" + + "ECF576F7E90484"; + private static final String EXPECTED_CERT_SIGNATURE_FOR_CERT_4 = + "77A3B38CD85DE0A7F24CE86A3B83C371B8EA9438863CEDDB04C7B16AD59" + + "3277B82E72D90B773CEC762A96F07A36D0AC0EE8189BAB87B607B" + + "4288F38A17B81B78B41D098134215796C61E66224808B3E3941BD" + + "48FB30066C01173E80CB531C5BE860EAFE17B6893A487F5FC512B" + + "5E5C75BC8FF66F95741480C4DB3826C64E41EA"; + + private static final String EXPECTED_CERT_SIGNATURE_FOR_CERT_5 = + "05EE695EB9161CB40CCF89F8D992494307BBC7A81E2D8B81BAF755D33ACE429" + + "277BA1453E900AF0C03BF1E5F09C886F7B86128CCD0CDF988FA469B" + + "D397BA967A028F5E1ED899B7999FA437F4FB748B75C509017A1284A" + + "D1098B0EB8C7E750D16FC99DADB0B32DF27B74F7BA1560DA56C3635" + + "47E84124E560B71D40B729326FC5"; + + private static final String EXPECTED_CERT_SIGNATURE_FOR_CERT2_1 = + "MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJVUzEUMBI" + + "GA1UECgwLRXhhbXBsZS5vcmcxDTALBgNVBAsMBHRlc3QxIDAeBgNVBAMMF1BsYXRmb" + + "3JtIENlcnRpZmljYXRlIENBMB4XDTE4MDQwNDE2NDUyMloXDTI4MDQwMzE2NDUyMlow" + + "VDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0V4YW1wbGUub3JnMQ0wCwYDVQQLDAR0Z" + + "XN0MSAwHgYDVQQDDBdQbGF0Zm9ybSBDZXJ0aWZpY2F0ZSBDQTCCASIwDQYJKoZIhv" + + "cNAQEBBQADggEPADCCAQoCggEBAKYnSJ7gHWl9BytxJQWWaYQzuYWjoeQ8PnLkYMm" + + "Kk8bV1v6hqRAg76p0QERubwtvDc3Rw0pVl5SqLku4ZzX7fzf3ra8IcrjR112f/ecAa" + + "gf+f4855anoYvBC5hELHnh6PQSyjl7wJJZiVLsB61gsumqfos5DnlaxoriUfW8Th26" + + "psnNIB+sbsn1f9WOHTDgXy81SGbgpG5+6joz1wXqpJvzZihIUNUSy8XQeusS22ZymI" + + "abL/Gs1P4doiJMeF651MNwjB/vdyG46KT56pDzc6TKJqo80Gb6HaeDS5RcakA9dRHz" + + "Vq7a3DOtzeNx84Cwl51tfE5MB/9mVP8grPjS5mQ8CAwEAAaNCMEAwDgYDVR0PAQH/B" + + "AQDAgIEMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNszjDaflH5+feDx2e/3OHI" + + "Fx/XrMA0GCSqGSIb3DQEBBQUAA4IBAQBkAGcfS3yLGQ4s/UXJjpyr8yGPJSvpbP87d" + + "B+9dtncXhaHikOAXDXh+4uwhbU1vxWoatetJR0SYj+hFfPeyhqOz8NXP0L4IZFQOe7" + + "23VNyTIhjpcbV/aqQq6wUC8FAvfsUc9FGZFjyKrWv/r454Wt3YSca6nlSOSWAU3xmW" + + "32E3upuduJT4+a/VTvx2/4tPqPxe9fgQU+RkuZwWTL/1l0G/IbpnEVWB+BmY3VdNAy" + + "au2zASSlprrEHQ4yr2u4QoOxbOmFx9aQIBHGw2srb4/iWegwfLxFLRnvqSTQp2ZU8i" + + "AD2mtNMSHSGu26zfmjtu2EokCrFCa2cSbOZV9pTkQQ4"; + + /** + * Tests parsing of a platform credential. + * + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void parseValidPlatformCertificate1() throws URISyntaxException { + URL resource = this.getClass().getResource(TEST_PLATFORM_CERT_1); + Path certPath = Paths.get(resource.toURI()); + + try { + new PlatformCredential(certPath); + //fail if it manage to parse the certificate + fail("Invalid certificate was parsed."); + } catch (IOException ex) { + if (ex == null || ex.getMessage().isEmpty()) { + //fail if the exception is empty or null + fail("Invalid Certificate produce null or empty exception"); + } else { + Assertions.assertEquals(ex.getMessage(), "Invalid Attribute Credential Type: "); + } + } + } + + /** + * Tests the parsing of a platform credential that has the subject directory attribute + * extension but is missing the subject alternative name extension. This certificate + * also has a policy extension, but it is not currently parsed. + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void parseValidPlatformCertificate3() throws IOException, URISyntaxException { + URL resource = this.getClass().getResource(TEST_PLATFORM_CERT_2); + Path certPath = Paths.get(resource.toURI()); + + PlatformCredential credential = new PlatformCredential(certPath); + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TimeZone.getTimeZone("UTC")); + calendar.set(2017, 2, 23, 22, 34, 33); + calendar.set(Calendar.MILLISECOND, 0); + Assertions.assertEquals(credential.getBeginValidity().getTime(), calendar.getTime().getTime()); + calendar.set(2030, 11, 31, 23, 59, 59); + Assertions.assertEquals(credential.getEndValidity().getTime(), calendar.getTime().getTime()); + + Assertions.assertNotNull(credential.getAttributeCertificate()); + byte[] sig = credential.getAttributeCertificate().getSignatureValue().getBytes(); + String sigStr = String.valueOf(Hex.encodeHex(sig)); + + Assertions.assertEquals(sigStr.toUpperCase(), EXPECTED_CERT_SIGNATURE_FOR_CERT_2); + + String issuer = Certificate.getAttributeCertificateIssuerNames( + credential.getAttributeCertificate().getAcinfo().getIssuer() + )[0].toString(); + + Assertions.assertEquals(credential.getManufacturer(), "Intel"); + Assertions.assertEquals(credential.getModel(), "DE3815TYKH"); + Assertions.assertEquals(credential.getVersion(), "H26998-402"); + Assertions.assertEquals(issuer, + "C=US,ST=CA,L=Santa Clara,O=Intel Corporation," + + "OU=Transparent Supply Chain,CN=www.intel.com"); + + Assertions.assertEquals(credential.getCredentialType(), "TCPA Trusted Platform Endorsement"); + + // the platform certificate in this test does not contain the following information + Assertions.assertEquals(credential.getPlatformSerial(), null); + Assertions.assertEquals(credential.getMajorVersion(), 1); + Assertions.assertEquals(credential.getMinorVersion(), 2); + Assertions.assertEquals(credential.getRevisionLevel(), 1); + Assertions.assertEquals(credential.getPlatformClass(), "1"); + } + + /** + * Tests the parsing of another platform credential that has the subject directory attribute + * extension but is missing the subject alternative name extension. This certificate + * also has a policy extension, but it is not currently parsed. + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void parseValidPlatformCertificate4() throws IOException, URISyntaxException { + URL resource = this.getClass().getResource(TEST_PLATFORM_CERT_3); + Path certPath = Paths.get(resource.toURI()); + + PlatformCredential credential = new PlatformCredential(certPath); + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TimeZone.getTimeZone("UTC")); + calendar.set(2017, 2, 23, 22, 34, 33); + calendar.set(Calendar.MILLISECOND, 0); + Assertions.assertEquals(credential.getBeginValidity().getTime(), calendar.getTime().getTime()); + calendar.set(2030, 11, 31, 23, 59, 59); + Assertions.assertEquals(credential.getEndValidity().getTime(), calendar.getTime().getTime()); + + Assertions.assertNotNull(credential.getAttributeCertificate()); + byte[] sig = credential.getAttributeCertificate().getSignatureValue().getBytes(); + String sigStr = String.valueOf(Hex.encodeHex(sig)); + + Assertions.assertEquals(sigStr.toUpperCase(), EXPECTED_CERT_SIGNATURE_FOR_CERT_3); + + String issuer = Certificate.getAttributeCertificateIssuerNames( + credential.getAttributeCertificate().getAcinfo().getIssuer() + )[0].toString(); + + Assertions.assertEquals(credential.getManufacturer(), "Intel"); + Assertions.assertEquals(credential.getModel(), "DE3815TYKH"); + Assertions.assertEquals(credential.getVersion(), "H26998-402"); + Assertions.assertEquals(issuer, + "C=US,ST=CA,L=Santa Clara,O=Intel Corporation," + + "OU=Transparent Supply Chain,CN=www.intel.com"); + + Assertions.assertEquals(credential.getCredentialType(), "TCPA Trusted Platform Endorsement"); + + // the platform certificate in this test does not contain the following information + Assertions.assertEquals(credential.getPlatformSerial(), null); + Assertions.assertEquals(credential.getMajorVersion(), 1); + Assertions.assertEquals(credential.getMinorVersion(), 2); + Assertions.assertEquals(credential.getRevisionLevel(), 1); + Assertions.assertEquals(credential.getPlatformClass(), "1"); + } + + /** + * Tests the parsing of a platform credential that has a combined baseboard and chassis + * serial number in one attribute can be parsed. + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void parseValidPlatformCertificate5() throws IOException, URISyntaxException { + URL resource = this.getClass().getResource(TEST_PLATFORM_CERT_4); + Path certPath = Paths.get(resource.toURI()); + + PlatformCredential credential = new PlatformCredential(certPath); + + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TimeZone.getTimeZone("UTC")); + calendar.set(2017, 3, 21, 17, 5, 29); + calendar.set(Calendar.MILLISECOND, 0); + Assertions.assertEquals(credential.getBeginValidity().getTime(), calendar.getTime().getTime()); + calendar.set(2030, 11, 31, 23, 59, 59); + Assertions.assertEquals(credential.getEndValidity().getTime(), calendar.getTime().getTime()); + + Assertions.assertNotNull(credential.getAttributeCertificate()); + byte[] sig = credential.getAttributeCertificate().getSignatureValue().getBytes(); + String sigStr = String.valueOf(Hex.encodeHex(sig)); + + Assertions.assertEquals(sigStr.toUpperCase(), EXPECTED_CERT_SIGNATURE_FOR_CERT_4); + + String issuer = Certificate.getAttributeCertificateIssuerNames( + credential.getAttributeCertificate().getAcinfo().getIssuer() + )[0].toString(); + + Assertions.assertEquals(credential.getManufacturer(), "Intel"); + Assertions.assertEquals(credential.getModel(), "DE3815TYKH"); + Assertions.assertEquals(credential.getVersion(), "H26998-402"); + Assertions.assertEquals(issuer, + "C=US,ST=CA,L=Santa Clara,O=Intel Corporation," + + "OU=Transparent Supply Chain,CN=www.intel.com"); + + Assertions.assertEquals(credential.getCredentialType(), "TCPA Trusted Platform Endorsement"); + + Assertions.assertEquals(credential.getChassisSerialNumber(), "G6YK42300C87"); + Assertions.assertEquals(credential.getPlatformSerial(), "GETY421001GV"); + } + + /** + * Tests the parsing another platform credential that has a combined baseboard and chassis + * serial number in one attribute can be parsed. + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void parseValidPlatformCertificate6() throws IOException, URISyntaxException { + URL resource = this.getClass().getResource(TEST_PLATFORM_CERT_5); + Path certPath = Paths.get(resource.toURI()); + + PlatformCredential credential = new PlatformCredential(certPath); + + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TimeZone.getTimeZone("UTC")); + calendar.set(2017, 3, 21, 17, 5, 30); + calendar.set(Calendar.MILLISECOND, 0); + Assertions.assertEquals(credential.getBeginValidity().getTime(), calendar.getTime().getTime()); + calendar.set(2030, 11, 31, 23, 59, 59); + Assertions.assertEquals(credential.getEndValidity().getTime(), calendar.getTime().getTime()); + + Assertions.assertNotNull(credential.getAttributeCertificate()); + byte[] sig = credential.getAttributeCertificate().getSignatureValue().getBytes(); + String sigStr = String.valueOf(Hex.encodeHex(sig)); + + Assertions.assertEquals(sigStr.toUpperCase(), EXPECTED_CERT_SIGNATURE_FOR_CERT_5); + + String issuer = Certificate.getAttributeCertificateIssuerNames( + credential.getAttributeCertificate().getAcinfo().getIssuer() + )[0].toString(); + + Assertions.assertEquals(credential.getManufacturer(), "Intel"); + Assertions.assertEquals(credential.getModel(), "DE3815TYKH"); + Assertions.assertEquals(credential.getVersion(), "H26998-402"); + Assertions.assertEquals(issuer, + "C=US,ST=CA,L=Santa Clara,O=Intel Corporation," + + "OU=Transparent Supply Chain,CN=www.intel.com"); + + Assertions.assertEquals(credential.getCredentialType(), "TCPA Trusted Platform Endorsement"); + + Assertions.assertEquals(credential.getChassisSerialNumber(), "G6YK42300CB6"); + Assertions.assertEquals(credential.getPlatformSerial(), "GETY42100160"); + } + + /** + * Tests isIssuer of a platform credential. + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void testIsIssuer() throws IOException, URISyntaxException { + + URL resource = this.getClass().getResource(TEST_PLATFORM_CERT2_1); + Path certPath = Paths.get(resource.toURI()); + + PlatformCredential platformCert = new PlatformCredential(certPath); + + Certificate issuer = new CertificateAuthorityCredential( + Base64.decode(EXPECTED_CERT_SIGNATURE_FOR_CERT2_1)); + + //Check if issuer certificate issued the platform credential + Assertions.assertTrue(platformCert.isIssuer(issuer).isEmpty()); + } + + /** + * Tests platform Configuration Values. + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void testPlatformConfiguration() throws IOException, URISyntaxException { + + URL resource = this.getClass().getResource(TEST_PLATFORM_CERT2_1); + Path certPath = Paths.get(resource.toURI()); + + PlatformCredential platformCert = new PlatformCredential(certPath); + PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + + //Check component identifier + List allComponents = platformConfig.getComponentIdentifier(); + if (allComponents.isEmpty()) { + Assertions.fail("Component Identifier is empty."); + } + + Assertions.assertEquals(allComponents.size(), 7); + ComponentIdentifier component; + + //Check component #2 + component = (ComponentIdentifier) allComponents.get(1); + Assertions.assertTrue(component.getComponentManufacturer() + .getString() + .equals("Intel Corporation")); + Assertions.assertTrue(component.getComponentModel() + .getString() + .equals("NUC7i5DNB")); + Assertions.assertTrue(component.getComponentSerial() + .getString() + .equals("BTDN732000QM")); + + //Check component #3 + component = (ComponentIdentifier) allComponents.get(2); + Assertions.assertTrue(component.getComponentManufacturer() + .getString() + .equals("Intel(R) Corporation")); + Assertions.assertTrue(component.getComponentModel().getString().equals("Core i5")); + Assertions.assertTrue(component.getFieldReplaceable().isTrue()); + + //Check component #5 + component = (ComponentIdentifier) allComponents.get(4); + Assertions.assertTrue(component.getComponentModel() + .getString() + .equals("Ethernet Connection I219-LM")); + Assertions.assertTrue(component.getComponentAddress().get(0) + .getAddressValue() + .getString() + .equals("8c:0f:6f:72:c6:c5")); + Assertions.assertTrue(component.getComponentAddress().get(0) + .getAddressTypeValue() + .equals("ethernet mac")); + + //Check Platform Properties + List platformProperties = platformConfig.getPlatformProperties(); + if (platformProperties.isEmpty()) { + Assertions.fail("Platform Properties is empty."); + } + + Assertions.assertEquals(platformProperties.size(), 2); + + PlatformProperty property; + + //Check property #1 + property = (PlatformProperty) platformProperties.get(0); + Assertions.assertTrue(property.getPropertyName().getString().equals("vPro")); + Assertions.assertTrue(property.getPropertyValue().getString().equals("true")); + + //Check property #2 + property = (PlatformProperty) platformProperties.get(1); + Assertions.assertTrue(property.getPropertyName().getString().equals("AMT")); + Assertions.assertTrue(property.getPropertyValue().getString().equals("true")); + + //Check Platform Properties URI + URIReference platformPropertyUri = platformConfig.getPlatformPropertiesUri(); + + Assertions.assertNotNull(platformPropertyUri); + Assertions.assertTrue(platformPropertyUri.getUniformResourceIdentifier() + .getString() + .equals("https://www.intel.com/platformproperties.xml")); + Assertions.assertNull(platformPropertyUri.getHashAlgorithm()); + Assertions.assertNull(platformPropertyUri.getHashValue()); + } + + /** + * Tests Platform Configuration Values. View platform Properties + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void testPlatformConfiguration2() throws IOException, URISyntaxException { + + URL resource = this.getClass().getResource(TEST_PLATFORM_CERT2_2); + Path certPath = Paths.get(resource.toURI()); + + PlatformCredential platformCert = new PlatformCredential(certPath); + PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + + //Check component identifier + List allComponents = platformConfig.getComponentIdentifier(); + Assertions.assertTrue(allComponents.isEmpty()); + + List platformProperties = platformConfig.getPlatformProperties(); + if (platformProperties.isEmpty()) { + Assertions.fail("Platform Properties is empty."); + } + Assertions.assertEquals(platformProperties.size(), 2); + + PlatformProperty property; + + //Check property #1 + property = (PlatformProperty) platformProperties.get(0); + Assertions.assertTrue(property.getPropertyName().getString().equals("vPro")); + Assertions.assertTrue(property.getPropertyValue().getString().equals("true")); + + //Check property #2 + property = (PlatformProperty) platformProperties.get(1); + Assertions.assertTrue(property.getPropertyName().getString().equals("AMT")); + Assertions.assertTrue(property.getPropertyValue().getString().equals("true")); + } + + /** + * Tests Platform Configuration Values. View platform Properties + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void testPlatformConfiguration3() throws IOException, URISyntaxException { + + URL resource = this.getClass().getResource(TEST_PLATFORM_CERT2_3); + Path certPath = Paths.get(resource.toURI()); + + PlatformCredential platformCert = new PlatformCredential(certPath); + PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + + //Check component identifier + List allComponents = platformConfig.getComponentIdentifier(); + if (allComponents.isEmpty()) { + Assertions.fail("Component Identifier is empty."); + } + + Assertions.assertEquals(allComponents.size(), 3); + ComponentIdentifier component; + + //Check component #2 + component = (ComponentIdentifier) allComponents.get(1); + Assertions.assertTrue(component.getComponentManufacturer() + .getString() + .equals("Intel(R) Corporation")); + Assertions.assertTrue(component.getComponentModel() + .getString() + .equals("Intel(R) Core(TM) i5-7300U CPU @ 2.60GHz")); + + //Check component #3 + component = (ComponentIdentifier) allComponents.get(2); + Assertions.assertTrue(component.getComponentModel() + .getString() + .equals("BIOS")); + Assertions.assertTrue(component.getComponentSerial() + .getString() + .equals("")); + Assertions.assertTrue(component.getComponentRevision() + .getString() + .equals("DNKBLi5v.86A.0019.2017.0804.1146")); + + //Check Platform Properties + List platformProperties = platformConfig.getPlatformProperties(); + if (platformProperties.isEmpty()) { + Assertions.fail("Platform Properties is empty."); + } + + Assertions.assertEquals(platformProperties.size(), 2); + + //Check Platform Properties URI + URIReference platformPropertyUri = platformConfig.getPlatformPropertiesUri(); + + Assertions.assertNotNull(platformPropertyUri); + Assertions.assertTrue(platformPropertyUri.getUniformResourceIdentifier() + .getString() + .equals("https://www.intel.com/platformproperties.xml")); + Assertions.assertNull(platformPropertyUri.getHashAlgorithm()); + Assertions.assertNull(platformPropertyUri.getHashValue()); + + //Test TBBSecurityAssertion + TBBSecurityAssertion tbbSec = platformCert.getTBBSecurityAssertion(); + Assertions.assertNotNull(tbbSec); + Assertions.assertTrue(tbbSec.getCcInfo().getVersion().getString().equals("3.1")); + Assertions.assertTrue(tbbSec.getCcInfo().getProfileOid().getId().equals("1.2.3.4.5.6")); + Assertions.assertTrue(tbbSec.getFipsLevel().getVersion().getString().equals("140-2")); + Assertions.assertTrue(tbbSec.getIso9000Uri().getString() + .equals("https://www.intel.com/isocertification.pdf")); + } + + /** + * Tests Platform Configuration Values. View platform Properties + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void testPlatformConfiguration4() throws IOException, URISyntaxException { + + URL resource = this.getClass().getResource(TEST_PLATFORM_CERT2_4); + Path certPath = Paths.get(resource.toURI()); + + PlatformCredential platformCert = new PlatformCredential(certPath); + PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + + //Check component identifier + List allComponents = platformConfig.getComponentIdentifier(); + if (allComponents.isEmpty()) { + Assertions.fail("Component Identifier is empty."); + } + + Assertions.assertEquals(allComponents.size(), 7); + ComponentIdentifier component; + + //Check component #1 + component = (ComponentIdentifier) allComponents.get(0); + Assertions.assertTrue(component.getComponentModel() + .getString() + .equals("NUC7i5DNB")); + Assertions.assertTrue(component.getComponentRevision() + .getString() + .equals("J57626-401")); + + //Check component #7 + component = (ComponentIdentifier) allComponents.get(6); + Assertions.assertTrue(component.getComponentAddress().size() > 0); + Assertions.assertTrue(component.getComponentAddress().get(0) + .getAddressValue() + .getString() + .equals("8c:0f:6f:72:c6:c5")); + Assertions.assertTrue(component.getComponentAddress().get(0) + .getAddressTypeValue() + .equals("ethernet mac")); + + //Check Platform Properties + List platformProperties = platformConfig.getPlatformProperties(); + if (platformProperties.isEmpty()) { + Assertions.fail("Platform Properties is empty."); + } + + Assertions.assertEquals(platformProperties.size(), 2); + + //Check Platform Properties URI + URIReference platformPropertyUri = platformConfig.getPlatformPropertiesUri(); + + Assertions.assertNotNull(platformPropertyUri); + Assertions.assertTrue(platformPropertyUri.getUniformResourceIdentifier() + .getString() + .equals("https://www.intel.com/platformproperties.xml")); + Assertions.assertNull(platformPropertyUri.getHashAlgorithm()); + Assertions.assertNull(platformPropertyUri.getHashValue()); + + //Test TBBSecurityAssertion + TBBSecurityAssertion tbbSec = platformCert.getTBBSecurityAssertion(); + Assertions.assertNotNull(tbbSec); + Assertions.assertTrue(tbbSec.getCcInfo().getVersion().getString().equals("3.1")); + Assertions.assertTrue(tbbSec.getCcInfo().getProfileOid().getId().equals("1.2.3.4.5.6")); + Assertions.assertTrue(tbbSec.getFipsLevel().getVersion().getString().equals("140-2")); + Assertions.assertTrue(tbbSec.getIso9000Uri().getString() + .equals("https://www.intel.com/isocertification.pdf")); + + } + + /** + * Tests Platform Configuration Values. View platform Properties + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void testPlatformConfiguration5() throws IOException, URISyntaxException { + + URL resource = this.getClass().getResource(TEST_PLATFORM_CERT2_SPEC2); + Path certPath = Paths.get(resource.toURI()); + + PlatformCredential platformCert = new PlatformCredential(certPath); + PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + + //Check component identifier + List allComponents = platformConfig.getComponentIdentifier(); + Assertions.assertFalse(allComponents.isEmpty()); + ComponentIdentifier component = allComponents.get(5); + Assertions.assertTrue(component.isVersion2()); + + List platformProperties = platformConfig.getPlatformProperties(); + if (platformProperties.isEmpty()) { + Assertions.fail("Platform Properties is empty."); + } + Assertions.assertEquals(platformProperties.size(), 3); + + PlatformProperty property; + + //Check property #1 + property = (PlatformProperty) platformProperties.get(0); + Assertions.assertTrue(property.getPropertyName().getString().equals("AMT")); + Assertions.assertTrue(property.getPropertyValue().getString().equals("true")); + + //Check property #2 + property = (PlatformProperty) platformProperties.get(1); + Assertions.assertTrue(property.getPropertyName().getString().equals("vPro Enabled")); + Assertions.assertTrue(property.getPropertyValue().getString().equals("true")); + + //Check property #3 + property = (PlatformProperty) platformProperties.get(2); + Assertions.assertTrue(property.getPropertyName().getString().equals("DropShip Enabled")); + Assertions.assertTrue(property.getPropertyValue().getString().equals("false")); + } + + /** + * Tests Platform Configuration Values. View platform Properties + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void testPlatformConfiguration6() throws IOException, URISyntaxException { + + URL resource = this.getClass().getResource(TEST_BASE_PLATFORM_CERT_1); + Path certPath = Paths.get(resource.toURI()); + + PlatformCredential platformCert = new PlatformCredential(certPath); + PlatformConfiguration platformConfig = platformCert.getPlatformConfiguration(); + + Assertions.assertTrue(platformConfig instanceof PlatformConfigurationV2); + Assertions.assertEquals(platformConfig.getPlatformPropertiesUri() + .getUniformResourceIdentifier().toString(), + "https://www.intel.com/platformproperties.xml"); + Assertions.assertNotNull(platformConfig.getComponentIdentifierUri()); + + Assertions.assertEquals(platformConfig.getComponentIdentifierUri() + .getUniformResourceIdentifier().toString(), + "https://www.intel.com/platformidentifiers.xml"); + + } + + /** + * Tests Platform Configuration Values. View platform Properties + * + * @throws URISyntaxException if there is a problem constructing the cert's URI + * @throws IOException if there is a problem reading the cert file + */ + @Test + public final void testSmallNewPlatformCredential() throws URISyntaxException, IOException { + Path path = Paths.get(this.getClass().getResource( + "/validation/platform_credentials_2/small_attribute_cert_2187.pem").toURI()); + PlatformCredential credential = new PlatformCredential(path); + Assertions.assertNotNull(credential); + } + + /** + * Tests Platform Configuration Values. View platform Properties + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void testMediumNewPlatformCredential() throws URISyntaxException, IOException { + Path path = Paths.get(this.getClass().getResource( + "/validation/platform_credentials_2/medium_attribute_cert_2187.pem").toURI()); + PlatformCredential credential = new PlatformCredential(path); + Assertions.assertNotNull(credential); + } + + /** + * Tests Platform Configuration Values. View platform Properties + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void testLargeNewPlatformCredential() throws URISyntaxException, IOException { + Path path = Paths.get(this.getClass().getResource( + "/validation/platform_credentials_2/large_attribute_cert_2187.pem").toURI()); + PlatformCredential credential = new PlatformCredential(path); + Assertions.assertNotNull(credential); + } + + /** + * Tests Platform Configuration Values. View platform Properties + * + * @throws IOException if an IO error occurs during processing + * @throws URISyntaxException if there is a problem constructing the cert's URI + */ + @Test + public final void testFlawedNewPlatformCredential() throws URISyntaxException, IOException { + Path path = Paths.get(this.getClass().getResource( + "/validation/platform_credentials_2/flawed_attribute_cert_2187.pem").toURI()); + PlatformCredential credential = new PlatformCredential(path); + Assertions.assertNotNull(credential); + } +} \ No newline at end of file diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/info/PortalInfoTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/info/PortalInfoTest.java new file mode 100644 index 00000000..2d825874 --- /dev/null +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/info/PortalInfoTest.java @@ -0,0 +1,127 @@ +package hirs.attestationca.persist.entity.userdefined.info; + +import hirs.utils.enums.PortalScheme; +import java.net.InetAddress; + +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.Test; + +/** + * Provides tests for PortalInfo. + */ +public class PortalInfoTest { + + /** + * Test the default state of the object, once constructed. + */ + @Test + public void testPortalInfoDefaults() { + PortalInfo info = new PortalInfo(); + assertNull(info.getName()); + assertNull(info.getIpAddress()); + assertEquals(info.getPort(), 0); + } + + /** + * Test that the scheme can be set and retrieved. + */ + @Test + public void testScheme() { + final PortalScheme scheme = PortalScheme.HTTPS; + + PortalInfo info = new PortalInfo(); + info.setSchemeName(scheme); + + assertEquals(info.getName(), scheme.name()); + } + + /** + * Test that setSchemeName does not accept a null input. + */ + @Test + public void testSchemeNull() { + final PortalScheme scheme = null; + + PortalInfo info = new PortalInfo(); + + try { + info.setSchemeName(scheme); + fail("The null scheme should have caused an error."); + } catch (NullPointerException e) { + assertNull(info.getName()); + } + } + + /** + * Test that the ip address can be set and retrieved via an InetAddress. + * @throws Exception If there is a problem with InetAddress. + */ + @Test + public void testIpAddressInetAddress() throws Exception { + final InetAddress address = InetAddress.getLocalHost(); + + PortalInfo info = new PortalInfo(); + info.setIpAddress(address); + + assertEquals(info.getIpAddress(), address); + } + + /** + * Test that the ip address can be set and retrieved via a String. + * @throws Exception If there is a problem with InetAddress. + */ + @Test + public void testIpAddressString() throws Exception { + final String address = "localhost"; + + PortalInfo info = new PortalInfo(); + info.setIpAddress(address); + + assertEquals(info.getIpAddress().getHostName(), address); + } + + /** + * Test that the scheme can be set and retrieved. + */ + @Test + public void testPort() { + final int port = 127; + + PortalInfo info = new PortalInfo(); + info.setPort(port); + + assertEquals(info.getPort(), port); + } + + /** + * Test that the context name can be set and retrieved. + */ + @Test + public void testContext() { + final String context = "Portal"; + + PortalInfo info = new PortalInfo(); + info.setContextName(context); + + assertEquals(info.getContext(), context); + } + + /** + * Test that setContextName does not accept a null input. + */ + @Test + public void testContextNull() { + final String context = null; + + PortalInfo info = new PortalInfo(); + + try { + info.setContextName(context); + fail("The null context should have caused an error."); + } catch (NullPointerException e) { + assertNull(info.getContext()); + } + } +} \ No newline at end of file diff --git a/HIRS_AttestationCA/src/test/resources/certificates/IntelSigningKey_20April2017.pem b/HIRS_AttestationCA/src/test/resources/certificates/IntelSigningKey_20April2017.pem new file mode 100644 index 00000000..bb74bdaa --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/IntelSigningKey_20April2017.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIEJVDCpzANBgkqhkiG9w0BAQUFADCBhzELMAkGA1UEBhMCVVMxCzAJBgNV +BAgTAkNBMRQwEgYDVQQHEwtTYW50YSBDbGFyYTEaMBgGA1UEChMRSW50ZWwgQ29ycG9yYXRpb24x +ITAfBgNVBAsTGFRyYW5zcGFyZW50IFN1cHBseSBDaGFpbjEWMBQGA1UEAxMNd3d3LmludGVsLmNv +bTAeFw0xNzA0MTkwMDAyMTBaFw0zNzEwMzEwMDAyMTBaMIGHMQswCQYDVQQGEwJVUzELMAkGA1UE +CBMCQ0ExFDASBgNVBAcTC1NhbnRhIENsYXJhMRowGAYDVQQKExFJbnRlbCBDb3Jwb3JhdGlvbjEh +MB8GA1UECxMYVHJhbnNwYXJlbnQgU3VwcGx5IENoYWluMRYwFAYDVQQDEw13d3cuaW50ZWwuY29t +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo7Cu8Y3uWKoTQW/RnmNJG5h3PlYdvE2B +v0c2+WUz0AprrVMpUvbJaNoMx47ev9CYvoxuJU0t9JjMm2i1u6Ol6VlK5yAWqr/qySvkryKTUuSx +7sOtkayF4LqD16LlTIAmUhC0KabbrEitpBa1BtKsy8yhGjbm+bYs0D19jjqHH9rOT3I8j04tc5a4 +r86dPuCZX8RJTV8tZd51ULFhl+70rIwPY/Ecbl5lzx786v9xW3XnC4/XplvMJXw2wkUo8G98qyeD +Odvha4Y49NswlqyUHnAlk+n4bIF7cvSDi+vb4YRaV2g5u2K3290ePUcNyzGTYgdpBnvOQlna/IZ0 +NifXQQIDAQABoyEwHzAdBgNVHQ4EFgQUIQWBMO10djQycITwJ5XfZw6L13MwDQYJKoZIhvcNAQEF +BQADggEBADgcp+GI5S6HSVhQD7wyqKIBCLUk5nC0FzE0W1vBuLrwCagXHXwMC09uDXOXtfNOoQVZ +duS3oaju5i40lSbFmp7V2hewQo6vlum/M05Lg/O7vndKxnKss/PeT5jMyjJ4t00HQ3KEm2aZL1BR +AJZjbH+hZ08bh5pY5uP7husjjcur0xqhFw9Afq4SUbXtA47QBaUuJTtBwTf2r/Nesq4a6zRAtqF/ +gmGD8VOSahBrtuIS30GRgcpsk6kKO4fLCvCZwyJ2/Mn+ySMB3+G6XqgDekkykCnnvMVUr+nzasug +d/4I62L3eZ2j5Xpa3O1kFZ+zIMrbLRh7Bu8OdjFdvodwmRU= +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/Intel_nuc_pc.pem b/HIRS_AttestationCA/src/test/resources/certificates/Intel_nuc_pc.pem new file mode 100644 index 00000000..1230354f --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/Intel_nuc_pc.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIDADCCAegCAQEwMKAuMBakFDASMRAwDgYDVQQDDAdTVE1pY3JvAhQrz0/5+zLfie1TVQpsz57k +yGtq3aCBkDCBjaSBijCBhzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRQwEgYDVQQHDAtTYW50 +YSBDbGFyYTEaMBgGA1UECgwRSW50ZWwgQ29ycG9yYXRpb24xITAfBgNVBAsMGFRyYW5zcGFyZW50 +IFN1cHBseSBDaGFpbjEWMBQGA1UEAwwNd3d3LmludGVsLmNvbTANBgkqhkiG9w0BAQUFAAIUQtCe +CYR41o33Qv3So+KiQIZviFAwIhgPMjAxNzAzMTUyMTA4MzBaGA8yMDMwMTIzMTIzNTk1OVowMTAZ +BgVngQUCETEQMA4wCQIBAQIBAgIBAQwBMTAUBgVngQUCEzELMAkCAQCCAQMBAQAwgaEwTQYDVR0g +AQH/BEMwQTA/BgoqhkiG+E0BBQIEMDEwLwYIKwYBBQUHAgIwIwwhVENQQSBUcnVzdGVkIFBsYXRm +b3JtIEVuZG9yc2VtZW50MFAGA1UdEQEB/wRGMESkQjBAMRAwDgYFZ4EFAgQMBUludGVsMRUwEwYF +Z4EFAgUMCkRFMzgxNVRZS0gxFTATBgVngQUCBgwKSDI2OTk4LTQwMjANBgkqhkiG9w0BAQUFAAOC +AQEAXPD46MxZy0vQlSQ7EOMRgBSDWUS9561Gc2IKM0FqXcYWi6YT4NAk1rx/j/ycA87fNiJzOjSC +D1qv5MAaI3IOuqE911Hk/lsZ9Xq25a5c6BeQjyCpwI/qNno0rnTINjOXYllurVzU6Dn109f1NQS/ +m9ZkJ1gicMWkna2mEO842kH5CfqaskRqUGOO5nViO6Y094pzwT/Zp+W2CRqAo1BwDIV8OM6u4AZn +EagFlbpPqnU8IfFO2n4zeILADiJ9TkXJovvfemJnoZlzcUPO6+8wjjsbtojEiu4bQF9QwIc/VtDS +YUYstwwuACuSxE6jvhROuZHiTBE85623uE0eMQl5vA== +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/Intel_nuc_pc2.pem b/HIRS_AttestationCA/src/test/resources/certificates/Intel_nuc_pc2.pem new file mode 100644 index 00000000..81f1acb9 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/Intel_nuc_pc2.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIDADCCAegCAQEwMKAuMBakFDASMRAwDgYDVQQDDAdTVE1pY3JvAhRrZ4VfPG34FALdQNaVQ0q4 +szdWuKCBkDCBjaSBijCBhzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRQwEgYDVQQHDAtTYW50 +YSBDbGFyYTEaMBgGA1UECgwRSW50ZWwgQ29ycG9yYXRpb24xITAfBgNVBAsMGFRyYW5zcGFyZW50 +IFN1cHBseSBDaGFpbjEWMBQGA1UEAwwNd3d3LmludGVsLmNvbTANBgkqhkiG9w0BAQUFAAIUM1Nq +X1KDMb4erHbXmwv9sBEi9E8wIhgPMjAxNzAzMTQyMzUyMTBaGA8yMDMwMTIzMTIzNTk1OVowMTAZ +BgVngQUCETEQMA4wCQIBAQIBAgIBAQwBMTAUBgVngQUCEzELMAkCAQCCAQMBAQAwgaEwTQYDVR0g +AQH/BEMwQTA/BgoqhkiG+E0BBQIEMDEwLwYIKwYBBQUHAgIwIwwhVENQQSBUcnVzdGVkIFBsYXRm +b3JtIEVuZG9yc2VtZW50MFAGA1UdEQEB/wRGMESkQjBAMRAwDgYFZ4EFAgQMBUludGVsMRUwEwYF +Z4EFAgUMCkRFMzgxNVRZS0gxFTATBgVngQUCBgwKSDI2OTk4LTQwMjANBgkqhkiG9w0BAQUFAAOC +AQEALBdTOKTd4wyKOBvKUGsDwfjiKVir93XmTa1SW/B176ZAhfxasEnqD1idi051DHKyF9Sw4VDC +vQfc7XE5QqBsqIrt1Fqq88dDbrcCauinzG6KBApG+cIbKT6K/wYeBwbvhpuDEeytQmv4noYG1FnA +U+eSdVvwha/4f2QeMNlnNxDMvyvi11oeTeIG3LO5Bp0UYmPNuozsOyY8eztFmHJ27xq0QbYKh6dV +I5kwuIPZz4VK9E7AuhDZcYpp2JgyUBFdJUA2a156NGC1JnYmxJ+WBxd+oQ41SLSbMUpymsQyFwvQ +WxuOaLnGLiHwrxXgvhsisH8MO/WkOo+iBDxQrTpkAw== +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/ab21ccf2-tpmcert.pem b/HIRS_AttestationCA/src/test/resources/certificates/ab21ccf2-tpmcert.pem new file mode 100644 index 00000000..9a9e2389 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/ab21ccf2-tpmcert.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEXjCCA0agAwIBAgIUWGRkKsiikVUJWz+eO8Pz0lN6xUwwDQYJKoZIhvcNAQEF +BQAwVTELMAkGA1UEBhMCQ0gxHjAcBgNVBAoTFVNUTWljcm9lbGVjdHJvbmljcyBO +VjEmMCQGA1UEAxMdU1RNIFRQTSBFSyBJbnRlcm1lZGlhdGUgQ0EgMDIwHhcNMTQw +MTE3MDAwMDAwWhcNMjQwMTE3MDAwMDAwWjAAMIIBNzAiBgkqhkiG9w0BAQcwFaIT +MBEGCSqGSIb3DQEBCQQEVENQQQOCAQ8AMIIBCgKCAQEAqyHM8tOsFtL2QEEAX+Tq +HPdi6TOZQ3Dc1sgCgwms4jRzoIoVcTMmYZhLY2qHiM0lnFXKEwb/3ox3Hzw5/ZFW +aSizfykbGN5tSkHBlBq9i8vK5i6/WcmOk88ai+VP8+pYTiFQRVQjjnrTV8YDg0pT +HIo+ZcUHVT5shxXISu7QEQe4ZnhiNG6BQmJH2+ytcUkCDh3m3pMgGsWehEMvrOSi +IjxMgKtb8MLQ4pijB81x2Tb4Wun2O5J/uUie+QbdWbbfLWOaFcH72WV9KzHcliKm +ICNqgBO9OBbB4SSzsTZY/vZ7G/xAsDaTfQdacm/qgnoXpU33dXdmY1QJTxHc5lYc +PwIDAQABo4IBZDCCAWAwHwYDVR0jBBgwFoAUVx+Aa0fM55v6NZR87Yi40QBa4J4w +QgYDVR0gBDswOTA3BgRVHSAAMC8wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cuc3Qu +Y29tL1RQTS9yZXBvc2l0b3J5LzBVBgNVHREBAf8ESzBJpEcwRTEWMBQGBWeBBQIB +DAtpZDo1MzU0NEQyMDEXMBUGBWeBBQICDAxTVDMzWlAyNFBWU1AxEjAQBgVngQUC +AwwHaWQ6MEQwQzB/BgNVHQkEeDB2MBYGBWeBBQIQMQ0wCwwDMS4yAgECAgF0MCAG +BWeBBQISMRcwFQIBAAEB/6ADCgEBoQMKAQCiAwoBADA6BgNVBTQxMzAkMCIGCSqG +SIb3DQEBBzAVohMwEQYJKoZIhvcNAQEJBARUQ1BBMAswCQYFKw4DAhoFADAMBgNV +HRMBAf8EAjAAMBMGA1UdJQEB/wQJMAcGBWeBBQgBMA0GCSqGSIb3DQEBBQUAA4IB +AQCN1xBDK47IE+Hs5/GcC8GG55A9THUocrVwGCXi5rN1CT7QnlypzEgxAhVBFZKI +X+AZLjB5HRczAlCH7kqbfNEGjcSMLQP61+7bkvAPcdfJtr9nLR8eK/tIlRcsXX33 +vE7HcnuDvuzyumb9x+RFT6tol/MhSVVA9/ETyTa4v9n2kZHQVo5KycU0fIUvQ0xe +CxU0kIdR8S6LcpBT1nSr8I8wgtaqKaoqQrMfBjAqVJYpogCUe2OLhRT8KzP/Ow3m +OarP5jgMM+rQpOHeqb/BxIrUl77ER2BJ7LIVIuCLl+cOUgsdTz46ZhY0HKVmKotu +0LThZ6mEE8+9rcaQtZsmYbRx +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/ek_cert_with_padded_bytes.cer b/HIRS_AttestationCA/src/test/resources/certificates/ek_cert_with_padded_bytes.cer new file mode 100644 index 0000000000000000000000000000000000000000..65426766e4ce2c318559e09cac9d8cf38ef4b59a GIT binary patch literal 1100 zcmXqLV(u_#Vk%g`%*4pV#L4h-*Xz`qS6wC<@Un4gwRyCC=VfGMWo0l3H4HY8XJZa! zVHTF~D=o_}$=3Gh`2%Fi!RaCTHMGB7kSPz5RA5|)E2NKMYj%g@PAuT*f(FDl3{ zN-W9D&okfzDPt363JEum6X!KFGcYwWGBPl-G&PPA=QRd$4K1Kt0|tX8#&`oSgj?7R zY!`3?O<>jLV`h?KWmqU-Acm0TK$2M`VjzT&;bdVAaSm`~U~XdM2N}x6)WpchFyn{t zE|Cw#9k1tkIV4y6>dP8dds%GD@C>;Xu*&A6g&mXl-K0Dj;a3$cw0v7i7jQU{ruhLs%bTo(*B7{n2z7s_qSB+Q}`Oc8}}r)e&{w`Tr1dfyqcT4 z?^~4q6<@Q((+|%*Y@2C)o~bD9_mtI}cAwOoYbrO@?e3*2pQo31bcRpYcjqsT;cHr( zqxkYV;|z`ES7&BzjBmYcK6T%5zuUZ5O0`d{eO1mic>M-)UR->i(OY z=Zeo?ZNH|?#LURRxVYG$(7*>6C$fT!jQ?4j3>=o&8Q2(F8Hlj4rZ=)OF$!~MrdXM{ znwppx8yFY}Kt!2@+5G~XL(D2FU?R-I>_Bw}rWS?7cg2F8JKUyd8?Q%FR$v~60?`d>HOK!{|jm#@I!}ynZUTF=W?U zp*OqKDwg_RuARthlD@V-;(Pl4|6lg|wBFyI=y*f*Jk!@w$BJvE;$zpyWUp1=3ZLyV7kJ&vv;)|uZhdXrmZkxd+Bg?G(*jd{?%9XD8*z-H1#(Uf0p48Q*KOHqp&eyJMdX=1TO+O=a_p;he%hpZ( b)Wl@K?scGx=i>j>MR&6Uw)+1R9O3`~^{Qw) literal 0 HcmV?d00001 diff --git a/HIRS_AttestationCA/src/test/resources/certificates/ek_cert_with_security_assertions.cer b/HIRS_AttestationCA/src/test/resources/certificates/ek_cert_with_security_assertions.cer new file mode 100644 index 0000000000000000000000000000000000000000..e05b049d05107ab1884c946f1614f30a06d00b73 GIT binary patch literal 1704 zcmWe&WMC~9U@~Z8Ei`CiiCnA1Dvxa0s&nCsyR=RT?T9$b$s9ge5%l(lYZ>^Yau!Qj;_C@^kXjGgFHd z9Ni6h47fl_xP_S=J$((;3{*foW?@-Rw+Mxh0AB@HZw1f1lGLKy)RfG`l2ip}M+E~5 z137VCLt{fjLsLUDV`D?(C~;mRWUc{&K@+37ffB;C>;|HXgbf4{0-P)?A z+jUAMe7oSi;8QES%X0SW>F+%%dyW6m;s(ZGE!{t@!JBJ$UHGN?y?50L-((lo>le4D zU5$LOESG)$a>Ki6Tjo5!;8!A^*pj5i>3UO8Kl{3M`0cl0+QtXo?9}CAEIYY#w#fG< zmnY-|>u02R3V)cg?%u|{JD& z^3(87t+(Ywk8)=0TC1vJS;)l9$iTR`i7C~fi7C+_6c`nXN+Ld2PPc!GVLEX|BfLqZJoj0}Yg1RxU3JnTRX z2Ee#7-~kyc3^JAp7*CCRKwJe7w{fFE<2r-J)ok1eZ61tmKU^8v^%)HsXB$|uacHvv z6C67eqnK_+NlAf~zJ7Umxn5anQD$*wdY)c#ey)B|YC(Q+W=VcgrG92!N@|5(MoDgt zK^$BwlR=PN07D3aGeZD_BZC5vRm4!rP|Q%mkjjt(1GOXD1a#+eNwKHk15og7c1|3wL0PHtb; zvF_mciiOonDhDj5G_i1G$cY&=P6j!XlcllSps~Zi3dmtG0Y(KV_p)m9F*8X4GqVaY z`NcpC5}yKwyawDn%)mGX6%LHd21XEZAwx|Abzo#JVCG_ETnHo>7J-Px0tS3y%*J|# zT#PJ0E>Hmwp_L}UtjNf)T=ny1iAk)xKh$hh{=4n_3VS8db3emo&Dv3RxSanUg9XRd ziaRnlUYTcvF-^Q!B5+~KxhZy;hg|+Q-JcX+T^+=H=TO+Q(rdd*6PrHyR&&NlIM4cE zw)2CI;nKS)Gd`)+Xfl4g)!SLO=+5jATa11%CUoH*IQi*8is%_*uBT zW!tl=f_Ex0>UL>C!Z!C3k96s4bDh04sbt2N)_47H>xJHwn-ub9SYK*1t7qR*P^h`{ jQA4-(-d*A!`l_DPGIqD`FN!n2@7lAtrHf${5FG*ln9IaW literal 0 HcmV?d00001 diff --git a/HIRS_AttestationCA/src/test/resources/certificates/fakeCA.pem b/HIRS_AttestationCA/src/test/resources/certificates/fakeCA.pem new file mode 100644 index 00000000..9ea625d2 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/fakeCA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5zCCAdGgAwIBAgIBATALBgkqhkiG9w0BAQswFzEVMBMGA1UEAwwMRmFrZSBS +b290IENBMB4XDTE3MDEyNDE1MjU0MVoXDTQ3MDEyNDE1MjU0MVowFzEVMBMGA1UE +AwwMRmFrZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +geIXUAtrlc+FY8FC/bAGC6Vg1lbok+kILT/ZmG/4vdigZ2hzFR3dVjmgWd4hp3uP +dY7E/JUEouBq24qDpPUWrHIxSCqGp9Rn+whGq6Yy7d1d0FGyskIJJ2aFr1QC+/jA +4CptLbQGhqmyALrmXFai3scUmNciuTbEb3Ap9829IdsD4F9hT557zRSocaelVCUw +6sNLU78fJfG7K3dKmKemvtprqlDlfM3nya5P6IzkRKiPpXN6Q1sL7FDkKQ3HuyBM +WqPU+AWhqhCR9hRenuTpwTxEPVPA8FRV78wkV3VLzXCG7lHPZ8xCDKAZzdbwymjU +wfm9Wr5KperE83suIcIHxQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUWOwxOhaZ+UwcjE4sZBJAKyWPAXcwCwYJKoZI +hvcNAQELA4IBAQBzEIk46ajACN11nMYXg/dIS21UMjfpkOhv8dYzE5WMMtMhiiUG +3PnvVt/THIWResw1iW7OGjX9dTQ0mMSK59dH/eDqbLyle6HqWHJnKuZWjP5h1W2a +vKUgOvr7Oh0NelYFGUmUD+zOBWnKhUidO+R/BE0AifnnR+WbyMgpAjlWv5ErhukY +NN+wi6X8O38GM9+Q+OjF83zKOdV5CmMb0KHGr8xfE0tiqHMiJoDt+Jk4XysLUnrR +7+8qS+30a+FwErt0/dhqHI3/iEwPNc1jtuA6yP+vt4IE4sSPXUPh2Z2pm8Je2goQ +ybWqhqtMT1QoTT2E2GzJ9JBSt3yEZPEQn+kt +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/fakeIntelIntermediateCA.cer b/HIRS_AttestationCA/src/test/resources/certificates/fakeIntelIntermediateCA.cer new file mode 100644 index 00000000..cf8ed36b --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/fakeIntelIntermediateCA.cer @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDGDCCAgKgAwIBAgIBAjALBgkqhkiG9w0BAQswFzEVMBMGA1UEAwwMRmFrZSBS +b290IENBMB4XDTE3MDEyNDE1MjU0MVoXDTI3MDEyNDE1MjU0MVowJzElMCMGA1UE +AwwcRmFrZSBJbnRlbCBJbnRlcm1lZGlhdGUgQ0EgMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKOwrvGN7liqE0Fv0Z5jSRuYdz5WHbxNgb9HNvllM9AK +a61TKVL2yWjaDMeO3r/QmL6MbiVNLfSYzJtotbujpelZSucgFqq/6skr5K8ik1Lk +se7DrZGsheC6g9ei5UyAJlIQtCmm26xIraQWtQbSrMvMoRo25vm2LNA9fY46hx/a +zk9yPI9OLXOWuK/OnT7gmV/ESU1fLWXedVCxYZfu9KyMD2PxHG5eZc8e/Or/cVt1 +5wuP16ZbzCV8NsJFKPBvfKsngznb4WuGOPTbMJaslB5wJZPp+GyBe3L0g4vr2+GE +WldoObtit9vdHj1HDcsxk2IHaQZ7zkJZ2vyGdDYn10ECAwEAAaNjMGEwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFCEFgTDtdHY0MnCE +8CeV32cOi9dzMB8GA1UdIwQYMBaAFFjsMToWmflMHIxOLGQSQCsljwF3MAsGCSqG +SIb3DQEBCwOCAQEAb9OPfUQSOZG5JLNJTMJtBUXWPAAhR7xXvWtG17B3c8UrU4kN +bfqAQnVkya+7vUPpaxVP5KJjzud8hBg5xqgaf7MO5mq/P+3RmtudB/AunTiBApSL +f0nXEMl3UbGdfseWnrEC0QMetsBDgPyhUAJ+P+KwEWWndpaeZRV1pfvPc2OMqG3J +or8hmfEVk2k9Di3GThsA5PnKehYE+FGHtT2+YO5Tpn75PdhN8r2N6MU7kXVPN9yi +5RT5HKpee8ZmkzYdOhWe7+7W23j3Klh3yyVHW1Yk426PRuRym9RrPOZO8dSJY0n5 +abPM8+BCy4GpK/wdUuZhKBo1BX/Mq7fMfR07kQ== +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/fakeIntelIntermediateCA.pem b/HIRS_AttestationCA/src/test/resources/certificates/fakeIntelIntermediateCA.pem new file mode 100644 index 00000000..f1da5126 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/fakeIntelIntermediateCA.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDGDCCAgKgAwIBAgIBAjALBgkqhkiG9w0BAQswFzEVMBMGA1UEAwwMRmFrZSBS +b290IENBMB4XDTE3MDIwNDE2MTgyOVoXDTI3MDIwNDE2MTgyOVowJzElMCMGA1UE +AwwcRmFrZSBJbnRlbCBJbnRlcm1lZGlhdGUgQ0EgMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAJazRiYf5J/QajAvSmUh+HYbBebXCaf7iIbYKEd1O0eF +qXGIbaWnNss53zyrBXos38fnIUl8NNFFywegnhtk2WgyF8fOgqwL0umr32Q1KMjS +bnDMwPqZFeWuDDt+JzxIz2GnI4JqqM/N/hWeEVqk4BzGeCCjFjuI5bypyvIWua3t +bV2Z4B36VHZ0pUz5wX3v86BLgRdHggBDpwPEMEp39A494X2k9YDuZdXjEsGf9i7a +yDoUBswOZfIubBweibXOd7slvR1utzPg5AfSfR6J8DPa9/hXmcQmezWroc6MX4TR +VJwv+Bv4g5rnPKxnYkEy5oEPgi+MqHYTpju0AhXqhysCAwEAAaNjMGEwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0OBBYEFLWs0BQDIqbT/Q7Z +dOWPEHF2opvqMB8GA1UdIwQYMBaAFFjsMToWmflMHIxOLGQSQCsljwF3MAsGCSqG +SIb3DQEBCwOCAQEAH5RkL203pAaKH03VtE0Fv3Hzv08M0aDBs7OcfNY8fNX38oPT +axdZ2hf9W5TyTfIMyfZde+Lo6C26LdfRT4YQE3h9O2TdCarU58FiYfRGf1n2QAHb +rMnItYpNRjDvqe0Om4jk2fUqzbVikDSS4Ca0yu86STO8+RIAKlro5dNyQ89GAMcj +LrtzDhQRxIhDQUUfH/brOqFulNx55Fbkd60eRAASIai7t4aWLIC7K/MKkC/Mn+aH +ayYbtXbHNEPsExkIN4i7wtsKklOoflBRPxHqe8iUd3MA3sYlh6kmVGGiElx8enUT +SQMwd2Eua7amb2mvpFhQ79BvzAarkIgFII2NXQ== +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/fakeIntel_S2600KP_F00F00F00F00-Att.pem b/HIRS_AttestationCA/src/test/resources/certificates/fakeIntel_S2600KP_F00F00F00F00-Att.pem new file mode 100644 index 00000000..03ee4f96 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/fakeIntel_S2600KP_F00F00F00F00-Att.pem @@ -0,0 +1,20 @@ +-----BEGIN ATTRIBUTE CERTIFICATE----- +MIIDUzCCAkECAQEwMKAuMBakFDASMRAwDgYDVQQDDAdTVE1pY3JvAhRYZGQqyKKR +VQlbP547w/PSU3rFTKCBkjCBj6SBjDCBiTEWMBQGA1UEAwwNd3d3LmludGVsLmNv +bTEbMBkGA1UECwwSVHJ1c3RlZFN1cHBseUNoYWluMRowGAYDVQQKDBFJbnRlbCBD +b3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExEzARBgNVBAgMCkNhbGlm +b3JuaWExCzAJBgNVBAYTAlVTMAcGBSsOAwIdAgEBMCIYDzIwMTYwODExMTgxOTM2 +WhgPMjAxNzA4MTExODE5MzZaME4wTAYIKwYBBQUHAgIxQDA+MBkMFUNyZWRlbnRp +YWwgVHlwZSBMYWJlbDAADCFUQ1BBIFRydXN0ZWQgUGxhdGZvcm0gRW5kb3JzZW1l +bnQwgfQwXwYDVR0RBFgwVjEQMA4GBWeBBQIEDAVJbnRlbDESMBAGBWeBBQIFDAdT +MjYwMEtQMRUwEwYFZ4EFAgYMCkgxMzg4OC0zNTAxFzAVBgVngQUCFwwMRjAwRjAw +RjAwRjAwMHAGA1UdCQRpMGcwGQYFZ4EFAhExEDAOMAkCAQECAQICAQEMATEwSgYF +Z4EFAhMxQTA/AgEBMBgWCkNDIFZlcnNpb24KAQcKAQIBAQAKAQEKAQIBAf8WGlVS +TCB0byBpc285MDAwIGNlcnRpZmljYXRlMB8GA1UdIwQYMBaAFLWs0BQDIqbT/Q7Z +dOWPEHF2opvqMAcGBSsOAwIdA4IBAQAWMj17Bk+dNYR6IHUyp/vTAh8gvgUw2Nnb +fZzbnA8nC6gLeCQYBD3F5we4YVUh9+rVv0dBwiZu9a46K3v2+kZYp7AtxyNs8f/R +ANyIUWsKOxyptqTuwEzC5UybRrRg0qVEY9hPGfZ0cas8vlhrO8TdlSuCHEYfLsgt +fYIgn6MiSG5GrGdIhWRcdNdQfeXNPjIzyXfP+1MD0CFvaDvRSphHP99mXUUlQija +9oBG5+JVahnP/LLx5q7wZZMYQtMNa+yGo2ictu/mteVgRR9KJb8RwYVMP9rflSQC +8/VrySFZUJMzGY2bFqv8WOWG3nOjaZvMV30P0c00eevObmzxrCKD +-----END ATTRIBUTE CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/fakeIntel_S2600KP_F00F00F00F00.pem b/HIRS_AttestationCA/src/test/resources/certificates/fakeIntel_S2600KP_F00F00F00F00.pem new file mode 100644 index 00000000..58c510f0 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/fakeIntel_S2600KP_F00F00F00F00.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDUzCCAkECAQEwMKAuMBakFDASMRAwDgYDVQQDDAdTVE1pY3JvAhRYZGQqyKKR +VQlbP547w/PSU3rFTKCBkjCBj6SBjDCBiTEWMBQGA1UEAwwNd3d3LmludGVsLmNv +bTEbMBkGA1UECwwSVHJ1c3RlZFN1cHBseUNoYWluMRowGAYDVQQKDBFJbnRlbCBD +b3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExEzARBgNVBAgMCkNhbGlm +b3JuaWExCzAJBgNVBAYTAlVTMAcGBSsOAwIdAgEBMCIYDzIwMTYwODExMTgxOTM2 +WhgPMjAxNzA4MTExODE5MzZaME4wTAYIKwYBBQUHAgIxQDA+MBkMFUNyZWRlbnRp +YWwgVHlwZSBMYWJlbDAADCFUQ1BBIFRydXN0ZWQgUGxhdGZvcm0gRW5kb3JzZW1l +bnQwgfQwXwYDVR0RBFgwVjEQMA4GBWeBBQIEDAVJbnRlbDESMBAGBWeBBQIFDAdT +MjYwMEtQMRUwEwYFZ4EFAgYMCkgxMzg4OC0zNTAxFzAVBgVngQUCFwwMRjAwRjAw +RjAwRjAwMHAGA1UdCQRpMGcwGQYFZ4EFAhExEDAOMAkCAQECAQICAQEMATEwSgYF +Z4EFAhMxQTA/AgEBMBgWCkNDIFZlcnNpb24KAQcKAQIBAQAKAQEKAQIBAf8WGlVS +TCB0byBpc285MDAwIGNlcnRpZmljYXRlMB8GA1UdIwQYMBaAFLWs0BQDIqbT/Q7Z +dOWPEHF2opvqMAcGBSsOAwIdA4IBAQAWMj17Bk+dNYR6IHUyp/vTAh8gvgUw2Nnb +fZzbnA8nC6gLeCQYBD3F5we4YVUh9+rVv0dBwiZu9a46K3v2+kZYp7AtxyNs8f/R +ANyIUWsKOxyptqTuwEzC5UybRrRg0qVEY9hPGfZ0cas8vlhrO8TdlSuCHEYfLsgt +fYIgn6MiSG5GrGdIhWRcdNdQfeXNPjIzyXfP+1MD0CFvaDvRSphHP99mXUUlQija +9oBG5+JVahnP/LLx5q7wZZMYQtMNa+yGo2ictu/mteVgRR9KJb8RwYVMP9rflSQC +8/VrySFZUJMzGY2bFqv8WOWG3nOjaZvMV30P0c00eevObmzxrCKD +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/fakeRootCA.cer b/HIRS_AttestationCA/src/test/resources/certificates/fakeRootCA.cer new file mode 100644 index 00000000..7fca7bac --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/fakeRootCA.cer @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5zCCAdGgAwIBAgIBATALBgkqhkiG9w0BAQswFzEVMBMGA1UEAwwMRmFrZSBS +b290IENBMB4XDTE3MDEyNDE1MjU0MVoXDTQ3MDEyNDE1MjU0MVowFzEVMBMGA1UE +AwwMRmFrZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +geIXUAtrlc+FY8FC/bAGC6Vg1lbok+kILT/ZmG/4vdigZ2hzFR3dVjmgWd4hp3uP +dY7E/JUEouBq24qDpPUWrHIxSCqGp9Rn+whGq6Yy7d1d0FGyskIJJ2aFr1QC+/jA +4CptLbQGhqmyALrmXFai3scUmNciuTbEb3Ap9829IdsD4F9hT557zRSocaelVCUw +6sNLU78fJfG7K3dKmKemvtprqlDlfM3nya5P6IzkRKiPpXN6Q1sL7FDkKQ3HuyBM +WqPU+AWhqhCR9hRenuTpwTxEPVPA8FRV78wkV3VLzXCG7lHPZ8xCDKAZzdbwymjU +wfm9Wr5KperE83suIcIHxQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUWOwxOhaZ+UwcjE4sZBJAKyWPAXcwCwYJKoZI +hvcNAQELA4IBAQA2qgdehg53y1ehnq9KKdV5JllGgPon1GigMrMJ8VMGo+zs7h2q +CYlqCyuCI5hYWzZTRzwX6OAfZkIVEgY0O2lYJgTzsC+kz4EFArzq5eLqw2/hsn8c +KveCz+6mIL9AoyAMx9NZB1IytkDWIOtIElxOoAojluEDp3L1gzr9PVHJkI9KMeVV +eaH6Hg+Wg6I0jS1546oJnheEmcrwYaLJ0pHZR9NGpkICxDNMpNTLW9yy8e/kK+iB +xzT6vc3p791ktO1UD5kfK0QW8oRyMX0eHdRlDK2so+VWA5pEka+ZPc9dPB5JSudm +HBfbguS1HVpYAfJslzj31UpSnxr7ZA4OWiLf +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/fakeSGIIntermediateCA.cer b/HIRS_AttestationCA/src/test/resources/certificates/fakeSGIIntermediateCA.cer new file mode 100644 index 00000000..959cb8e7 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/fakeSGIIntermediateCA.cer @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFjCCAgCgAwIBAgIBAzALBgkqhkiG9w0BAQswFzEVMBMGA1UEAwwMRmFrZSBS +b290IENBMB4XDTE3MDEyNDE1MjU0MVoXDTI3MDEyNDE1MjU0MVowJTEjMCEGA1UE +AwwaRmFrZSBTR0kgSW50ZXJtZWRpYXRlIENBIDEwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC7tS739kM5cCJBVXGJtTgiV30AKtnDXeF5uw40DYfiXf1H +H5QAHNdiLqiZpsYJPiTnS7drsdvlzT1zjkfu11cI0jdUjMqDfSP+2MfAvrcjpdSN +R2YlcIJSNTeJyydvkxl6l0keXKdaoUkrMoJ+O0BWbSy7jXbicmndh4aoscq0Qp6s +99n4bPwrKqV/GkuTRjaUqGoEx/h9gM05kUcO5kw9xwO21ogY1H+j3NNstmTAjko+ +PNEhVEp5Ax6XpqTZOqbFpiWQdA7oXJsXar0tXi0DWBWcVz0EXqoOSxhH4cpnBmSZ +ioioIOCzcxitdcWIQS+phm/B+vhK4+YUKHCF2ds1AgMBAAGjYzBhMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQynzPkAJcEtxU2u0uy +YG2QqJ+U/zAfBgNVHSMEGDAWgBRY7DE6Fpn5TByMTixkEkArJY8BdzALBgkqhkiG +9w0BAQsDggEBAGs9uq0DKACdcgoNyJcHzyb11EhMe8+l/D+j8JjsRp3w6rXpw60U +ptZVMh7/SpRte7NjUBJ7wk76IIhntu6rcf/ik4ptyOgSUxDzGDffQzPRHRmXmjj0 +eir+cVQP34O7gByj/n92S9GP4/0RYGt7X7PGGiNArSroeS83fUQMVHhN8PbFzcrk +y9NHNR/In90Le/tPsFwGdTYzirgnjmcaVZFgCQfKuU3xr9vjANc2i5+QzzApjZ1i +K3o3z1eLOz6x25C03J8MF6GRiSV9AjrP8P0vQc25zpsjKH/rvdwmLIC6IjprF3Wk +nqakIzC7ABXdKhS8pOLkbmcoPlyt1rP9RgA= +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/fakeSGIIntermediateCA.pem b/HIRS_AttestationCA/src/test/resources/certificates/fakeSGIIntermediateCA.pem new file mode 100644 index 00000000..e6d11bea --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/fakeSGIIntermediateCA.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFjCCAgCgAwIBAgIBAzALBgkqhkiG9w0BAQswFzEVMBMGA1UEAwwMRmFrZSBS +b290IENBMB4XDTE3MDIwNDE2MjAyN1oXDTI3MDIwNDE2MjAyN1owJTEjMCEGA1UE +AwwaRmFrZSBTR0kgSW50ZXJtZWRpYXRlIENBIDEwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCZyYplXrOvY6ydbaGz2aQCZB/ua+8zV2xqC2FD642BUeJm +rHWWe4tP7O2xY9m0o2RQoRsKvP8ugYO4++wLsswvQjox67oeJowWKWks29hlpaA2 +cC+VMJqbMdIr18BwHxadYViv1fVMw3KDkGYAOWc1D2FuGeloscx32g+g3HAUKx1W +VdbCjTUaRFtubJKdF7bmXrf/WuOCDceUclG7309Vm8xJJlRunhgp87jhXX+GSEjb +fp8V2Msw7pQN/oh4n8rvmMX3vlVvr9cdvoKz+PmRvXal+9wm4isNt8xQRnDI8NQh +L6SRJD2WpA2CaN5MZsnOXHwc9MBazRwC3sw1ayb3AgMBAAGjYzBhMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBTmzRQ+smIRebtqGq3J +pTUXiaK11zAfBgNVHSMEGDAWgBRY7DE6Fpn5TByMTixkEkArJY8BdzALBgkqhkiG +9w0BAQsDggEBAH8IFAMl2VeQ1nnZm/U6EFMMHBWzd0MIn4fps+K2+JE+vJT2lmUd +s5cbvoj8ikC8czPrux+t53AGnRwpfQhuPa5UdLdtT8e1GX4O9oHeGcDZVrmfZasQ +rlJ46AmI1NO7Wi6dVb2YxKJKLPdxNpWuE8YXLnwkZYdQiNDBbVRlHIQk0PjPJkXJ +qTter5DWb1Pdca0b8JBI29jDdoI9kJ0eMM8YILdo4a5B0QKwN2OBWNvlBR8O5IB6 +UOPAOpdzJhzbEYLpxkxiZU1HhHPBn1YVr4G6WnN78FgPBvQXEsg78pAJca5qeZYy +MyTRDBTBp/IjiybJetKti5mOzZHtSHdARqE= +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/fakeSGI_J2_F00F00F0.pem b/HIRS_AttestationCA/src/test/resources/certificates/fakeSGI_J2_F00F00F0.pem new file mode 100644 index 00000000..d6b68826 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/fakeSGI_J2_F00F00F0.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkTCCAn8CAQEwc6BxMFmkVzBVMQswCQYDVQQGEwJDSDEeMBwGA1UECgwVU1RN +aWNyb2VsZWN0cm9uaWNzIE5WMSYwJAYDVQQDDB1TVE0gVFBNIEVLIEludGVybWVk +aWF0ZSBDQSAwMgIUWGRkKsiikVUJWz+eO8Pz0lN6xUyggZAwgY2kgYowgYcxFDAS +BgNVBAMMC3d3dy5zZ2kuY29tMRswGQYDVQQLDBJUcnVzdGVkIFN5c3RlbSBPRU0x +GDAWBgNVBAoMD1NHSSBGZWRlcmFsIExMQzEXMBUGA1UEBwwOQ2hpcHBld2EgRmFs +bHMxEjAQBgNVBAgMCVdpc2NvbnNpbjELMAkGA1UEBhMCVVMwBwYFKw4DAh0CBQCg +7/8RMCIYDzE5NzAwMTAxMDAwMDAwWhgPMjAyMTEyMzExMTU5NTlaMFAwTgYIKwYB +BQUHAgIxQgxAW1tDcmVkZW50aWFsIFR5cGUgTGFiZWwsIFtdXSwgVENQQSBUcnVz +dGVkIFBsYXRmb3JtIEVuZG9yc2VtZW50XTCB6zBWBgNVHREETzBNpEswSTEOMAwG +BWeBBQIEDANTR0kxEzARBgVngQUCBQwISnVwaXRlcjIxDTALBgVngQUCBgwCSjIx +EzARBgVngQUCFwwIRjAwRjAwRjAwcAYDVR0JBGkwZzBKBgVngQUCEzFBMD8CAQEw +GBYKQ0MgVmVyc2lvbgoBAQoBAgEBAAoBAQoBAgEB/xYaVVJMIHRvIGlzbzkwMDAg +Y2VydGlmaWNhdGUwGQYFZ4EFAhExEDAOMAkCAQECAQICAQEMATEwHwYDVR0jBBgw +FoAU5s0UPrJiEXm7ahqtyaU1F4mitdcwBwYFKw4DAh0DggEBAGW9m5fw1JtwaYQh +ASmBg6oRGBTjz0eCb9WX858ncq6eo+OjJKv0wM4Ris/T0qjGK9VMb+H6BYOQa8y3 +gDFS/tiFGpgJTnwxYwxUPOmc36lZXP85XpdLJWF8LV09Eko0eFw8Lf1nyp0N8enY +W5Tj5YCuu/W4prC8OF9nrqfkDQ0f1gYEwxd+lJCXQuDfnQ2DcrQiM+Wm8pjpRKXh +FpbkdCTRLMJHgWF2l75rR5wejJ6Ww/HEEn4p+V160TsKKezV2M7mv5G2B4Kcx3MD +KkoBytPA+4G7cRu5dl9wcaDfB7gvCZzaH+GhuwrjBpJne9s3AihQwUP6+ardJA9W +p5E3as8= +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/fakeSelfSigned.cer b/HIRS_AttestationCA/src/test/resources/certificates/fakeSelfSigned.cer new file mode 100644 index 00000000..862beb52 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/fakeSelfSigned.cer @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgIJAO6HRjma9a4oMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV +BAYTAlVTMQswCQYDVQQIDAJNRDEVMBMGA1UECgwMVGVzdCBDb21wYW55MRIwEAYD +VQQDDAlUZXN0IE5hbWUwIBcNMTcwMzAzMTkyNDI1WhgPMjI5MDEyMTcxOTI0MjVa +MEUxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNRDEVMBMGA1UECgwMVGVzdCBDb21w +YW55MRIwEAYDVQQDDAlUZXN0IE5hbWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDAYXs6PlEDkqHMZPifar+SScjG245NoXxu+oeiaRTvoOBMgmit9pj/ +ZWen2T2h/78EdmcHNr8KZaVkiAkA2vb0l5Lm6F73UoygS1nUsFPHIZ8pTRtWk5xG +A2GF5vmcWYtLMxM5VFVfXfm0VNZeTbbx5TxmdDjzVHnldsHtQNp7uRkAGMhuukQL +IkQ0+sJPwvYfieN9TgiHLqyV34ZmTPaIc15iALqXx8k7p6tKSkYMvXZjQBfe1rEJ +91QaQ9e+7t/a55RL/bwGXmp8p8ZlM6H1pXHzZGlHakMgYcs3m/amoYd4f5OG+U6t +Y6fFDBacZADwgMV/QN5F0FkhVwbrNa01AgMBAAGjUDBOMB0GA1UdDgQWBBQtJ6lZ +nJfJugfQvoStHdpvyXTldjAfBgNVHSMEGDAWgBQtJ6lZnJfJugfQvoStHdpvyXTl +djAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBgayv1fPLFgPyfpJtW +ey5atj3BDVD4o2zw1EWhrgepoUhamCEkyJ+1kSeWiBbYYlGpRjCd7/x51uAENwqf +rhYwwesMf/PAPFcATHBNwv0tHaslrnPgzUQd0RktO5fWKQnRcKfjp/b37YI3h1m0 +iGkeA6JptvTA+9MTAdfniHXyOE5RhSDjsbpMRNmEcpNf07EGiOqz/fGC5dDbQzRM +Put56ZEz5KedrvhJtRHSHV6jkZQp24cBsq8sotlqBeTE938K7QglBxAF21mqcagP +MShJFsKqMygNNzFioBZXIteiZPrcufVLD2SGsh45DA6mKUs0M9sseHvFsTY2qq4G +snlO +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/fakestmtpmekint02.pem b/HIRS_AttestationCA/src/test/resources/certificates/fakestmtpmekint02.pem new file mode 100644 index 00000000..eefe3b6f --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/fakestmtpmekint02.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjzCCAnmgAwIBAgIBBTALBgkqhkiG9w0BAQswFzEVMBMGA1UEAwwMRmFrZSBS +b290IENBMB4XDTExMDEyMTAwMDAwMFoXDTI5MTIzMTAwMDAwMFowVTELMAkGA1UE +BhMCQ0gxHjAcBgNVBAoTFVNUTWljcm9lbGVjdHJvbmljcyBOVjEmMCQGA1UEAxMd +U1RNIFRQTSBFSyBJbnRlcm1lZGlhdGUgQ0EgMDIwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCTt4oZ/7h4Fdx65T2ab/PtfsYPXHC396VVyaE+Z/Dxx4sT +emUQZn/zYPOfzg2c8Z6LQuuFg/BhzC8kNAp2tzCRfjBiWeUeSZLiUQeArYEz8HE1 +WSLArrqdGg1pz82Kh8L32og9hQ9GmsQp0yiI1lPTs7Uw9iOtcVtiyhGOFXXvltwu +1mYEuU6apG4Sc8tjSY+qEjAypJXyN1/I1X+254DHAkd19zXCKN+PSA7da9Rn8Afq +Fq4aIGVZzBSSgKEmD/GkKyw1Ze0kDgIE189iAw+m6NY4Gv/Cm+9nQ4fA9qq5Kloe +x8HWrN46qm2/boqujtnSSWPOhY3341z6N4xpRY07AgMBAAGjgaswgagwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAgQwRQYDVR0gAQH/BDswOTA3BgRVHSAA +MC8wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cuc3QuY29tL1RQTS9yZXBvc2l0b3J5 +LzAdBgNVHQ4EFgQUVx+Aa0fM55v6NZR87Yi40QBa4J4wHwYDVR0jBBgwFoAUWOwx +OhaZ+UwcjE4sZBJAKyWPAXcwCwYJKoZIhvcNAQELA4IBAQB8IaDIWicxm7m2qyDv +v4L253D3qRcx+sdM2GM0IpvK3u9z3BQraAhF6PPLlgFGP6slZdDY6ryrP8PEkvsH +tHoapB1MWe+eMrxw7dXQLnpzm/P++8AWMtY8roziiO7x3AYTbRb9lB2HjOWc2aGZ +1xW+su+aTnr9U4uYO1+HrDDKYgkypIcousRwUMW6c6szAZY2UtWS2e4346V3LVLz +sv22n4rqWWRzJ2tl+jIqLepChqOdgscDL+aO2iowmzTSWV/WLJRaTs0AsOYJkdlG +8wWRzygRbfGdIL7A/hKK42o0b7v3R/NI0nemwAzVN/QOYjTbkOCIUBg/6mT8CkYx +pmiq +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/gstpmroot.pem b/HIRS_AttestationCA/src/test/resources/certificates/gstpmroot.pem new file mode 100644 index 00000000..fc684ab8 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/gstpmroot.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID1zCCAr+gAwIBAgILBAAAAAABIBkJGa4wDQYJKoZIhvcNAQELBQAwgYcxOzA5 +BgNVBAsTMkdsb2JhbFNpZ24gVHJ1c3RlZCBDb21wdXRpbmcgQ2VydGlmaWNhdGUg +QXV0aG9yaXR5MRMwEQYDVQQKEwpHbG9iYWxTaWduMTMwMQYDVQQDEypHbG9iYWxT +aWduIFRydXN0ZWQgUGxhdGZvcm0gTW9kdWxlIFJvb3QgQ0EwHhcNMDkwMzE4MTAw +MDAwWhcNNDkwMzE4MTAwMDAwWjCBhzE7MDkGA1UECxMyR2xvYmFsU2lnbiBUcnVz +dGVkIENvbXB1dGluZyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxEzARBgNVBAoTCkds +b2JhbFNpZ24xMzAxBgNVBAMTKkdsb2JhbFNpZ24gVHJ1c3RlZCBQbGF0Zm9ybSBN +b2R1bGUgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPi3 +Gi0wHyTT7dq24caFAp31gXFDvALRGJrMiP+TunIYPacYD8eBVSNEiVoCUcVfYxzl +/DPTxmRyGXgQM8CVh9THrxDTW7N2PSAoZ7fvlmjTiBL/IQ7m1F+9wGI/FuaMTphz +w6lBda7HFlIYKTbM/vz24axCHLzJ8Xir2L889D9MMIerBRqouVsDGauH+TIOdw4o +IGKhorqfsDro57JHwViMWlbB1Ogad7PBX5X/e9GDNdZTdo4c0bZnKO+dEtzEgKCh +JmQ53Mxa9y4xPMGRRnjLsyxuM99vkkYXy7rnxctSo7GtGIJJVabNuXZ0peaY9ku0 +CUgKAsQndLkTHz8bIh0CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wHQYDVR0OBBYEFB4jY/CFtfYlTu0awFC+ZXzH1BV6MA0GCSqGSIb3 +DQEBCwUAA4IBAQCVb7lI4d49u7EtCX03/rUCCiaZ64NMxxqRmcSVdUx6yRrbl8NN +FNr6ym2kTvwe1+JkTCiDxKzJsOR/jcPczAFiYpFbZQYLA6RK0bzbL9RGcaw5LLhY +o/flqsu3N2/HNesWbekoxLosP6NLGEOnpj1B+R3y7HCQq/08U5l3Ete6TRKTAavc +0mty+uCFtLXf+tirl7xSaIGD0LwcYNdzLEB9g4je6FQSWL0QOXb+zR755QYupZAw +G1PnOgYWfqWowKcQQexFPrKGlzh0ncITV/nBEi++fnnZ7TFiwaKwe+WussrROV1S +DDF29dmoMcbSFDL+DgSMabVT6Qr6Ze1rbmSh +-----END CERTIFICATE----- \ No newline at end of file diff --git a/HIRS_AttestationCA/src/test/resources/certificates/nuc-1/tpmcert.pem b/HIRS_AttestationCA/src/test/resources/certificates/nuc-1/tpmcert.pem new file mode 100755 index 00000000..e0fd403d --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/nuc-1/tpmcert.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEXjCCA0agAwIBAgIUS5gujeW5kYvYdMJZlIUT6s3F0cwwDQYJKoZIhvcNAQEF +BQAwVTELMAkGA1UEBhMCQ0gxHjAcBgNVBAoTFVNUTWljcm9lbGVjdHJvbmljcyBO +VjEmMCQGA1UEAxMdU1RNIFRQTSBFSyBJbnRlcm1lZGlhdGUgQ0EgMDIwHhcNMTQw +MjIyMDAwMDAwWhcNMjQwMjIyMDAwMDAwWjAAMIIBNzAiBgkqhkiG9w0BAQcwFaIT +MBEGCSqGSIb3DQEBCQQEVENQQQOCAQ8AMIIBCgKCAQEAsdTxu5pRjEOgA0tCNYgn +NmAqLzIxBTBft4pMBGdEk922dvBLvQySN13YnvVF6FnYCc0Y+5hSAZiRCcXpr/M3 +6wx5YkePCPss06KQMujy3X9jwxTU0cDbKTjKCmFpQqCqiGIk2f7mss8yIABlwT3R +cBBbcDpGn2wYi5s9UhUfCOQ6D7qEPKJEi5IQC7/oyu5zT5FMUANdsebxrYpALcKK +8/mp5Rwj+xmaAg/+OC9jIeFGLYYu/hQr/1BPYSVicfuIFdc/0VzyJO5KMRozvV3I +2dbzQwqUD4xUxPR+f7VC+3p641Mb7WobIZH7wJm2k0M8HWeErytA66WtAoueU89O +iQIDAQABo4IBZDCCAWAwHwYDVR0jBBgwFoAUVx+Aa0fM55v6NZR87Yi40QBa4J4w +QgYDVR0gBDswOTA3BgRVHSAAMC8wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cuc3Qu +Y29tL1RQTS9yZXBvc2l0b3J5LzBVBgNVHREBAf8ESzBJpEcwRTEWMBQGBWeBBQIB +DAtpZDo1MzU0NEQyMDEXMBUGBWeBBQICDAxTVDMzWlAyNFBWU1AxEjAQBgVngQUC +AwwHaWQ6MEQwQzB/BgNVHQkEeDB2MBYGBWeBBQIQMQ0wCwwDMS4yAgECAgF0MCAG +BWeBBQISMRcwFQIBAAEB/6ADCgEBoQMKAQCiAwoBADA6BgNVBTQxMzAkMCIGCSqG +SIb3DQEBBzAVohMwEQYJKoZIhvcNAQEJBARUQ1BBMAswCQYFKw4DAhoFADAMBgNV +HRMBAf8EAjAAMBMGA1UdJQEB/wQJMAcGBWeBBQgBMA0GCSqGSIb3DQEBBQUAA4IB +AQAb50G/d9D18ahy6RScXObaazgrNZHcF0otH9W1uJzXgSQPjFFYbHAh2+EGI8uD +90Hj9XgZYmcGv0pUHcFw7msNamr3c/Or8+pLPnu5OZtr4jCEZ7/Z75v0Z825Ov8R +N+JIxB9RT0Yd3KAPQsp4d45NHWOPBQPgBi/pW/eJqPO2MJD0uraRqAlNrUD3ppc7 +xxsmOoOhyUFcs14KyrgIWNazx+4EElAKU3PthU70cszFAQM2hw/EYBfRwQ5rVZd7 +V2x9hMC4POgACE6gVIDV/mHoZe6AfGQKveblJEX9gOccI28vnT14d0CwhN/SvgZF +JigA9V7w26ecFRWXpm79utMU +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/nuc-2/tpmcert.pem b/HIRS_AttestationCA/src/test/resources/certificates/nuc-2/tpmcert.pem new file mode 100755 index 00000000..eba757bd --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/certificates/nuc-2/tpmcert.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEXjCCA0agAwIBAgIUBwCBhWf/NXkWkNLUBJRd9WsObccwDQYJKoZIhvcNAQEF +BQAwVTELMAkGA1UEBhMCQ0gxHjAcBgNVBAoTFVNUTWljcm9lbGVjdHJvbmljcyBO +VjEmMCQGA1UEAxMdU1RNIFRQTSBFSyBJbnRlcm1lZGlhdGUgQ0EgMDIwHhcNMTQw +MjIzMDAwMDAwWhcNMjQwMjIzMDAwMDAwWjAAMIIBNzAiBgkqhkiG9w0BAQcwFaIT +MBEGCSqGSIb3DQEBCQQEVENQQQOCAQ8AMIIBCgKCAQEAvcrvqYUTomoUC5zk5Jhd +myVzoEe94eXX1YFHyElCCpLM4/86ZbADKTHeGwygR4AWClb0Jmmloj+aIRUY3pZD +2GVxDnmD9CBS+60doM1cN0+D01hhg7J/dnaigAbFxPZauSyV9XfTqq1MQlxWpUEf +J4IALc+MhVd0kqSzzqSDxoneu83w1Ssvmah73wqWpansqQRYr1D7ABbkvouO56iu +4z6UditUSbrk3FrZBs+e73tzy9OAzQBg617kU+BKhHCRuRIPYk3tPXHq53Y7Jwvf +CkiEVWAU+MEMZJc/RRIOnWdSdDMxHZVnaxywrC8KUKZ1G3id/GVJfeivPxZVRBdh +sQIDAQABo4IBZDCCAWAwHwYDVR0jBBgwFoAUVx+Aa0fM55v6NZR87Yi40QBa4J4w +QgYDVR0gBDswOTA3BgRVHSAAMC8wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cuc3Qu +Y29tL1RQTS9yZXBvc2l0b3J5LzBVBgNVHREBAf8ESzBJpEcwRTEWMBQGBWeBBQIB +DAtpZDo1MzU0NEQyMDEXMBUGBWeBBQICDAxTVDMzWlAyNFBWU1AxEjAQBgVngQUC +AwwHaWQ6MEQwQzB/BgNVHQkEeDB2MBYGBWeBBQIQMQ0wCwwDMS4yAgECAgF0MCAG +BWeBBQISMRcwFQIBAAEB/6ADCgEBoQMKAQCiAwoBADA6BgNVBTQxMzAkMCIGCSqG +SIb3DQEBBzAVohMwEQYJKoZIhvcNAQEJBARUQ1BBMAswCQYFKw4DAhoFADAMBgNV +HRMBAf8EAjAAMBMGA1UdJQEB/wQJMAcGBWeBBQgBMA0GCSqGSIb3DQEBBQUAA4IB +AQAAbZng7i2L22p05GpbURYk6o7bYH3LZ+nusEGvi0tRkpqr9Qc8vMp8fgYQMaZV +8QiDa5JfYD3vzOjQBRvUdqz8UrzemsuErk4w3yzsBh2lIY54jcXWmJFVk4HVp2wV +xL5EysIII9Fkt2gfcoPSGyIDX4p83Vou5nhNOQPowahMuS6BUfcBKzMM7pK40GUj +N+cijK61zPkvAQArEkAnVNuTxvLS41WW3x1kTtkLUPuTh7SynNAYwoVfl19uNPOs +UTxDrFA7But7Vo0xoj+zSBQqzk0Gp3Pldw6mOUc3uI1UBmVtQGRy7cgsbLJ3bu/6 +fLuuAG5/ywVpo4MiG+PkFYXh +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/certificates/stMicroCaCerts/gstpmroot.crt b/HIRS_AttestationCA/src/test/resources/certificates/stMicroCaCerts/gstpmroot.crt new file mode 100644 index 0000000000000000000000000000000000000000..f8ff7e0d30c9257c1d06740809d18ddade9de376 GIT binary patch literal 987 zcmXqLV!m$B#I%0_GZP~d6E_P35HKo8a!Rf<;AP{~YV&CO&dbQi&B|cV*luWTV9CZD z%EB#dGys7pab6Q-?jUk$6QdGxFfy_-FgG#sGZ-{6axpbAGBW(wE~RTAuX6eA zt!)pFwKC29+F0nkhv}lktTP?|C+{kfuw5>}f4nhN*`+gzDe!1~vdq&z#+Q$!6iHSH z7$2D0e&zUjfy>dG%WM@i(zm~#mT|d5=)WT0vn%m?4H)+cjuTe`;kxk7i2G%Q%CmSTD5Ow@NhLz{yW z-6~FR*2y!zpFhb>{PeEpM^6VW-ndqx$uo4>*_~x2OP|g7=Dmf}gNx~iddW^OjE0)SBa0M5~ZP8JJjsq0GoIHGika!+W;7H|lcMn*ZC%#HBX#b+gZLsfja> zOfB`PIw^H~`e9#@Tfa`_F7f*#cl}X{k4E#6H77SbsqZ~}=L};~(!}UgHg4u6UKjV= z*1zIbxW-avN5taqPgkAZZk~VK^tD*-ON}GDbnF*^@93Cd_}zOY9o;d-%-Lv3@%y%!-u5qkwJ%l@5} z`}vejZ|MXB>EP#9Y+`jwR~%R_;P}SXZd2QIi;}sAgu{Ox6w=>US9$ZTVbZ}x8>*kK n+jQ!pWo!_SVcFN4D-4fa5;6M6$I_FzHTWghuhh5Mc_|A4U=f2t literal 0 HcmV?d00001 diff --git a/HIRS_AttestationCA/src/test/resources/certificates/stMicroCaCerts/stmtpmekint02.crt b/HIRS_AttestationCA/src/test/resources/certificates/stMicroCaCerts/stmtpmekint02.crt new file mode 100644 index 0000000000000000000000000000000000000000..3b258a9b4f971475f6c1fb6c64030d92022811e5 GIT binary patch literal 976 zcmXqLVm@Qg#I$7rGZP~d6N>`_1FHcq8>d#AN85K^Mn-N{1_LicZUas>=1>+kVJ2q} zLpcK(5Qj@xG&saJGr1@~H77N>q$ocxGr3s7FU(NdKoTU+EGz_+R|pC4RdDrI2+Ged zQE+xNkQ3)MG&C?YGBf~#C~;mROG6`L7}p?_G`rLcR3LWABH87cSCU$ko0^iDSdt2~ zQ^CN4UG0ay-|Db!<#(HPMDwyn$F<^syx};Ld+B%6LmKz{J^1cs zUrGPK{z`0}ltOCc8Ieg13)T2PF45L8O?|7v$Ha2|d=fMNvKQAZr2Ze8{XX5f{lK?X zJGG+Zjvu_X=APB6-2Hi7>-uh9@=QM0+WY-+%rEnvOxIp(CT2zk#>I{63>sG($O1!D zmXAe@MI>ClA=~}T^Vz>lr_{Xd*m02|>cKn%d62X+i-dt#gGm0fqdDx`bGo@2CpE{M zc9i?pcTwHI6{J9ck?}u^wSlF9IU5U*$6%mupv%Ug&Bn;e%Fe_nrkGJuQedU8UtV6W zS6rf(oS&-?Oep$AsRjAPnI-u}mHGyJAY=GJ#;`C06Q+R>h%XG{a~QAzDJDh+7Q z_D=)FEXRwXOmA zAB%eUd*)8{Z{x5q`ugFtoBQsXb*%L#HZPs@@_?!$Lncq;>GrfRh9=H;lRxe}Z05oD S%bxw8<0J`wp4sf2nM(o6S!^Nz literal 0 HcmV?d00001 diff --git a/HIRS_AttestationCA/src/test/resources/certificates/stMicroCaCerts/stmtpmekroot.crt b/HIRS_AttestationCA/src/test/resources/certificates/stMicroCaCerts/stmtpmekroot.crt new file mode 100644 index 0000000000000000000000000000000000000000..1fad0434fb4c53d9b48df7251394207bbb27ba64 GIT binary patch literal 1040 zcmXqLV&O4pV*0XxnTe5!iJOH12pE+P=6tR*;AP{~YV&CO&dbQi&B|cV*luWTV9CZD z%EB#ddrbHleMc_CrrHpWvdwzC{Y2n)L zv$bzB#CP5eKkLX^a`s-HvBPDroei44feIYoqQYDwt9Tz=oqSR{%YU|>P1&~72U9td zCAC7fh^bjD{cLt|Uxf2R?#EWMzZ+NHdw;pKEv{+%rKxAXn8mwYFIMP&uf64?*P%0o zmnSmjiDoaTyQLXqT4pUT94xxl=fmsd<6XWVr`tS_IrPWM%>KX7ybjel8@Tc$)H)dd zUEXMtbSs|OMD{h;-f$*nMh3>kjav*FHyZE(gHe{Bk?}tZ3o{cFi-8b`FAU;y7_b2; zCPqdBS&$eXix`VY{(EDt2?Bm-&L_ z#!?D0ZadQs#@W8+K6dK*+?xV1y0c!q*YLB*`m1qlc6gk;S*)t`+pp@8*OW67{8m)n zNqumY@mtai1^%+%fm_px7tYMA{cT?J^=bKq%-;<))uor*m`tztpV7~?=2$J$&G#wl z@ zdk|OpATB?FA_(xSTKN^gFKy$SfL}tSLb5_SU8Wd>7FvlBFkF13V3{`7>t~q|i@O+4 z6&nhKe10a1TZ)Nn$P`slvGgewE?co>jLSY2cU9O)H4r+W#6KzaM!)$BO4FPc-0o(p zy>1Uz9r3e1oVMUVlBldfx!`&$-wynSHvTiCV1K5{A+iLInfG5K1i7>1H`M zP6yl(cVAK|Sh|hnm;g?PBH>WP&G|ztp$BbG!g;QUn~jFu5r*Y(XLUFnsK@Clx1Ysr z(P(vVKDM&rqPZ@s(?w)}s;8K=+S*#RU-YZ?go2Q!NPfMkr0G!_f~3kNsLDF;a>;k4 z8ry@i+j;x5wkOBFwmpN~%vVVuj0Aw5B)~*bvqb?#f{r2xASobcLmaJ#9EIG+%h7aV z5Trvgil8VW5t<~ENhA_PC^hk$MI?hVaZN%YqenJ`NCTmDf^Om@3&|#Q2Z?YAPU46Z zK_n1IjwzHv1UaHah&XaU5bSM@BPPg~$q*q1rb+-dX4=>nF~gJsfDG=}#gg76DU*>h zk-U^t>*G>NOD#d3fl(%tiq=Y}I~c8Ieb@lI)<9TvgqE@vKptID5KFQY&|00zXyT=m znutpYlYWViP)V<4nj<7MAoLQyQsc*HrtZ6smJE4RnejUF?2&3dodK$<;z zvq#6vNJ4bnQ(RjPWGAppN3fT5*H460Olq;aFc}xAWvS9B^~qP$U@i`o!td^uEJ_H51_k&S|tJ z%4pJ3My?l2CP&V=ALeq{i=IqR)w;5#n$H zwKOg#t?>xSN5z|XsR#x9o_Z(e=9r+Mpbl4hLEY~gg~8Lwk`By7V&XMe_ClCBsr2(`kcWSLi6QCP>{Qmt!fV2Ess@ z^0Yt@V_fBoGB~~&*TIf{Tb{a+O4_HHQJ(!Zb70ce=={D(i*pZFjHj%3Qj3V{UyH{VsR7>{y0> zAsuMeeY5d!^=jlwN6x*#!_?5pXDcUmzP7#b>XE~f%OCw1Se5RhH{3pdt9fGThizYN zI_0=+?KpJi#*KNcgLggsq2utx1-r4yzr6pXsNkXMYU39~uA_Y3j2$z!NN!Y)8Kqm( zweyclPZpi*_B9@ON=o_S9_E;Q-m zsRQrs$E==~E%vOM`j77ZdVa{-t>pI;7XLhdCK5Z|@LS2QW8-T)w~l6PT5H#yXy1O4 zTjD%(abNzLmQf1|jmQ5g_AgcxRqB`TeOhy~qujOe_=BMLPv^ddStFLU5R=wjxw!Ma kCe`LGWy75pW^EmlpinRz9tIeN+YxrWjPk|1$z z9-)w;(&CcTl;F~Wf}Bd{jKs`5Ln#9ZkR%t6peIO!f^&XRL4HwUNoIbYA)FR?K>|c zBP%Nd$YV+p{6+?bW(I~vMn;APMg|5^U;%R^0Ruk+A2tqcHlP-ECMH7%13Lpr9#Q9_ z)Rfe`lFY;$g^YB6ZM zY!DB0ldK?1gh3cMKv~lpS(#XPSiwFu6fzKC1BC;(Z&$&zW14h&p{p|dy56MndA_t%$m1gG`CtqwkC?^C#<^TlMbt_cU?`FSU2_tv!s z%Os|I-cBiNxvS^QoxgdTzD5fB%h`2@E^#CT_4xU2KAu>8Sn<9bUwrR3#?z|R_om1> zpXTbjwDY~()OH>Fby0;=A7)T5ma)9>YlJR7IXax{PaRCmLdgD>s|#?Ak*Nasb+uh!!!y<+^9 mpC`V^C`se4Up4Pyz~X!+flXc8emML&Cfj({KmWhrrWF9DWdr;G literal 0 HcmV?d00001 diff --git a/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/Intel_pc2.cer b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/Intel_pc2.cer new file mode 100755 index 0000000000000000000000000000000000000000..46e5f938fe2cba94bba4b9737e11ecb27fefb664 GIT binary patch literal 772 zcmXqLVrDRCVtm2G$Y@}&K+iyIiHL!ap@0D&8*?ZNGY@-kh;L?cQ9hFhJ40h@`hU|( zu?d&1uuO^ln$4Gcd_m&`gT~$^ja>$f?S|Y2oFF}H!c3vTFb)R~le42C&_s|7I}dko zVqQt2f^$w{QKF%gfdojDi$~BiuOu}`!8yOEAipTFBr`wHP|-jhB*)Do5mJ)FR?K>|cBP%Nd zlSs(D*QdmkKF7y;#YS$wU(315{pEWDB?*2b14DBIV56AREpeKrnlHlVxMnV1Zec@#sO0~{4Xib{)1Qd1NH zauQ3@@{4j6T=P=$i;7cofnGKU02wC;GS1DwWr>r412}5HcC+xXf&G8de@I z7gu8oL(`B*Zx4hp8xNOo6=$B_S`x@Iy;nft zp5U$2zqNn)Y65pSNo+7atlP9^!9g#N!}A^{SVda?a2MP-l~e1q@$bdak`0m!I?8ID zeiy!9tY66z@O<^X_ZMay)UepMB{I4z+fL!4n6KaGs|{-oX19fGd+xkx;RVZ5<#t|1 z)mIY^OZLdjkpCOj{=V7y^?_!KzN3>F)56L(M0lKuU%l~JjKN2V`r#mNh z-zYg0Ii*$j)!CyL&n#%1V9?mRq_NAOvE7i{fD@#LO_(V(7{=k?VRCjf1eyqvVdvov zPRuJwRB+BoEJ`$#GLQg?a`6ay=9Q%8C^+XA733EsmSpDV87dmcgXFk*BtnW3^NI@+ zi&FDS6oN|&3UVqHoHG(L^9;odL_kWId3ejq%k?rrM(8Ey=Nj;`acZ@Bw0-AgWMpM! zU=rccE|&aTlKd#`P|u1P0R_+6%Dp@dlqC3#3=GW;jE#(qjEqf;jiW#U#s-E)#z16h zX=)i|U}zx8#+u&9$|ML14g*eL2r)4-0ZAT4L!jMYDPfRDnHU+G7?~Lv84Ma18u$Vo zC9A;5_@Bkuz|p{-jSJ+MAHIyNOe{bX_1QSI*?{h1XJRr?=1~lB4scWmDJm^4Nlj4* z$Vn_o%P-1RaLr4}FDg#W1$x;a0A!pX$T&9xmnBXH4&bN(+s(qm3Jy3!Q3GL!Ygl=> zTwIMU3{68Ky*&`ZY&={ZMrM|l7P=+|Mrh%~+yr#DxQTx8YHfyg_In(st{$K6!(hhX z=e7FTDzyw{7F+HaL5rVm+q2E+o0%0;EO*Z0ra&DQ4H2UYn+vWrHn@bX{mgCh%By>6 zm>{oZ`2}g#%}RAnJl{R4HX6TkK9{%PWcNe9M8^BGe-$P!Ntx(sa9T^B`?X!p_MHM6 zVhY(lx5ek&+;*IM>eth&FR4~=*E^=9@+Vq#zk0H2+TH!vxE7!NbAdhh<##TQ60 t^_Z-f9Fud;CU!1|`{nbm>uv?!HT=E3jQ!lhDJM5ue|__{?E6cW768LZ@-YAa literal 0 HcmV?d00001 diff --git a/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/Intel_pc4.pem b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/Intel_pc4.pem new file mode 100644 index 0000000000000000000000000000000000000000..9ea77f12c977877d6ba8cafe4de96fd59203dea6 GIT binary patch literal 914 zcmXqLV(v3&V*1X+$Y@}&K+iyIiHL!ap@0D&8*?ZNGY@-kh;L?cQ9hFhJ40h@`hU|( zu?d&1uuO^ln$4Gcd_m&`gT~$^ja>$f?S|Y2oFF}H!c3vTFb)R~le42C&_s|7I}dko zVqQt2f^$w{QKF%gfdojDi$~BiuOu}`!8yOEAipTFBr`wHP|-jhB*)Do5mJ)FR?K>|cBP%Nd zlL*t~1Ha8xg86M;O4^)U{;$AM^6WMPB?*2b14DBI6C*<)X=-E{1rjheFf=j-B2!CK z%P0dw14%a4^hQ=DK~QiQZ~{Y!iIE9N@-P|#?FLH;gFMQ_$k4>d%*e=K(8Rdjpm8nG zS+WX@jQ?307a26pH)x#0#szZG4_`)BCKh0L8R)ZdXtM!b$IirLpvfH zT#}li5Rj8tl9peTtKgcKl3!GunhW%}K@?mAqnKYtNl8JmmA-xnL`QLIQCVhkYB3@R z^po>}p^;aj9}?`WpPX7$QVe2&7yR(hSN$&J_eXH`gG0Nv1(M zIP$^1W8q;1M~$JVfiT3stUO#UuErLIrXi8u9tdGJ9xe|fGfPVgT@wQ%LsbK1Ha1|u zu`;spNV=OvdYc#-8yGlSnCrN^hC~8`+`z!lJq#SfvdSzH24W2&8kaY`_^&emTMzT2 z?xQ?O>vVsmHyI?ue9g$n5^fM`5DeoRFtxdp6AEC@1ZSq_W#*-Or&j6#g9I(PFgG?b zlrP@gb0hY_@=rc5vaFjA7w&j9#iGsT?QNFh8?&xXR=<&2Ly{>@N6|ay049I k{ln^v$xGV5{t48Miz(gH|1E!NiAckd+ZJla{2X5a0Fet4>i_@% literal 0 HcmV?d00001 diff --git a/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/Intel_pc5.pem b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/Intel_pc5.pem new file mode 100644 index 0000000000000000000000000000000000000000..478f6229a0f8f675626f79c3207cdb988b715274 GIT binary patch literal 914 zcmbV~T}V@57{~XX?Hrw+l^<)&NSkS7A8yat+;n!6E>jUpI9o9x^EBr?G|yRQ$A$*c z8EGGCU-Y3AXtAJ+OfLdIx(I?{koJK$Ru@4aSV33O%mO=SVnUa}%gg&d&-*;*|NlJ) zqUy^K#S$1o0K;Z5#PpCwWxxhP?a`>o6xvW@j6KsryQgI1{_vM~?6c1a~MR|O?^R5B@KI?Zq*V{!!rHiUoPJ)Y#!PBh?<@_YJqLWjaHyap~OnbyWIwj zO27t`)g~{y)9!2p3UUZMAmLc1f&;WNAq-*iP9jSFb~2T%7{!n(iqr_HAc{so8j)q? znh;viNcTY+0_iT1rYKsfM>wXDd4YvU-A%~qQZNh($b7e}p~B=AI>MsA#ncdF#8zHt zH&t;hyb$)c%f_McZviqKY!k&$xZGk9S1ZDP;S}rhhu0BUe7sD96D@AqW%2n1F|3@F zLjxaVeVw$(h{?X@P)jRB6uFs-+;%t-V~3#e z&3c$1(`u{^r?afM1gz9{C?E(K9F7Pwr`qAIE3w)DT$PSJ)m3h_KlR4R)dD5-vycTD@D zCo#bk&AgfYd13j$ow?gnx4N(^O?mT!>+IOZyXZSt% i{zJO;6Dc@skb literal 0 HcmV?d00001 diff --git a/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/TPM_INTC_Platform_Cert_RSA.txt b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/TPM_INTC_Platform_Cert_RSA.txt new file mode 100644 index 0000000000000000000000000000000000000000..f99f228125ff7c86484d5f25c79ac388041fe47a GIT binary patch literal 2144 zcmbVNX>b!|7|w349$RQ>DTPv4L7*Jnyt_Fz4QH;lp(K~JcG45ADa3L~h9Acw~=Drl7%h5;RQ1VNyH3JmrKNCy~nH*JBT{BWGvAK&+W@AW<3 z`#cNrq)LcuzD5xQ#7)iO8z8RQB{qS$oJ@sejj}?e$wVDa@&yVTl0PHk+`qSO%XsEK`);vu`!RspK>bqT5-3Z zs|)%ALS2;Qs&Ts&2Z};fOSH9Do5kHA?%XAA2XX6DO;vciH%S<3w~|@VM=qhoQoVjo z@Zz`b>mNT>m~*Z5fu zcg13LUH!O9i;L#^oL(Q94OyL+Nn5yZA;HRdi2xslG)?lTrjn+6X$X?4R-jqPh!x7* zpRZ19-8(sL^UB}vmM5p5haow=DIg1hA`K)>8T2qqHs~oZ>PZqPJy5eCu3QQOHR@_n zjb@OUkO9dkf})5*dL)%fp->>wRTHQE$z;$bmPsgNciQ@qX&^nFJ#J%OjY45a*4RZQ)-*S8tVzO$x48P2O)t%6JQ1dL6Qa&l=Mi` z^8vABPlcUkjSi3PnLbh`8)*||Dlh;E3wmVAN;H&TKJw{lz_ik6FgR;$%=YoPjlql9 zP>89*Z4LNT!b!LZG5_f>CNbTtv4GYCRN(fq3Vaey5hf@uSq#P=CAD6EI9A71W9e=K zO!M#=kfLGs` zZUmrAHkzi*V5DfUi7FFV3!$z@s^`F$>lA93D8~pA4jjh>WK!TRiYzRc;%>|^2P_b@ zn1U9XvII<)fKfy#a@Rl@kQk>71ncRsa{{DdN~_z4sf1`916deWUl!$YC+D9hVcBKv zkEJ`Je8gMBMjoH2gZ@yAX&IkAwnh*lF^f(oQ!5hk3qd{_4hO4cg6X>U5haNo_evbk z!&TxA5VwK&jwVIsc842Lqbd;B!YobFXbqxPYf&WI(_KlrbxdHYVobE24KT4M+Mtu_ z2$H(!d|taQAT=M8SMs8a53zv;uizJ$u;f5Qs)9f~&W*wl4ENcKabIUy|xPzGQ-{5fzrw&7cxzLe@I%YAj_kP15>8 znLuPN^zZW5V7(pFCD{anq*xMbNl5$^@`kE%AiFVZ_pR11UuhmQzoXvmsmv}hr8j>x z3Fdd-MbfT0Q27KmK%4$AZgab2*=~I-%7ldFGXkuPBckH7yE_gyoL_V8BD=BgFU-Mh zx=XjB7js+Qf2jR?_ASpKI`6$JFN%Ar!e=+l&OJ3`kmcB-`yKVAqtoMt`;)$1ygjq7 zwl$~yI(O%_9pG~RB=Q$5`B z)6w?REvk1@Kiv3WTIC{P`nj9K6(>)7l142XaOCX%2U|xiZ@Y14Z`FafEb9k`;m=L& zu8Wmhg%QJt|F*9q|FzmNH;I?`+&*L-zwyY~{;o`7Xzb)4v4_Q%50a`k@6?Xn(Qm|e z7ut@sHk8l3x_@Tg`U^|>q)6%Al`TcX94>3$8SYcM4c@gQ+dF1XKk?PR!#8HPoL-$W zY4fTK^^kkla+~_)pBr^__v+HC=5vnE?E~846ITx%w&a`dXB|+i+%V5LTl~P=YuzX4 zoFBHgO+LBh$6HH(9en1|Kc1Z2WB0b!kIg!GnU83vtXZ+oReon(tTkn6&BBHSGX{3_ fE;k2-2OY=T*UVgeccNuk@12!R*M&nX59a&}jckdr literal 0 HcmV?d00001 diff --git a/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/ca.pub b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/ca.pub new file mode 100644 index 00000000..bcf8b63d --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/ca.pub @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyGJpmVcVj6P+gZ0U8fvx +CixxPjNwW+dKXT9FaeIMpYvwfoQKlBdQNy9VH1CeV5ovUMTy/Z2dIKI+GZ2F2lUD +XLhMsN7N2P8pqQ7y3wkG8A2eP2WmOYtYj/Jg1h4TDtzxLcEaHuY9e9T7GQsVINPj +aXaUNpncns4+wgP9PE/9vasvSuj4JOAdaZ0AYE1nA+s3wfT9fbF92lUta0zRgDw5 +o1D0uzciA3VnHePA0bSMq5onNLzdFXQwqvwHFE7hYGUbmmoun7t+g25YrYuk0wV+ +AB0dIfiLNk5ySMNn4YkLkKQmbbeeG3nb6BiVFzVHdYsIVmre++8wTC0WWJq8SsIL +KQIDAQAB +-----END PUBLIC KEY----- diff --git a/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/intel_chain/root/intermediate1.crt b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/intel_chain/root/intermediate1.crt new file mode 100644 index 00000000..f6d31da7 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/intel_chain/root/intermediate1.crt @@ -0,0 +1,46 @@ +-----BEGIN CERTIFICATE----- +MIIIHTCCBAWgAwIBAgICEAEwDQYJKoZIhvcNAQEFBQAwSjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNvbWUtU3RhdGUxDjAMBgNVBAoMBUludGVsMRYwFAYDVQQDDA1J +bnRlbCBSb290IENBMB4XDTE4MDcxMTE4MTAzMVoXDTIwMDcxMDE4MTAzMVowUjEe +MBwGA1UEAwwVSW50ZWwgSW50ZXJtZWRpYXRlIENBMRMwEQYDVQQIDApTb21lLVN0 +YXRlMQswCQYDVQQGEwJVUzEOMAwGA1UECgwFSW50ZWwwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDHnFB0pCfGKgaJrmURmL/fjPHWwrycYH43XGypdxga +lLxnZAu1ydvrSYTwSsGYtXu4+o74qy4ntazTP/V04thrwzmKecDpwJzgO+Vs3OOT +X238Z6RAEhzx0lnigAWd5eFFLDV7GHjN36eHdEz7RKggoxkaSPu1XFbcamseyeSl +GpddMf7dBwyqrPFXf63gCacuQChVWA1sVFbR+IACgGQH/cVYUpoWF8JWAgvWAuIS +3Bb7nSF5SUl1aV7QMQLrJQxMr18vqX/0ajnad6jOeOHo+NFdnr/7kebuPpoVLpHo +27ny2Cp3kC9g7cQU0ijYHYmdhXayVPxJ/+T8QNWFp+2lAgMBAAGjggIDMIIB/zAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSs0nif51+eoH1QlFkIe3uHcdfQhDAf +BgNVHSMEGDAWgBTz4tyrFw4DWPlY4DRglUoP6ZXsXTALBgNVHQ8EBAMCAaYwEwYD +VR0lBAwwCgYIKwYBBQUHAwEwbAYDVR0fBGUwYzAyoDCgLoYsaHR0cDovL3BraS5z +cGFya2xpbmdjYS5jb20vU3BhcmtsaW5nUm9vdC5jcmwwLaAroCmGJ2h0dHA6Ly9w +a2kuYmFja3VwLmNvbS9TcGFya2xpbmdSb290LmNybDBDBgNVHREEPDA6ghtTcGFy +a2xpbmcgSW50ZXJtaWRpYXRlIENBIDGCG1NwYXJrbGluZyBDQSBJbnRlcm1pZGlh +dGUgMTCB1gYIKwYBBQUHAQEEgckwgcYwOAYIKwYBBQUHMAKGLGh0dHA6Ly9wa2ku +c3BhcmtsaW5nY2EuY29tL1NwYXJrbGluZ1Jvb3QuY3J0MDMGCCsGAQUFBzAChido +dHRwOi8vcGtpLmJhY2t1cC5jb20vU3BhcmtsaW5nUm9vdC5jcnQwLAYIKwYBBQUH +MAGGIGh0dHA6Ly9wa2kuc3BhcmtsaW5nY2EuY29tL29jc3AvMCcGCCsGAQUFBzAB +hhtodHRwOi8vcGtpLmJhY2t1cC5jb20vb2NzcC8wDQYJKoZIhvcNAQEFBQADggQB +AE+ju9M/AvwP5IGOyK92rlPI3VhZ3xDZMHYorDfPCqydf9w+xDsnpbXop4Gdi//0 +SlOJCEbFa2oCt04JOJE986HuTfBLVZT9CtoMxOUEN2jWRq5ZZgHNqNPKqp59cxTm +KgSjDv3ch/OnbmVNxxgH79obCnBI0lBy/tlC7GoeOyL9KtDZ6Kp13Fyyn9dtFxu9 +i2nYlf2mq6RPQBW9ZXUVYDLSllASSy9FVoK0BfsWa3eHwwBgNJGH4ZpkbIuaXN+U +io4t1SnGHN3QLvDpNprK3mItkbC0BDAzbP/xDHFrjPSWS04HUyn8JHHHgUcnET+p +1SU+PJr82NbdPVl6/n+xMVMaaFdDlDyZx6D1jQNKOJDCemdujbW4ndpcUoFp/mds +IWulrYTu2IJQvuqOvXGSfg4AE5FqbAZDt0xvWOl7vcMkZuL5Sl4kWbzoV63KjMT5 +o+YeMyF0ExIuCWhYJ4eI0f3S1e4hS/1h6wXXR5aCsnL7jMoFjD+zn8rfjaohof5Q +pV9xwDRrY3ySrpQ9cm8dJCeTeFzW4kqZgIiUlMMIh1VQExGNsnp9DHHGwqzqpyRC +vCj3UkaGgvth8elNATBdv8ONoHklpjQFSTnRAU/MSBE+kUrTdw/bETLU11Azn/bt +BTxikRssprLKxeExoa3jm+Vavkkfu+dY+NSHJVVIUXu8PkKjNNJbPeNx9qwAYgGA +AqgGGchZrBdvNhkoUKTJmDRIF5jM7DG34yC83x5T6lzp1OciGaXf3jRXghKBojI1 +jxAvZG6FBHdzwPAOjsY21yU2TbXrxQ8j6Z9fOnQ9vmmpMM2oqthaCxGRAzDrDdFT +O2FRDt7d72rgj6oRIl3H39C0l4z5yXO6kd0uAz35aGxpKGIJTJY7nLtRx0Ajmhdf +/40si5xEgpFyzXA/ZIYy9TPJxZkOTlJI4G32Wvdhj2hZSwQOCWoI2cmQbnzkC0w4 +ad1H/+YBiB2wqypuwpREwsjvo5GPVNhYg8S6dC7yfFMlKyNtAoPs4KdaatI4rgy3 +av/zt9jxBC67LVIRuOM00wTLJzmfwcbMuOgr3p42x7MoZ6YRKd7yaAvTvmhPXaZV +dXiceCxofbbcTDputNakrrFRZ9Gijs85lDX+5/Ify4ageHfLxp17sDdYXN+13Jxd +ApI1vlEKlhJlyUCl+wYIVmh1h6X8gM5JIqWIuI5fUMzrD1Qw67vEhRTbDumL9JU6 +IealkhroBbgZb04WTJ+5hqrYRcS38Z3Vxx3IbRnXx/nRpN6UkyP2JpgOj+oaea0k +yHloDdHH9JDQpHxrQ64aEtHJUEEdBIAvKD9pJCnQxuXx+SMvNr+bwdX0WnkkfuxG +sXy5JPb2g9iuxtRJpy+N6AM= +-----END CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/intel_chain/root/intermediate1.key b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/intel_chain/root/intermediate1.key new file mode 100644 index 00000000..bd63bba7 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/intel_chain/root/intermediate1.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEAx5xQdKQnxioGia5lEZi/34zx1sK8nGB+N1xsqXcYGpS8Z2QL +tcnb60mE8ErBmLV7uPqO+KsuJ7Ws0z/1dOLYa8M5innA6cCc4DvlbNzjk19t/Gek +QBIc8dJZ4oAFneXhRSw1exh4zd+nh3RM+0SoIKMZGkj7tVxW3GprHsnkpRqXXTH+ +3QcMqqzxV3+t4AmnLkAoVVgNbFRW0fiAAoBkB/3FWFKaFhfCVgIL1gLiEtwW+50h +eUlJdWle0DEC6yUMTK9fL6l/9Go52neoznjh6PjRXZ6/+5Hm7j6aFS6R6Nu58tgq +d5AvYO3EFNIo2B2JnYV2slT8Sf/k/EDVhaftpQIDAQABAoIBAQC9dxOvAzl1kOJP +wSbRwwksqd3LGWBplfV3mtTRLefFIzSJdp7e2FFUTZ5PbsW/q1NaSwl14xWWP41h +nq3fWopODyoI1HRV66t7855a7HdepRACqmVvI0IyDpWetiGetFpUjBffVWUlFIsx +uSRww8RJ5kWne2rfxFv2L1SqDrxmMOAPrUpMegjxDqEYYZ/wTrTUrEiGlmU5UrBp +4WID6siJJFrAaHYeN7qo1OcOoYVk40q0g3kZarLyV5nlfQG+iC1oSHK5VJEJQbFm +xV8MiUFE2LJUM9DiDPm6OyTJMu+gFC/MsC+jxcXqleBEVBhpFfLcfTTN1PQEzJZk +yQ22j4XBAoGBAOaHsKhuefnka5Bm4Z6cXK8kIAIOsiF0aYNOrEa/q6Hb/bNSK2SC +jVxK9pomHmCvrt8GFq1hkA9y/GNR4+26WSb1XZcOUr9IGRFZ0oBbgYhm9zr+gcL+ +QrtPyPPs8dMlyJz/QhO3/sgc1eCrQoAgahzrW+XqTt79nVjHGtFJpyatAoGBAN2q +GV4Hnci59eCvSYl9pFajQwBtc8GdQ7gT2svtVdjhd6vgsK9OS9VUD6q6VcKOecH4 ++SAcancifYZwmfowAbNHrGfybTzI6m+nuK6X/JoFEGXZBql9Sg1CVnmixOTwrHGR +YrpTZOJ8kKusT5A8DKEbe3sF9gYledG6EZHDXlnZAoGBAIfiF4lQhWl88MJPQlJh +zGgYHR3ZV7pMih0x9G5HcH2Z1LMsjhNSuMxcC3vVWDaZl7QyPI+6YFYa6xYIIRfx +rbc/DgmKEdBaSRxnG6M5TOL//l6xwf8ULHWIk+TkF67kKJoSA/rni7Cc/pzNlgc8 +FBAz0xl0wUTDrUm1IuOWTIaJAoGBAIX3/TboUYN0aNdv+Xjgd8dpCuCiRhjZbIk/ +brhba8wVkNdPiFmbb5eyI3ni/lwE8i+6ww6WPf5c2RK80UL1asGo6tk0GrNnFtF+ +w865yxBnSR7VCQK811mmI0+GgYuArihBXzMPneSItoMbNEcPE+73Bi03UBcs5TBN +TbsUId0ZAoGBAKnk0lqK5yBNIjUwHWut4kVu1m3vhSk3TjEiWYAqwbsVK4f4ilDg +CHoUq089If5eOuf57MZvvtFpQFD4aRVq8O+3regCD3iTHUVHS6zFAJOY02RultPc +7hmNyEiZb1W65IIqo1inFqytpaeYGF0yE0Q2ThN+b3sNp+VAcLlJFy3o +-----END RSA PRIVATE KEY----- diff --git a/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/intel_chain/root/intermediate2.cer b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials/intel_chain/root/intermediate2.cer new file mode 100644 index 0000000000000000000000000000000000000000..4ed90e4aee0a61b0c3546fe4b013fb18170eca93 GIT binary patch literal 1645 zcmXqLV#_pWVhLQp%*4pVBvQR^5#ze7MJFO&l-|itQtp1GC~(YxmyJ`a&7r7bF&?=9MS}mlhP{R4O=UBxdF* z1m))gMKaU#GV{_6#SBD1>X~_X%gf94GC}6)CFkcF$cghBnj0Dzm>PgVlsK=k5fay+ zaSqI-RB^VMfeFOfx;UNfSzKHSbg_c7qk^ZmyIXvSYj6lo=QlAfLJnv~RtDxK#(oBa zCdMwNCdNjF1(WAp_UmrfkC62H^UPwJdhI#`RzZ)$efd>9llQqL$IOoS5c=Y%+J5`p zDl&1)HE&xNB8F7W04!~yp}vKSr_%_`QE10nPN@{|B3z=aG52Ra^tI# zcr25$&J)Kvtt&6@{^VxZ{r2viNk%($&hk8#`y_K{8IR~Lpv3~YRIQ~$489B22l?5gV4 zO~G?bY$xs%@$Jk%-D)+}TBHB5>vG5E?F$;db!hcZ)7Co-N{>8X9fB zR)pu#)-MMqUbal1`B#{4inPkg$K~t9@^`E459!=+C;Q{v*Fg+g%l4P=eSVdnk&}s; zk%4h>6QepXMwAV5**LV>7+G1_85vm;4dM-AVSEFow!n;%l7eC@ef^T6(&CcTl;YH) zvdrYvVnkZiPtFG>+q@F}kYH#1Hqc>{T1 zQj=9?kuVTz5ZRhvboOuBx#oHDw;eqD*)`>(XKn{)I$2>x#{VoF25dlziIKs;52Q(+ z#ofTwzw5*=2Q19O*Na#4-}AILm@kR2?*!lKPU7R2Xc5n~atVcYpTd8y6P zn(TIGW6O_sR|3p{F1lAF-}d3RO-!!ajZSOn zM18;HvF7;t`>z7cy|?$e#1`u(oSj$Ua$YQ{Byq#P_5W{_uaEi3vbr>@F(J$3U)WKj z`$xks_QtqvEjr8anMd)Vox`*mhklWhiyALUO^@9#F0uUX&UV&q*)~s}uA1>))^fXT z60ew8L&LMoQwnCapFV!b>Xr!$yA^*d;8b?Z-Z#50edyPnR93R9`4LNV=JetYDMw?$ z`2{lHHhO4?sqVY}uz!K1dWrPz;BM|tLE%X;EG6p%TBaqb+RNRmbo>72Ui7u%-nnO8 zXMg@>k;~2dFgp6hVby}9L>8};S{|OCBu$jBJ#>m$?CN*YGvs^m&#G5_;_+EGUb*!P zZ<7hK&Hq!E&^~Lrt(kJv{~7O=G!{!arhVJnS!R8-Wbw?&ZiQEtv3X z?uXHGgUF`tO=}&>`L)g!dUXCu_X;=Z-FRwk+xx43{$_6u`S_nLwk7!Pr+*vX`xsrk z_q0t#zx!l&lfQ1|)WyYmN7QyFKP|LXYDfrL@~hma?r`daEiA_BW~?45=ar}YeYaI< z-mcsw5nlmu_kB&(1co=680xf>g^(|o&|o=% z5GRCiXEelzhMUU9v>r}iqPR28C*piaVB;KV0n=c^`XC?Tl8F${Z~`7^N+hB!xU(_D za=0g%Y#QpvQ|+!?7IX!Iqz(!PFO$1^^=g8Z^Ah2B406?3Guo=!Zs#IMjw%B!L>_rw zQSwdS!qa=_<#w*W{@bFgyvs1DXbc6U4Jgt?(v-;vOJswQ0<)1MfieQM1X7BpVS-xK zAgWL;SpZtdLJ<^2GNeaRDl;-N5b3Jv(_%6UH0fm~3c5ktI5HQcr;~isUzXHt+P6T4 zOG=VL6bO<5DfEI`BUMl#8k9_-CnUr1?i4y3=D-7LwRDiL7%KKJ&|#ViCb?3GCt5K_ zu);@6?E@_IiU;0wg>L2^5+DE0_q9G+Cf( zRGQHbh-LX|oHT2$@Hzg`NA^53ZJ{iB6OgcKRHnjoL(>*bzkeDqjWikz&YD|w!8q<< z@JcosW$JN93%-DG5ne)^c7GU?o^IBxr;PwLxYJ*Q&&4Ui0`96O!91#@CJ>4xo45un z&ugMdyO}f@T@KJY{f^d5o7D_12UP){QDM2hxHOOnCd@`yrXI_y_W0a^-~t~Wu$uq^ z#@0MD0A+E|G;IYlMT1>bTEK3DrctT>1-=rO(8%x{BS<)K921sFfqN*@rl0R^)mp>l z5Gl7r%4w=RY$*?$MU*0YCcyagIB5}Vw8x%DAqP{~y+KSV@J$R9Vpy}EkK-;bv|Pe+ z$Xbl$Rq*jdppi|CoTwt9Xp(ttj&4??AS9CI27^qkL^LEs;(RO?X^;tK7}_VKXoeRg z*)f=GMyt(aw3>)UAqJJ{!Brs&ayFFftp6cZEF72QtifQSt+dHX8?D5eSQJvoArSXU z9G{3Q#aBUm8N^-cY?<5rUPOf|LEH#S)R|>!M5WT8h|V`$NxF4XVCs_$-^_-YS7T!;9+PAfOp;S)!q;z}{^*(RnJfC6y}nvql_jtH zow=}L_%4!m)j{n&+yHI+zqlj_2{Em$1k7iv2U;CRaYJCU9!9P$kgNKkG%2LiH$A$dpq#4{zZ!2 zna<{tPwwoGH&e8MYG3W%>UATnb^5GfA1GpKHm4DIJe6AgZikOvhHd3rY@-# zULCkrdTd44bp!qLPdzuMbiVn`%}bllw9g_-KLqTs_6*(rXV>}8*nso&+``t+o<-k2 zd-vpT1#g@xD>*dZdnJ3vjJu_GtW#a@BAYJ!(AQtbY&^~0zpwafV#dks1&g;_v0I*7cd(;T+*+i2_>UWl^*1|7B6Z@qL#0#B-uk?DwXS%_ zZGTr==}VdiTKd|vRx(>3eCAq5*UR5)Z=73abMfa6yjH!XZhhdrtFGQPi@CM8V~!gy z+-)19YvJ762OhMQRerW}(#3Js4~#mje#7_9p2unC;qR7zf&cP5)jNwl(z$C~_;{fB c)>l)Xo$#ZkYu6bf<{;J}?0rm5P761SM literal 0 HcmV?d00001 diff --git a/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/large_plat_cert.pem b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/large_plat_cert.pem new file mode 100644 index 00000000..183942c0 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/large_plat_cert.pem @@ -0,0 +1,43 @@ +-----BEGIN ATTRIBUTE CERTIFICATE----- +MIIHgDCCBmgCAQEwgZWggZIwgYmkgYYwgYMxCzAJBgNVBAYTAkRFMSEwHwYDVQQK +DBhJbmZpbmVvbiBUZWNobm9sb2dpZXMgQUcxGjAYBgNVBAsMEU9QVElHQShUTSkg +VFBNMi4wMTUwMwYDVQQDDCxJbmZpbmVvbiBPUFRJR0EoVE0pIFJTQSBNYW51ZmFj +dHVyaW5nIENBIDAyMgIEewdr5KBaMFikVjBUMQswCQYDVQQGEwJVUzEUMBIGA1UE +CgwLRXhhbXBsZS5vcmcxDTALBgNVBAsMBHRlc3QxIDAeBgNVBAMMF1BsYXRmb3Jt +IENlcnRpZmljYXRlIENBMA0GCSqGSIb3DQEBCwUAAhRgKWfqeST97mzBULkeg3d9 +H0J5mTAiGA8yMDE3MDgyMDE1NTM0NFoYDzIwMjAwODIwMTU1MzQ0WjCCA7QwHAYF +Z4EFAhExEzARMAkCAQICAQACASsEBAAAAAEwFAYFZ4EFAhcxCzAJAgEBAgEAAgEL +MIHHBgVngQUCEzGBvTCBugIBAKB0FgMzLjEKAQcKAQIBAQCAAQGBBSoDBAUGoi0W +K2h0dHBzOi8vd3d3LmludGVsLmNvbS9wcm90ZWN0aW9ucHJvZmlsZS5wZGaDBSoD +BAUHpCQWImh0dHBzOi8vd3d3LmludGVsLmNvbS9jY3RhcmdldC5wZGahDRYFMTQw +LTIKAQEBAQCCAQMBAQAWKmh0dHBzOi8vd3d3LmludGVsLmNvbS9pc29jZXJ0aWZp +Y2F0aW9uLnBkZjAsBgZngQUFAQMxIjAgFh5odHRwczovL3d3dy5pbnRlbC5jb20v +UENScy54bWwwggKEBgdngQUFAQcBMYICdzCCAnOgggIiMEQMEUludGVsIENvcnBv +cmF0aW9uDAlOVUM3aTVETkKADEJURE43MzIwMDBRTYEKSjU3NjI2LTQwMYIHKwYB +BAGCV4MB/zAxDBFJbnRlbCBDb3Jwb3JhdGlvbgwLT1VUIE9GIFNQRUOAAIEBMoIH +KwYBBAGCV4MB/zCBjgwUSW50ZWwoUikgQ29ycG9yYXRpb24MKEludGVsKFIpIENv +cmUoVE0pIGk1LTczMDBVIENQVSBAIDIuNjBHSHqAFlRvIEJlIEZpbGxlZCBCeSBP +LkUuTS6BKEludGVsKFIpIENvcmUoVE0pIGk1LTczMDBVIENQVSBAIDIuNjBHSHqC +BysGAQQBgleDAf8wQQwLSW50ZWwgQ29ycC4MBEJJT1OBIEROS0JMaTV2Ljg2QS4w +MDE5LjIwMTcuMDgwNC4xMTQ2ggcrBgEEAYJXgwH/MCgMB1NhbXN1bmcMEE00NzFB +NTE0M0VCMC1DUEKBCDk4NTBFQjJEgwH/MDYMCEtJTkdTVE9ODAxTQTQwMFMzNzEy +MEeAEDUwMDI2Qjc3NzgwNTI3MEKCBysGAQQBjBqDAf8wcQwRSW50ZWwgQ29ycG9y +YXRpb24MG0V0aGVybmV0IENvbm5lY3Rpb24gSTIxOS1MTYAROGM6MGY6NmY6NzI6 +YzY6YzWBAjIxggcrBgEEAYJXgwH/pBwwGgYFZ4EFEQEMEThjOjBmOjZmOjcyOmM2 +OmM1oRswDAwEdlBybwwEdHJ1ZTALDANBTVQMBHRydWWiLhYsaHR0cHM6Ly93d3cu +aW50ZWwuY29tL3BsYXRmb3JtcHJvcGVydGllcy54bWwwggFsMHwGA1UdIAR1MHMw +cQYKKoZIhvhNAQUCBDBjMDEGCCsGAQUFBwIBFiVodHRwczovL3d3dy5pbnRlbC5j +b20vcGxhdGNlcnRjcHMucGRmMC4GCCsGAQUFBwICMCIMIFRDRyBUcnVzdGVkIFBs +YXRmb3JtIEVuZG9yc2VtZW50MB8GA1UdIwQYMBaAFJmT1DnLMuKrlfc3o7d3KRzU +pDm2MDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cHM6Ly9leGFtcGxl +LmNvbS9vY3NwMIGUBgNVHREEgYwwgYmkgYYwgYMxHTAbBgZngQUFAQEMEUludGVs +IENvcnBvcmF0aW9uMRUwEwYGZ4EFBQECMAkGBysGAQQBglcxFjAUBgZngQUFAQQM +Ck5VQzdpNUROSEUxFjAUBgZngQUFAQUMCko3MTczOS00MDExGzAZBgZngQUFAQYM +D0RXMTYwMDQyMDMwMDExMDANBgkqhkiG9w0BAQsFAAOCAQEAgXjdUlD16jiwNEuc +MNTXKP9HrJfnihv5XXtnTdm3LrVhdaiyeKXgxI1/70FrNL7ZO37BhMnud4PIgbbU +320fxJBIcWO2rkwlPj7rR2S7fiaUTgO1NwCtW5QZ3TBJ0AU6XvFVSaEvi22JZjbJ +ZyOJuaAKlSyPPkRftAGDewJHxzfpaG9g0hZB4KdTYDYiSdU42L4izd/bY4nVyTia +SWjBWpxZpwZTLP2At4lEVkG7ifjlybGZkHUecjRogfvyzuJ3e05Y2/j4IzIqdmKv +20M/ogn0QP42rVSwYjgztHmkZfd6fbklltDDOdOV73q5NKc2l8vkx9GN2hItkWJ0 +3zSQeA== +-----END ATTRIBUTE CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/larger_attribute_cert_2187.pem b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/larger_attribute_cert_2187.pem new file mode 100644 index 00000000..48430fee --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/larger_attribute_cert_2187.pem @@ -0,0 +1,3 @@ +-----BEGIN ATTRIBUTE CERTIFICATE----- +MIIFJTCCBA0CAQEwV6BVMEukSTBHMQswCQYDVQQGEwJVUzELMAkGA1UECAwCU1QxEDAOBgNVBAcMB0VYQU1QTEUxDDAKBgNVBAoMA29yZzELMAkGA1UEAwwCY2ECBgFkKBN3iqBNMEukSTBHMQswCQYDVQQGEwJVUzELMAkGA1UECAwCU1QxEDAOBgNVBAcMB0VYQU1QTEUxDDAKBgNVBAoMA29yZzELMAkGA1UEAwwCY2EwDQYJKoZIhvcNAQELBQACDgGu/H+usYn7Cxf59c33MCIYDzIwMTgwNjI4MDQwMDAwWhgPMjAyODA2MzAwNDAwMDBaMIIB3zAqBgVngQUCEzEhMB+gDhYDMi4yCgEGCgEBgAECoQoWBTE0MC0yCgECggEAMBwGBWeBBQIRMRMwETAJAgEBAgEDAgEWBAQAAAABMIIBewYHZ4EFBQEHATGCAW4wggFqoIIBZDA7DBJPcmFjbGUgQ29ycG9yYXRpb24MBU90aGVygA1Ob3QgU3BlY2lmaWVkgQ1Ob3QgU3BlY2lmaWVkpAAwKgwST3JhY2xlIENvcnBvcmF0aW9uDApWaXJ0dWFsQm94gAEwgQMxLjKkADAkDAxpbm5vdGVrIEdtYkgMBEJJT1OAAIEKVmlydHVhbEJveKQAMFEMEUludGVsIENvcnBvcmF0aW9uDCM4MjU0MEVNIEdpZ2FiaXQgRXRoZXJuZXQgQ29udHJvbGxlcoARMDg6MDA6Mjc6NmQ6MmM6NmKBAjAypAAwVQwiQWR2YW5jZWQgTWljcm8gRGV2aWNlcywgSW5jLiBbQU1EXQwWNzljOTcwIFtQQ25ldDMyIExBTkNFXYARMDg6MDA6Mjc6ZjU6MjE6OWWBAjQwpAAwKQwEVkJPWAwISEFSRERJU0uAE1ZCYmU5ZWYzYjAtZGNiYTA0YjaBAKQAoQAwFAYFZ4EFAhcxCzAJAgEBAgEAAgEQMIIBODB0BgNVHSMEbTBrgBRGudxuHtihoLQVKHMF1KiHXd3fJaFLpEkwRzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNUMRAwDgYDVQQHDAdFWEFNUExFMQwwCgYDVQQKDANvcmcxCzAJBgNVBAMMAmNhggYBZCgRrgMwXwYDVR0gBFgwVjBUBgIqAzBOMBwGCCsGAQUFBwIBFhBodHRwOi8vbG9jYWxob3N0MC4GCCsGAQUFBwICMCIMIFRDRyBUcnVzdGVkIFBsYXRmb3JtIEVuZG9yc2VtZW50MF8GA1UdEQRYMFakVDBSMRYwFAYGZ4EFBQEEDApWaXJ0dWFsQm94MRgwFgYGZ4EFBQEBDAxpbm5vdGVrIEdtYkgxDzANBgZngQUFAQUMAzEuMjENMAsGBmeBBQUBBgwBMDANBgkqhkiG9w0BAQsFAAOCAQEAlH++UXf8MldFwLV3SHd+hmJyLsPxfY7at3tVo/qiwKTvUKOXJTZl/m/k1XysqCT1rqkKurIeBcYAYTRlVuAbeqvmn+8pjbiOh5eUn9MAvndZ1tDHCSBs85CyC6AHQpG2FnPAhMnrvCXcST/qxBUFPa+BayrORUjII7n0Ti3Y4dX8E2T5lI+xCEh1HM4V9DIoKLQhGUmNYd3jvl584cW3v5zBMVv3CxHHgBzVbqMHw0WXlgI6PELm1urseUfbHtK1JVU1s7C9H0YA9HvcQ/zxA8fcEuZAhRkzIsaVe5jAKWhpT3EL056IOhtI9vvOqiUQ0aoJJsBHUlRJNuscGdOolA== +-----END ATTRIBUTE CERTIFICATE----- \ No newline at end of file diff --git a/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/medium_attribute_cert_2187.pem b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/medium_attribute_cert_2187.pem new file mode 100644 index 00000000..c4b9ca99 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/medium_attribute_cert_2187.pem @@ -0,0 +1,3 @@ +-----BEGIN ATTRIBUTE CERTIFICATE----- +MIIEzjCCA7YCAQEwV6BVMEukSTBHMQswCQYDVQQGEwJVUzELMAkGA1UECAwCU1QxEDAOBgNVBAcMB0VYQU1QTEUxDDAKBgNVBAoMA29yZzELMAkGA1UEAwwCY2ECBgFkKBN3iqBNMEukSTBHMQswCQYDVQQGEwJVUzELMAkGA1UECAwCU1QxEDAOBgNVBAcMB0VYQU1QTEUxDDAKBgNVBAoMA29yZzELMAkGA1UEAwwCY2EwDQYJKoZIhvcNAQELBQACDgTQbuZ+aGZ8yTKkIlGcMCIYDzIwMTgwNjI4MDQwMDAwWhgPMjAyODA2MzAwNDAwMDBaMIIBiDAqBgVngQUCEzEhMB+gDhYDMi4yCgEGCgEBgAECoQoWBTE0MC0yCgECggEAMBwGBWeBBQIRMRMwETAJAgEBAgEDAgEWBAQAAAABMIIBJAYHZ4EFBQEHATGCARcwggEToIIBDTAhDBJPcmFjbGUgQ29ycG9yYXRpb24MBU90aGVygACBAKQAMCYMEk9yYWNsZSBDb3Jwb3JhdGlvbgwKVmlydHVhbEJveIAAgQCkADAkDAxpbm5vdGVrIEdtYkgMBEJJT1OAAIEKVmlydHVhbEJveKQAMD4MEUludGVsIENvcnBvcmF0aW9uDCM4MjU0MEVNIEdpZ2FiaXQgRXRoZXJuZXQgQ29udHJvbGxlcoAAgQCkADBCDCJBZHZhbmNlZCBNaWNybyBEZXZpY2VzLCBJbmMuIFtBTURdDBY3OWM5NzAgW1BDbmV0MzIgTEFOQ0VdgACBAKQAMBYMBFZCT1gMCEhBUkRESVNLgACBAKQAoQAwFAYFZ4EFAhcxCzAJAgEBAgEAAgEQMIIBODB0BgNVHSMEbTBrgBRGudxuHtihoLQVKHMF1KiHXd3fJaFLpEkwRzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNUMRAwDgYDVQQHDAdFWEFNUExFMQwwCgYDVQQKDANvcmcxCzAJBgNVBAMMAmNhggYBZCgRrgMwXwYDVR0gBFgwVjBUBgIqAzBOMBwGCCsGAQUFBwIBFhBodHRwOi8vbG9jYWxob3N0MC4GCCsGAQUFBwICMCIMIFRDRyBUcnVzdGVkIFBsYXRmb3JtIEVuZG9yc2VtZW50MF8GA1UdEQRYMFakVDBSMRYwFAYGZ4EFBQEEDApWaXJ0dWFsQm94MRgwFgYGZ4EFBQEBDAxpbm5vdGVrIEdtYkgxDzANBgZngQUFAQUMAzEuMjENMAsGBmeBBQUBBgwBMDANBgkqhkiG9w0BAQsFAAOCAQEAb/IhDAmWMU5xELnHQS/ZH0TjTxw5sBRJrs39/HW1xHLcYCjQa0n7tMCGqdaeXw2k/LX5GWy6SMXKgq6U6ZEYOAkn4CEkiKS8XgJuZlg+xPwYijefcrQOOWBA58mEcwN0Vhf2QgdcFBo0n19JZq9SrQ8JakUnYxzEByXD26dEZjUdGYiWamcoyOXT1wcV7oJhj9PnsYAZsGUxFv8YCChYBKE8qlgWvCuHbBpvaKmeguGbZiJZia0uBtoUfO2YFKYCOa2PNhKB3Vxt3nOoJCzOS3ACRcwFy7YoVUjUKClAzA9K7bdlSTkUBcYK6f7ncKjYCSjoBqQXjAx53OdKCPexvg== +-----END ATTRIBUTE CERTIFICATE----- \ No newline at end of file diff --git a/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/medium_plat_cert.pem b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/medium_plat_cert.pem new file mode 100644 index 00000000..3533de71 --- /dev/null +++ b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/medium_plat_cert.pem @@ -0,0 +1,37 @@ +-----BEGIN ATTRIBUTE CERTIFICATE----- +MIIGeDCCBWACAQEwgZWggZIwgYmkgYYwgYMxCzAJBgNVBAYTAkRFMSEwHwYDVQQK +DBhJbmZpbmVvbiBUZWNobm9sb2dpZXMgQUcxGjAYBgNVBAsMEU9QVElHQShUTSkg +VFBNMi4wMTUwMwYDVQQDDCxJbmZpbmVvbiBPUFRJR0EoVE0pIFJTQSBNYW51ZmFj +dHVyaW5nIENBIDAyMgIEewdr5KBaMFikVjBUMQswCQYDVQQGEwJVUzEUMBIGA1UE +CgwLRXhhbXBsZS5vcmcxDTALBgNVBAsMBHRlc3QxIDAeBgNVBAMMF1BsYXRmb3Jt +IENlcnRpZmljYXRlIENBMA0GCSqGSIb3DQEBCwUAAhRgKWfqeST97mzBULkeg3d9 +H0J5mTAiGA8yMDE3MDgyMDE1NTM0NFoYDzIwMjAwODIwMTU1MzQ0WjCCAqwwHAYF +Z4EFAhExEzARMAkCAQICAQACASsEBAAAAAEwFAYFZ4EFAhcxCzAJAgEBAgEAAgEL +MIHHBgVngQUCEzGBvTCBugIBAKB0FgMzLjEKAQcKAQIBAQCAAQGBBSoDBAUGoi0W +K2h0dHBzOi8vd3d3LmludGVsLmNvbS9wcm90ZWN0aW9ucHJvZmlsZS5wZGaDBSoD +BAUHpCQWImh0dHBzOi8vd3d3LmludGVsLmNvbS9jY3RhcmdldC5wZGahDRYFMTQw +LTIKAQEBAQCCAQMBAQAWKmh0dHBzOi8vd3d3LmludGVsLmNvbS9pc29jZXJ0aWZp +Y2F0aW9uLnBkZjAsBgZngQUFAQMxIjAgFh5odHRwczovL3d3dy5pbnRlbC5jb20v +UENScy54bWwwggF8BgdngQUFAQcBMYIBbzCCAWugggEaMEQMEUludGVsIENvcnBv +cmF0aW9uDAlOVUM3aTVETkKADEJURE43MzIwMDBRTYEKSjU3NjI2LTQwMYIHKwYB +BAGCV4MB/zCBjgwUSW50ZWwoUikgQ29ycG9yYXRpb24MKEludGVsKFIpIENvcmUo +VE0pIGk1LTczMDBVIENQVSBAIDIuNjBHSHqAFlRvIEJlIEZpbGxlZCBCeSBPLkUu +TS6BKEludGVsKFIpIENvcmUoVE0pIGk1LTczMDBVIENQVSBAIDIuNjBHSHqCBysG +AQQBgleDAf8wQQwLSW50ZWwgQ29ycC4MBEJJT1OBIEROS0JMaTV2Ljg2QS4wMDE5 +LjIwMTcuMDgwNC4xMTQ2ggcrBgEEAYJXgwH/oRswDAwEdlBybwwEdHJ1ZTALDANB +TVQMBHRydWWiLhYsaHR0cHM6Ly93d3cuaW50ZWwuY29tL3BsYXRmb3JtcHJvcGVy +dGllcy54bWwwggFsMHwGA1UdIAR1MHMwcQYKKoZIhvhNAQUCBDBjMDEGCCsGAQUF +BwIBFiVodHRwczovL3d3dy5pbnRlbC5jb20vcGxhdGNlcnRjcHMucGRmMC4GCCsG +AQUFBwICMCIMIFRDRyBUcnVzdGVkIFBsYXRmb3JtIEVuZG9yc2VtZW50MB8GA1Ud +IwQYMBaAFJmT1DnLMuKrlfc3o7d3KRzUpDm2MDQGCCsGAQUFBwEBBCgwJjAkBggr +BgEFBQcwAYYYaHR0cHM6Ly9leGFtcGxlLmNvbS9vY3NwMIGUBgNVHREEgYwwgYmk +gYYwgYMxHTAbBgZngQUFAQEMEUludGVsIENvcnBvcmF0aW9uMRUwEwYGZ4EFBQEC +MAkGBysGAQQBglcxFjAUBgZngQUFAQQMCk5VQzdpNUROSEUxFjAUBgZngQUFAQUM +Cko3MTczOS00MDExGzAZBgZngQUFAQYMD0RXMTYwMDQyMDMwMDExMDANBgkqhkiG +9w0BAQsFAAOCAQEAcWts9N210lLj4HlSIzYVX46oZQWz7jaGfkatoiUBOJwTloAV +1ZwyFEq9VCFGj2qgXv2ndMQGQWjSUrBakmkZQcLU3SCuQkP4F3K8sg2tL+xJOu1s +UvTDMs7nJM8TAhlHUi2+j/u7tjWUPOxjoLkv5AfkZIPT+QD1+jXCPZjgsm+soQQb +x/LrydPk+qjXiD/w+VRshLpBgc7ob3k9/r+FqdrqTeAy6XhrsgOrY0J/bvGHnK4V +nIGBrtCkb6KJN7HCaUvxV9zC0R9IuWAWmBleKtX/OEg79rDNUXfDwoNoFcsM3faq +GmrMH1qGfLP344wOLJIgfwF6W/qr5152w9wliw== +-----END ATTRIBUTE CERTIFICATE----- diff --git a/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/paccor_platform_cert.crt b/HIRS_AttestationCA/src/test/resources/validation/platform_credentials_2/paccor_platform_cert.crt new file mode 100644 index 0000000000000000000000000000000000000000..b6ad38c4dd9df89239f6e0f6365850f1dc01fe90 GIT binary patch literal 1102 zcmXqLV(~I)Vm4x8WHbn05NhDP#M8jtklTQhjX9KsO_(V(7{=k?VG0g06foce$*}XV zyGA(r2Kcxd@)&S|M7VgE^NZ49ikW$sk`tNO7*jNa%exj>8CWbaGcbWkLW~tL5Q6CA zPOV7HEyzjLOU}1vrPK7MB3IoLX%jZQpqr8M#>*K+aT>;5RZbv@kFP zLNJH|2^b*@7&I{k8*sC+rZ=)O2^%sQFc`={ID&@427(5hKx3E~nVA^HSXdYs7#M-d z`PkTjidh-i84a6&b~OH5(D>6pj)&JTzeFLpAT>ENEi*L*jccHYCV<9mW@IoBMHAy; z33YYzGzjOBb1KSDOaXdX!80#ePa!ccMWMJfsW>wwGqET$wU|fGFSR71q$o8vRl&*G z*VNp|NWncbJuxY>M8UNrBef_mwL~Gn*;B!_qM#_XxVVwYz@VA&zkv&npl4o5YL0?) zeo;YwQDRAEejblJT!(XhUS4W4NKiq;NK?Vn$k0;P$G4Hm*szIRn~jl$u_+vA%0dPM z5lDE6gW?PvTEL(e0EQE%K?*Q_WR+QB4Wb)F7VIfJaxrFWpp@r|C1LAtteL-kanM4t z;%sc-IA%eM6C^1{ z+)}J)QfMiY8JKJsdW;?Rs!s_$Q#wJvA;sTyO}zJt$>&Qv)|G^0EKRd$?Ra}UJ!$UB zMNdL9L*nL?9aL4izyGU5Irq#J5@l9FN!F25=O`q-P+HWhanJj==7%5iRKDK0DZYJ& z{_~fC#}*5!9X!%fB`zv_^DDy(nMV(&O+34cVRn7s7mY`^gd3-yU}_CLy6?rDm<6lP zRtCNAtz5+RNH+G<(TvAFCMu_oT>IqBZ+!pZ+k1jd5lg?%z419tc30w+TFy=PK29*& zdA0c^e~L))`ps*3c%Pms{LVaSmuuenfNg^MucTw8^)lyptT(?qm;FxQHO;X7HI+Nn cTPLg+n Date: Thu, 5 Oct 2023 20:05:21 +0000 Subject: [PATCH 16/26] addeded OS sepcific checks for mariadb --- 10 => .ci/docker/Dockerfile.ubuntu22ci | 0 package/scripts/aca/aca_check_setup.sh | 35 ++++++++++++++++++++----- package/scripts/aca/aca_remove_setup.sh | 4 +-- package/scripts/aca/aca_setup.sh | 8 +++--- package/scripts/db/db_create.sh | 16 ++++++++--- package/scripts/pki/pki_setup.sh | 8 +++--- test.sh | 5 ---- 7 files changed, 50 insertions(+), 26 deletions(-) rename 10 => .ci/docker/Dockerfile.ubuntu22ci (100%) delete mode 100644 test.sh diff --git a/10 b/.ci/docker/Dockerfile.ubuntu22ci similarity index 100% rename from 10 rename to .ci/docker/Dockerfile.ubuntu22ci diff --git a/package/scripts/aca/aca_check_setup.sh b/package/scripts/aca/aca_check_setup.sh index 3ca9c8e9..bf4ed0d5 100755 --- a/package/scripts/aca/aca_check_setup.sh +++ b/package/scripts/aca/aca_check_setup.sh @@ -37,7 +37,15 @@ DB_SRV_CONF="/etc/my.cnf.d/mariadb-server.cnf" DB_CLIENT_CONF="/etc/my.cnf.d/client.cnf" ALL_CHECKS_PASSED=true ALL_CERTS_PASSED=true + source $SCRIPT_DIR/../db/mysql_util.sh +source /etc/os-release + +# Setup distro specifc paths and variables +if [ $ID = "ubuntu" ]; then + DB_SRV_CONF="/etc/mysql/mariadb.conf.d/50-server.cnf" + DB_CLIENT_CONF="/etc/mysql/mariadb.conf.d/50-client.cnf" +fi # Check for Admin privileges if [ "$EUID" -ne 0 ]; then @@ -69,16 +77,24 @@ done echo "Checking HIRS ACA Setup on this device..." # Check if aca setup was performed # Check is RPM was installed via RPM package - rpm -q --quiet HIRS_AttestationCA + if [ $ID = "rhel" ]; then + echo "RHEL distro detected" + rpm -q --quiet HIRS_AttestationCA + elif [ $ID = 'ubuntu' ]; then + echo "Ubuntu distro detected" + dpkg -l "HIRS_AttestationCA" > /dev/null + else + echo "Unsupported OS Distro encountered" + fi if [ $? -eq 0 ]; then - echo "HIRS ACA was installed via rpm package on this device" + echo "HIRS ACA was installed via an OS package on this device" if [[ $(cat /etc/crontab | grep -c hirs/aca) > 0 ]]; then echo " HIRS ACA is set to start on boot via crontab file" else echo " HIRS ACA is NOT set to start on boot via crontab file" fi else - echo "HIRS ACA was NOT installed via rpm package on this device" + echo "HIRS ACA was NOT installed via an OS package on this device" fi # Check install setup pki files @@ -92,7 +108,6 @@ echo "Checking HIRS ACA Setup on this device..." source /etc/hirs/aca/aca.properties; - check_pwds () { PRESENT=true @@ -121,13 +136,13 @@ check_mysql_setup () { # make sure mysql is running and restart if its not... check_mysql # Check DB server/client TLS setup. - if [[ $(cat "$DB_SRV_CONF" | grep -c "ssl") < 1 ]]; then + if [[ $(cat "$DB_SRV_CONF" | grep -c "HIRS") < 1 ]]; then echo " Mysql server ($DB_SRV_CONF) is NOT configured for Server Side TLS" ALL_CHECKS_PASSED=false else echo " Mysql server ($DB_SRV_CONF) is configured for Server Side TLS" fi - if [[ $(cat "$DB_CLIENT_CONF" | grep -c "ssl") < 1 ]]; then + if [[ $(cat "$DB_CLIENT_CONF" | grep -c "HIRS") < 1 ]]; then echo " Mysql client ($DB_CLIENT_CONF)is NOT configured for command line use of TLS without provding key/cert ino the commandline" ALL_CHECKS_PASSED=false else @@ -240,12 +255,18 @@ check_db () { mysql -u hirs_db --password=$hirs_db_password -e "SHOW DATABASES;"; echo "Privileges for the hirs_db user:" mysql -u hirs_db --password=$hirs_db_password -e "SHOW GRANTS FOR 'hirs_db'@'localhost'" + echo "MYSQL Log:" + mysql -u root --password=$mysql_admin_password -e "SHOW GLOBAL VARIABLES LIKE 'log_error'" fi } # Check selinux status and files that require specific contexts check_selinux () { + if [ $ID = "ubuntu" ]; then + echo "Skipping selinux check on ubuntu" + return + fi SELINUXSTATUS=$(getenforce) DB_SRV_CONTEXT=$(ls -Z $DB_SRV_CONF) DB_CLIENT_CONTEXT=$(ls -Z $DB_CLIENT_CONF) @@ -283,4 +304,4 @@ if [ $ALL_CHECKS_PASSED = true ]; then echo "ACA setup checks passed!" else echo "ACA setup checks failed." -fi \ No newline at end of file +fi diff --git a/package/scripts/aca/aca_remove_setup.sh b/package/scripts/aca/aca_remove_setup.sh index 6cb473e5..01f38cfb 100755 --- a/package/scripts/aca/aca_remove_setup.sh +++ b/package/scripts/aca/aca_remove_setup.sh @@ -22,7 +22,7 @@ check_mysql_root # remove the hrs-db and hirs_db user pushd $SCRIPT_DIR/../db/ &>/dev/null -sh db_drop.sh $DB_ADMIN_PWD +./db_drop.sh $DB_ADMIN_PWD popd &>/dev/null # remove pki files and config files if not installed by rpm @@ -36,4 +36,4 @@ echo "Removing the ACA crontab" sed -i '/aca_bootRun.sh/d' /etc/crontab echo "Shutting down the aca..." ps axf | grep HIRS_AttestationCAPortal.war | grep -v grep | awk '{print "kill " $1}' | sh >/dev/null 2>&1 -echo "ACA setup removal complete." \ No newline at end of file +echo "ACA setup removal complete." diff --git a/package/scripts/aca/aca_setup.sh b/package/scripts/aca/aca_setup.sh index d3561c32..42f5d7ea 100755 --- a/package/scripts/aca/aca_setup.sh +++ b/package/scripts/aca/aca_setup.sh @@ -25,7 +25,7 @@ help () { echo " -u | --unattended Run unattended" echo " -h | --help Print this Help." echo " -sp | --skip-pki run the setup without pki setup." - echo " -sb | --skip-db run the setup without database setup." + echo " -sd | --skip-db run the setup without database setup." echo } @@ -97,7 +97,7 @@ if [ -z $HIRS_PKI_PWD ]; then fi if [ -z "${ARG_SKIP_PKI}" ]; then - sh ../pki/pki_setup.sh $LOG_FILE $PKI_PASS $ARG_UNATTEND + ../pki/pki_setup.sh $LOG_FILE $PKI_PASS $ARG_UNATTEND if [ $? -eq 0 ]; then echo "ACA PKI setup complete" | tee -a "$LOG_FILE" else @@ -109,7 +109,7 @@ if [ -z "${ARG_SKIP_PKI}" ]; then fi if [ -z "${ARG_SKIP_DB}" ]; then - sh ../db/db_create.sh $LOG_FILE $PKI_PASS $ARG_UNATTEND + ../db/db_create.sh $LOG_FILE $PKI_PASS $ARG_UNATTEND if [ $? -eq 0 ]; then echo "ACA database setup complete" | tee -a "$LOG_FILE" else @@ -122,4 +122,4 @@ fi echo "ACA setup complete" | tee -a "$LOG_FILE" -popd &>/dev/null \ No newline at end of file +popd &>/dev/null diff --git a/package/scripts/db/db_create.sh b/package/scripts/db/db_create.sh index e723ec9f..99c17f24 100755 --- a/package/scripts/db/db_create.sh +++ b/package/scripts/db/db_create.sh @@ -17,7 +17,7 @@ SCRIPT_DIR=$( dirname -- "$( readlink -f -- "$0"; )"; ) SPRING_PROP_FILE="/etc/hirs/aca/application.properties" ACA_PROP_FILE="/etc/hirs/aca/aca.properties" DB_ADMIN_PWD="" -# Db Configuration files +# Db Configuration fileis, use RHELpaths as default DB_SRV_CONF="/etc/my.cnf.d/mariadb-server.cnf" DB_CLIENT_CONF="/etc/my.cnf.d/client.cnf" # Default Server Side Certificates @@ -39,6 +39,14 @@ mkdir -p /var/log/hirs/ source $SCRIPT_DIR/mysql_util.sh source $ACA_PROP_FILE +source /etc/os-release + +# Setup distro specifc paths and variables +if [ $ID = "ubuntu" ]; then + DB_SRV_CONF="/etc/mysql/mariadb.conf.d/50-server.cnf" + DB_CLIENT_CONF="/etc/mysql/mariadb.conf.d/50-client.cnf" + echo log_error=/var/log/mysql/mariadb.log >> $DB_SRV_CONF +fi check_mysql_root_pwd () { # Check if DB root password needs to be obtained @@ -79,8 +87,8 @@ check_mysql_root_pwd () { } set_mysql_server_tls () { - # Check DB server setup. If ssl params dont exist then we need to add them. - if [[ $(cat "$DB_SRV_CONF" | grep -c "ssl") < 1 ]]; then + # Check DB server setup. If HIRS ssl params dont exist then we need to add them. + if [[ $(cat "$DB_SRV_CONF" | grep -c "HIRS") < 1 ]]; then # Add TLS files to my.cnf echo "Updating $DB_SRV_CONF with ssl parameters..." | tee -a "$LOG_FILE" echo "ssl_ca=$SSL_DB_SRV_CHAIN" >> "$DB_SRV_CONF" @@ -101,7 +109,7 @@ set_mysql_server_tls () { set_mysql_client_tls () { # Update ACA property file with client cert info, if not there already -if [[ $(cat "$DB_CLIENT_CONF" | grep -c "ssl") < 1 ]]; then +if [[ $(cat "$DB_CLIENT_CONF" | grep -c "HIRS") < 1 ]]; then echo "Updating $DB_CLIENT_CONF with ssl parameters..." | tee -a "$LOG_FILE" echo "ssl_ca=$SSL_DB_CLIENT_CHAIN" >> $DB_CLIENT_CONF echo "ssl_cert=$SSL_DB_CLIENT_CERT" >> $DB_CLIENT_CONF diff --git a/package/scripts/pki/pki_setup.sh b/package/scripts/pki/pki_setup.sh index 5a28142b..763e40f5 100755 --- a/package/scripts/pki/pki_setup.sh +++ b/package/scripts/pki/pki_setup.sh @@ -33,8 +33,8 @@ if [ -z "$2" ]; then fi # Check for sudo or root user -if [ "$EUID" -ne 0 ] - then echo "This script requires root. Please run as root" | tee -a "$LOG_FILE" +if [ "$EUID" -ne 0 ]; then + echo "This script requires root. Please run as root" | tee -a "$LOG_FILE" exit 1 fi @@ -52,8 +52,8 @@ if [ ! -d "/etc/hirs/certificates" ]; then pushd /etc/hirs/certificates/ &> /dev/null cp $PKI_SETUP_DIR/ca.conf . - sh $PKI_SETUP_DIR/pki_chain_gen.sh "HIRS" "rsa" "3072" "sha384" "$PKI_PASS" "$LOG_FILE" - sh $PKI_SETUP_DIR/pki_chain_gen.sh "HIRS" "ecc" "512" "sha384" "$PKI_PASS" "$LOG_FILE" + $PKI_SETUP_DIR/pki_chain_gen.sh "HIRS" "rsa" "3072" "sha384" "$PKI_PASS" "$LOG_FILE" + $PKI_SETUP_DIR/pki_chain_gen.sh "HIRS" "ecc" "512" "sha384" "$PKI_PASS" "$LOG_FILE" popd &> /dev/null echo "hirs_pki_password="$PKI_PASS >> $ACA_PROP diff --git a/test.sh b/test.sh deleted file mode 100644 index 6eeb60f5..00000000 --- a/test.sh +++ /dev/null @@ -1,5 +0,0 @@ -echo " -# *** ACA Directories *** -aca.directories.root = /etc/hirs/ -aca.prop.file=aca.directories.root/aca.properties -aca.directories.certificates = root/certificates" From 556322ad394a0469968c8b3d711bb2121fbb5860 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Fri, 6 Oct 2023 15:07:12 -0400 Subject: [PATCH 17/26] Some additional changes to fix UI errors after I was able to test against another machine. --- .../entity/tpm/TPM2ProvisionerState.java | 4 +-- .../provision/IdentityClaimProcessor.java | 4 +-- .../portal/PersistenceJPAConfig.java | 2 +- .../CertificatePageController.java | 21 ++++++----- .../controllers/DevicePageController.java | 4 +-- .../ReferenceManifestPageController.java | 6 ++-- ...estfulAttestationCertificateAuthority.java | 35 ------------------- .../RimDatabasePageController.java | 4 +-- 8 files changed, 26 insertions(+), 54 deletions(-) delete mode 100644 HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RestfulAttestationCertificateAuthority.java diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerState.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerState.java index 18b50f08..fc44115d 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerState.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerState.java @@ -20,7 +20,7 @@ import java.util.Date; @NoArgsConstructor @Entity public class TPM2ProvisionerState { - private static final int MAX_BLOB_SIZE = 65535; + private static final int MAX_BLOB_SIZE = 16777215; @Id private Long firstPartOfNonce; @@ -88,7 +88,7 @@ public class TPM2ProvisionerState { /** * Convenience method for finding the {@link TPM2ProvisionerState} associated with the nonce. * - * @param TPM2ProvisionerStateRepository the {@link TPM2ProvisionerStateRepository} to use when looking for the + * @param tpm2ProvisionerStateRepository the {@link TPM2ProvisionerStateRepository} to use when looking for the * {@link TPM2ProvisionerState} * @param nonce the nonce to use as the key for the {@link TPM2ProvisionerState} * @return the {@link TPM2ProvisionerState} associated with the nonce; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java index d969114c..05e1ad77 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java @@ -464,8 +464,8 @@ public class IdentityClaimProcessor extends AbstractProcessor { if (baseRim != null) { // pull the base versions of the swidtag and rimel and set the // event log hash for use during provision - SupportReferenceManifest sBaseRim = (SupportReferenceManifest) referenceManifestRepository - .findByBase64Hash(baseRim.getBase64Hash()); + SupportReferenceManifest sBaseRim = referenceManifestRepository + .getSupportRimEntityById(baseRim.getAssociatedRim()); baseRim.setEventLogHash(temp.getHexDecHash()); sBaseRim.setEventLogHash(temp.getHexDecHash()); referenceManifestRepository.save(baseRim); diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/PersistenceJPAConfig.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/PersistenceJPAConfig.java index 8168d623..1bbac7ff 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/PersistenceJPAConfig.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/PersistenceJPAConfig.java @@ -52,7 +52,7 @@ import java.util.Properties; @PropertySource(value = "classpath:hibernate.properties"), // detects if file exists, if not, ignore errors - @PropertySource(value = "file:/etc/hirs/aca/application.properties", + @PropertySource(value = "file:/etc/hirs/aca/aca.properties", ignoreResourceNotFound = true) }) @ComponentScan({"hirs.attestationca.portal", "hirs.attestationca.portal.page.controllers", "hirs.attestationca.persist", "hirs.attestationca.persist.entity", "hirs.attestationca.persist.service"}) diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java index 7a58df69..7e71de79 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java @@ -228,6 +228,7 @@ public class CertificatePageController extends PageController { }; int currentPage = input.getStart() / input.getLength(); + int itemCount = 0; Pageable paging = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName)); // special parsing for platform credential @@ -242,9 +243,10 @@ public class CertificatePageController extends PageController { org.springframework.data.domain.Page pagedResult = this.platformCertificateRepository.findAll(paging); if (pagedResult.hasContent()) { records.addAll(pagedResult.getContent()); + itemCount = records.size(); } - records.setRecordsTotal(input.getLength()); - records.setRecordsFiltered(platformCertificateRepository.count()); + records.setRecordsTotal(platformCertificateRepository.count()); + records.setRecordsFiltered(itemCount); EndorsementCredential associatedEC; if (!records.isEmpty()) { @@ -274,10 +276,11 @@ public class CertificatePageController extends PageController { org.springframework.data.domain.Page pagedResult = this.endorsementCredentialRepository.findAll(paging); if (pagedResult.hasContent()) { records.addAll(pagedResult.getContent()); + itemCount = records.size(); } - records.setRecordsTotal(input.getLength()); - records.setRecordsFiltered(endorsementCredentialRepository.count()); + records.setRecordsTotal(endorsementCredentialRepository.count()); + records.setRecordsFiltered(itemCount); log.debug("Returning list of size: " + records.size()); return new DataTableResponse<>(records, input); @@ -290,9 +293,10 @@ public class CertificatePageController extends PageController { if (pagedResult.hasContent()) { records.addAll(pagedResult.getContent()); + itemCount = records.size(); } - records.setRecordsTotal(input.getLength()); - records.setRecordsFiltered(caCredentialRepository.count()); + records.setRecordsTotal(caCredentialRepository.count()); + records.setRecordsFiltered(itemCount); log.debug("Returning list of size: " + records.size()); return new DataTableResponse<>(records, input); @@ -301,9 +305,10 @@ public class CertificatePageController extends PageController { org.springframework.data.domain.Page pagedResult = this.issuedCertificateRepository.findAll(paging); if (pagedResult.hasContent()) { records.addAll(pagedResult.getContent()); + itemCount = records.size(); } - records.setRecordsTotal(input.getLength()); - records.setRecordsFiltered(issuedCertificateRepository.count()); + records.setRecordsTotal(issuedCertificateRepository.count()); + records.setRecordsFiltered(itemCount); log.debug("Returning list of size: " + records.size()); return new DataTableResponse<>(records, input); diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java index 693e85a2..9153f21f 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java @@ -96,8 +96,8 @@ public class DevicePageController extends PageController { if (pagedResult.hasContent()) { deviceList.addAll(pagedResult.getContent()); } - deviceList.setRecordsTotal(input.getLength()); - deviceList.setRecordsFiltered(deviceRepository.count()); + deviceList.setRecordsTotal(deviceRepository.count()); + deviceList.setRecordsFiltered(deviceList.size()); FilteredRecordsList> records = retrieveDevicesAndAssociatedCertificates(deviceList); diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java index 6a83348f..49690f99 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java @@ -119,6 +119,7 @@ public class ReferenceManifestPageController extends PageController records = new FilteredRecordsList<>(); + int itemCount = 0; int currentPage = input.getStart() / input.getLength(); Pageable paging = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName)); org.springframework.data.domain.Page pagedResult = referenceManifestRepository.findAll(paging); @@ -127,11 +128,12 @@ public class ReferenceManifestPageController extends PageController(records, input); diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RestfulAttestationCertificateAuthority.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RestfulAttestationCertificateAuthority.java deleted file mode 100644 index 74213318..00000000 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RestfulAttestationCertificateAuthority.java +++ /dev/null @@ -1,35 +0,0 @@ -package hirs.attestationca.portal.page.controllers; - -/** - * Restful implementation of the {@link }. - * Exposes the ACA methods as REST endpoints. - */ -//@RestController -//@RequestMapping("/") -public class RestfulAttestationCertificateAuthority { -// private final ReferenceManifestRepository referenceManifestRepository; -// private final ReferenceDigestValueRepository referenceDigestValueRepository; -// -// @Autowired -// public RestfulAttestationCertificateAuthority( -// final ReferenceManifestRepository referenceManifestRepository, -// final ReferenceDigestValueRepository referenceDigestValueRepository) { -// -// this.referenceManifestRepository = referenceManifestRepository; -// this.referenceDigestValueRepository = referenceDigestValueRepository; -// -// } -// -// -// @ResponseBody -// @RequestMapping(value = "/upload-swidtag", method = RequestMethod.POST, consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE) -// public byte[] uploadSwidtag(@RequestBody final byte[] request) { -// return null; -// } -// -// @ResponseBody -// @RequestMapping(value = "/upload-rimel", method = RequestMethod.POST, consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE) -// public byte[] uploadRimel(@RequestBody final byte[] request) { -// return null; -// } -} diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java index 0a2e76ed..474ce59e 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java @@ -117,8 +117,8 @@ public class RimDatabasePageController extends PageController { if (pagedResult.hasContent()) { referenceDigestValues.addAll(pagedResult.getContent()); } - referenceDigestValues.setRecordsTotal(input.getLength()); - referenceDigestValues.setRecordsFiltered(referenceDigestValueRepository.count()); + referenceDigestValues.setRecordsTotal(referenceDigestValueRepository.count()); + referenceDigestValues.setRecordsFiltered(referenceDigestValues.size()); // FilteredRecordsList referenceDigestValues = // OrderedListQueryDataTableAdapter.getOrderedList( From ec39bf55a335e03cbbc9695a16849b83f6d1dee5 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Tue, 10 Oct 2023 13:31:45 -0400 Subject: [PATCH 18/26] Corrected an issue with the root CA looking itself causing an issue because the one root CA had an illegal character. --- .../persist/entity/manager/CACredentialRepository.java | 1 + .../portal/page/controllers/DevicePageController.java | 4 ++-- .../page/controllers/ReferenceManifestPageController.java | 6 ++---- .../page/controllers/RimDatabasePageController.java | 4 ++-- .../portal/page/utils/CertificateStringMapBuilder.java | 8 ++++---- .../src/main/java/hirs/utils/BouncyCastleUtils.java | 4 ++-- 6 files changed, 13 insertions(+), 14 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/CACredentialRepository.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/CACredentialRepository.java index cd30f254..d3f3074f 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/CACredentialRepository.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/CACredentialRepository.java @@ -17,4 +17,5 @@ public interface CACredentialRepository extends JpaRepository findBySubject(String subject); List findBySubjectSorted(String subject); CertificateAuthorityCredential findBySubjectKeyIdentifier(byte[] subjectKeyIdentifier); + CertificateAuthorityCredential findBySubjectKeyIdString(String subjectKeyIdString); } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java index 9153f21f..693e85a2 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java @@ -96,8 +96,8 @@ public class DevicePageController extends PageController { if (pagedResult.hasContent()) { deviceList.addAll(pagedResult.getContent()); } - deviceList.setRecordsTotal(deviceRepository.count()); - deviceList.setRecordsFiltered(deviceList.size()); + deviceList.setRecordsTotal(input.getLength()); + deviceList.setRecordsFiltered(deviceRepository.count()); FilteredRecordsList> records = retrieveDevicesAndAssociatedCertificates(deviceList); diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java index 49690f99..6a83348f 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java @@ -119,7 +119,6 @@ public class ReferenceManifestPageController extends PageController records = new FilteredRecordsList<>(); - int itemCount = 0; int currentPage = input.getStart() / input.getLength(); Pageable paging = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName)); org.springframework.data.domain.Page pagedResult = referenceManifestRepository.findAll(paging); @@ -128,12 +127,11 @@ public class ReferenceManifestPageController extends PageController(records, input); diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java index 474ce59e..0a2e76ed 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java @@ -117,8 +117,8 @@ public class RimDatabasePageController extends PageController { if (pagedResult.hasContent()) { referenceDigestValues.addAll(pagedResult.getContent()); } - referenceDigestValues.setRecordsTotal(referenceDigestValueRepository.count()); - referenceDigestValues.setRecordsFiltered(referenceDigestValues.size()); + referenceDigestValues.setRecordsTotal(input.getLength()); + referenceDigestValues.setRecordsFiltered(referenceDigestValueRepository.count()); // FilteredRecordsList referenceDigestValues = // OrderedListQueryDataTableAdapter.getOrderedList( diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java index f7921b6a..9c1066a9 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/CertificateStringMapBuilder.java @@ -20,6 +20,7 @@ import org.bouncycastle.util.encoders.Hex; import java.io.IOException; import java.math.BigInteger; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; @@ -149,15 +150,14 @@ public final class CertificateStringMapBuilder { final Certificate certificate, final CertificateRepository certificateRepository, final CACredentialRepository caCredentialRepository) { - List issuerCertificates = new LinkedList<>(); + List issuerCertificates = new ArrayList<>(); CertificateAuthorityCredential skiCA = null; String issuerResult; //Check if there is a subject organization if (certificate.getAuthorityKeyIdentifier() != null && !certificate.getAuthorityKeyIdentifier().isEmpty()) { - byte[] bytes = Hex.decode(certificate.getAuthorityKeyIdentifier()); - skiCA = caCredentialRepository.findBySubjectKeyIdentifier(bytes); + skiCA = caCredentialRepository.findBySubjectKeyIdString(certificate.getAuthorityKeyIdentifier()); } else { log.error(String.format("Certificate (%s) for %s has no authority key identifier.", certificate.getClass().toString(), certificate.getSubject())); @@ -185,7 +185,7 @@ public final class CertificateStringMapBuilder { if (issuerResult.isEmpty()) { //Check if it's root certificate if (BouncyCastleUtils.x500NameCompare(issuerCert.getIssuerSorted(), - issuerCert.getSubject())) { + issuerCert.getSubjectSorted())) { return null; } return containsAllChain(issuerCert, certificateRepository, caCredentialRepository); diff --git a/HIRS_Utils/src/main/java/hirs/utils/BouncyCastleUtils.java b/HIRS_Utils/src/main/java/hirs/utils/BouncyCastleUtils.java index 3c748284..eab8a820 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/BouncyCastleUtils.java +++ b/HIRS_Utils/src/main/java/hirs/utils/BouncyCastleUtils.java @@ -36,8 +36,8 @@ public final class BouncyCastleUtils { X500Name x500Name2; try { - x500Name1 = new X500Name(nameValue1.replace(SEPARATOR_PLUS, SEPARATOR_COMMA)); - x500Name2 = new X500Name(nameValue2.replace(SEPARATOR_PLUS, SEPARATOR_COMMA)); + x500Name1 = new X500Name(nameValue1); + x500Name2 = new X500Name(nameValue2); result = x500Name1.equals(x500Name2); } catch (IllegalArgumentException iaEx) { log.error(iaEx.toString()); From 841080ba58dc8a4b0c124925b5b204aa71ed1572 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Tue, 10 Oct 2023 14:22:35 -0400 Subject: [PATCH 19/26] Missed some additional code for testing the element listing --- .../CertificatePageController.java | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java index 7e71de79..0cf5c1ec 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java @@ -235,18 +235,14 @@ public class CertificatePageController extends PageController { // Add the EndorsementCredential for each PlatformCredential based on the // serial number. (pc.HolderSerialNumber = ec.SerialNumber) if (certificateType.equals(PLATFORMCREDENTIAL)) { -// records = OrderedListQueryDataTableAdapter.getOrderedList( -// getCertificateClass(certificateType), platformCertificateRepository, -// input, orderColumnName, criteriaModifier); FilteredRecordsList records = new FilteredRecordsList<>(); org.springframework.data.domain.Page pagedResult = this.platformCertificateRepository.findAll(paging); if (pagedResult.hasContent()) { records.addAll(pagedResult.getContent()); - itemCount = records.size(); } - records.setRecordsTotal(platformCertificateRepository.count()); - records.setRecordsFiltered(itemCount); + records.setRecordsTotal(input.getLength()); + records.setRecordsFiltered(platformCertificateRepository.count()); EndorsementCredential associatedEC; if (!records.isEmpty()) { @@ -269,34 +265,26 @@ public class CertificatePageController extends PageController { log.debug("Returning list of size: " + records.size()); return new DataTableResponse<>(records, input); } else if (certificateType.equals(ENDORSEMENTCREDENTIAL)) { -// records = OrderedListQueryDataTableAdapter.getOrderedList( -// getCertificateClass(certificateType), endorsementCredentialRepository, -// input, orderColumnName, criteriaModifier); FilteredRecordsList records = new FilteredRecordsList<>(); org.springframework.data.domain.Page pagedResult = this.endorsementCredentialRepository.findAll(paging); if (pagedResult.hasContent()) { records.addAll(pagedResult.getContent()); - itemCount = records.size(); } - records.setRecordsTotal(endorsementCredentialRepository.count()); - records.setRecordsFiltered(itemCount); + records.setRecordsTotal(input.getLength()); + records.setRecordsFiltered(endorsementCredentialRepository.count()); log.debug("Returning list of size: " + records.size()); return new DataTableResponse<>(records, input); } else if (certificateType.equals(TRUSTCHAIN)) { -// records = OrderedListQueryDataTableAdapter.getOrderedList( -// getCertificateClass(certificateType), caCredentialRepository, -// input, orderColumnName, criteriaModifier); FilteredRecordsList records = new FilteredRecordsList<>(); org.springframework.data.domain.Page pagedResult = this.caCredentialRepository.findAll(paging); if (pagedResult.hasContent()) { records.addAll(pagedResult.getContent()); - itemCount = records.size(); } - records.setRecordsTotal(caCredentialRepository.count()); - records.setRecordsFiltered(itemCount); + records.setRecordsTotal(input.getLength()); + records.setRecordsFiltered(caCredentialRepository.count()); log.debug("Returning list of size: " + records.size()); return new DataTableResponse<>(records, input); @@ -305,10 +293,9 @@ public class CertificatePageController extends PageController { org.springframework.data.domain.Page pagedResult = this.issuedCertificateRepository.findAll(paging); if (pagedResult.hasContent()) { records.addAll(pagedResult.getContent()); - itemCount = records.size(); } - records.setRecordsTotal(issuedCertificateRepository.count()); - records.setRecordsFiltered(itemCount); + records.setRecordsTotal(input.getLength()); + records.setRecordsFiltered(issuedCertificateRepository.count()); log.debug("Returning list of size: " + records.size()); return new DataTableResponse<>(records, input); From d968080a4341ae99966a2206abbdb3b3d18ed564 Mon Sep 17 00:00:00 2001 From: iadgovuser26 Date: Tue, 10 Oct 2023 18:29:37 +0000 Subject: [PATCH 20/26] minor adjustments for the deb package --- HIRS_AttestationCAPortal/build.gradle | 7 +++--- package/scripts/db/db_create.sh | 23 +++++++++++------- package/scripts/db/db_drop.sh | 15 +++++++++--- package/scripts/db/mysql_util.sh | 35 +++++++++++++++++---------- 4 files changed, 51 insertions(+), 29 deletions(-) diff --git a/HIRS_AttestationCAPortal/build.gradle b/HIRS_AttestationCAPortal/build.gradle index 94868efa..8a36feda 100644 --- a/HIRS_AttestationCAPortal/build.gradle +++ b/HIRS_AttestationCAPortal/build.gradle @@ -94,16 +94,16 @@ ospackage { } // Post Install - postInstall 'sh /opt/hirs/aca/scripts/aca/aca_setup.sh -u' + postInstall 'bash /opt/hirs/aca/scripts/aca/aca_setup.sh -u' // add chrontab to run ACA at boot postInstall 'echo "@reboot root /opt/hirs/aca/scripts/aca/aca_bootRun.sh -w" >> /etc/crontab' // run ACA after install postInstall '/opt/hirs/aca/scripts/aca/aca_bootRun.sh -w &' postInstall 'chmod +x /opt/hirs/aca/scripts/aca/*' - postInstall 'sh /opt/hirs/aca/scripts/aca/check_for_aca.sh' + postInstall 'bash /opt/hirs/aca/scripts/aca/check_for_aca.sh' // Uninstall - preUninstall 'sh /opt/hirs/aca/scripts/aca/aca_remove_setup.sh' + preUninstall 'bash /opt/hirs/aca/scripts/aca/aca_remove_setup.sh' postUninstall 'rm -rf /etc/hirs' buildRpm { @@ -111,6 +111,7 @@ ospackage { } buildDeb { + packageName = 'hirs-attestationca' arch = 'amd64' } } diff --git a/package/scripts/db/db_create.sh b/package/scripts/db/db_create.sh index 99c17f24..2976395d 100755 --- a/package/scripts/db/db_create.sh +++ b/package/scripts/db/db_create.sh @@ -45,7 +45,7 @@ source /etc/os-release if [ $ID = "ubuntu" ]; then DB_SRV_CONF="/etc/mysql/mariadb.conf.d/50-server.cnf" DB_CLIENT_CONF="/etc/mysql/mariadb.conf.d/50-client.cnf" - echo log_error=/var/log/mysql/mariadb.log >> $DB_SRV_CONF + echo log_error=/var/log/mysql/mysqld.log >> $DB_SRV_CONF fi check_mysql_root_pwd () { @@ -97,10 +97,12 @@ set_mysql_server_tls () { # Make sure mysql can access them chown mysql:mysql $SSL_DB_SRV_CHAIN $SSL_DB_SRV_CERT $SSL_DB_SRV_KEY # Make selinux contexts for config files, if selinux is enabled - selinuxenabled - if [ $? -eq 0 ]; then - semanage fcontext -a -t mysqld_etc_t $DB_SRV_CONF > /dev/null #adds the context type to file - restorecon -v -F $DB_SRV_CONF > /dev/null # changes the file's context type + if [ $ID = "rhel" ]; then + selinuxenabled + if [ $? -eq 0 ]; then + semanage fcontext -a -t mysqld_etc_t $DB_SRV_CONF > /dev/null #adds the context type to file + restorecon -v -F $DB_SRV_CONF > /dev/null # changes the file's context type + fi fi else echo "mysql.cnf contians existing entry for ssl, skipping..." | tee -a "$LOG_FILE" @@ -116,10 +118,12 @@ if [[ $(cat "$DB_CLIENT_CONF" | grep -c "HIRS") < 1 ]]; then echo "ssl_key=$SSL_DB_CLIENT_KEY" >> $DB_CLIENT_CONF chown mysql:mysql $SSL_DB_CLIENT_CHAIN $SSL_DB_CLIENT_CERT $SSL_DB_CLIENT_KEY # Make selinux contexts for config files, if selinux is enabled - selinuxenabled - if [ $? -eq 0 ]; then - semanage fcontext -a -t mysqld_etc_t $DB_CLIENT_CONFf > /dev/null #adds the context type to file - restorecon -F $DB_CLIENT_CONF > /dev/null #changes the file's context type + if [ $ID = "rhel" ]; then + selinuxenabled + if [ $? -eq 0 ]; then + semanage fcontext -a -t mysqld_etc_t $DB_CLIENT_CONFf > /dev/null #adds the context type to file + restorecon -F $DB_CLIENT_CONF > /dev/null #changes the file's context type + fi fi fi } @@ -193,6 +197,7 @@ check_for_container -p set_mysql_server_tls set_mysql_client_tls start_mysqlsd +check_mysql check_mysql_root_pwd set_hirs_db_pwd create_hirs_db_with_tls diff --git a/package/scripts/db/db_drop.sh b/package/scripts/db/db_drop.sh index 234f98e9..cb5cdc5c 100755 --- a/package/scripts/db/db_drop.sh +++ b/package/scripts/db/db_drop.sh @@ -1,13 +1,14 @@ #!/bin/bash -SRV_CNF=/etc/my.cnf.d/mariadb-server.cnf -CLIENT_CNF=/etc/my.cnf.d/client.cnf +DB_SRV_CONF=/etc/my.cnf.d/mariadb-server.cnf +DB_CLIENT_CONF=/etc/my.cnf.d/client.cnf SCRIPT_DIR=$( dirname -- "$( readlink -f -- "$0"; )";) LOG_FILE=/dev/null DB_ADMIN_PWD=$1 #source /etc/hirs/aca/aca.properties; source $SCRIPT_DIR/mysql_util.sh +source /etc/os-release # Check for sudo or root user, not actually needed but a good idea if [ "$EUID" -ne 0 ] @@ -15,6 +16,12 @@ if [ "$EUID" -ne 0 ] exit 1 fi +# Setup distro specifc paths and variables +if [ $ID = "ubuntu" ]; then + DB_SRV_CONF="/etc/mysql/mariadb.conf.d/50-server.cnf" + DB_CLIENT_CONF="/etc/mysql/mariadb.conf.d/50-client.cnf" +fi + if [ -d /opt/hirs/scripts/db ]; then MYSQL_DIR="/opt/hirs/scripts/db" else @@ -44,8 +51,8 @@ fi # Remove key , cert and truststore entries from client.cnf andf mariadb.cnf echo "Removing hirs cert references from mariadb configuration files" -grep -v "hirs" $SRV_CNF > tmpfile && mv tmpfile $SRV_CNF -grep -v "hirs" $CLIENT_CNF > tmpfile && mv tmpfile $CLIENT_CNF +grep -v "hirs" $DB_SRV_CONF > tmpfile && mv tmpfile $DB_SRV_CONF +grep -v "hirs" $DB_CLIENT_CONF > tmpfile && mv tmpfile $DB_CLIENT_CONF echo "restarting mariadb" diff --git a/package/scripts/db/mysql_util.sh b/package/scripts/db/mysql_util.sh index f2eefeb7..fdd31289 100755 --- a/package/scripts/db/mysql_util.sh +++ b/package/scripts/db/mysql_util.sh @@ -40,8 +40,13 @@ check_mariadb_install () { # Starts mariadb during intial install start_mysqlsd () { PRINT_STATUS=$1 + PROCESS="mysqld" + source /etc/os-release + if [ $ID = "ubuntu" ]; then + PROCESS="mariadb" + fi # Check if mysql is already running, if not initialize - if [[ $(pgrep -c -u mysql mysqld) -eq 0 ]]; then + if [[ $(pgrep -c -u mysql $PROCESS) -eq 0 ]]; then # Check if running in a container if [ $DOCKER_CONTAINER = true ]; then # if in Docker container, avoid services that invoke the D-Bus @@ -70,13 +75,6 @@ start_mysqlsd () { fi fi # non contanier mysql start fi - # Wait for mysql to start before continuing. - if [[ $PRINT_STATUS == "-p" ]]; then echo "Checking mysqld status..."| tee -a "$LOG_FILE"; fi - while ! mysqladmin ping -h "$localhost" --silent; do - sleep 1; - done - - if [[ $PRINT_STATUS == "-p" ]]; then echo "mysqld is running."| tee -a "$LOG_FILE"; fi } # Basic check for marai db status, attempts restart if not running @@ -95,12 +93,23 @@ check_mysql () { fi fi - # Wait for mysql to start before continuing. - while ! mysqladmin ping -h "$localhost" --silent; do - sleep 1; +# Wait for mysql to start before continuing. + count=1; + if [[ $PRINT_STATUS == "-p" ]]; then echo "Checking mysqld status..."| tee -a "$LOG_FILE"; fi + + until mysqladmin ping -h "localhost" --silent ; do + ((count++)) + if [[ $count -gt 20 ]]; then + break; + fi + sleep 1; done - echo " Mariadb is running." + if [[ $count -gt 20 ]]; then + echo "Timed out waiting for Mariadb to respond" + else + echo "Mariadb started" + fi } # Check for mysql root password , abort if not available @@ -164,4 +173,4 @@ mysqld_reboot () { sleep 2 check_for_container start_mysqlsd -} \ No newline at end of file +} From 0c131e6ee57ecab085ac7d383fe0ad2d53df7d8c Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Tue, 10 Oct 2023 15:06:12 -0400 Subject: [PATCH 21/26] Fixed the inccorect data at the bottom of the data tables when displaying the elements. --- .../CertificatePageController.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java index 0cf5c1ec..08df7d76 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificatePageController.java @@ -228,7 +228,6 @@ public class CertificatePageController extends PageController { }; int currentPage = input.getStart() / input.getLength(); - int itemCount = 0; Pageable paging = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName)); // special parsing for platform credential @@ -236,12 +235,15 @@ public class CertificatePageController extends PageController { // serial number. (pc.HolderSerialNumber = ec.SerialNumber) if (certificateType.equals(PLATFORMCREDENTIAL)) { FilteredRecordsList records = new FilteredRecordsList<>(); - org.springframework.data.domain.Page pagedResult = this.platformCertificateRepository.findAll(paging); + if (pagedResult.hasContent()) { records.addAll(pagedResult.getContent()); + records.setRecordsTotal(pagedResult.getContent().size()); + } else { + records.setRecordsTotal(input.getLength()); } - records.setRecordsTotal(input.getLength()); + records.setRecordsFiltered(platformCertificateRepository.count()); EndorsementCredential associatedEC; @@ -267,11 +269,14 @@ public class CertificatePageController extends PageController { } else if (certificateType.equals(ENDORSEMENTCREDENTIAL)) { FilteredRecordsList records = new FilteredRecordsList<>(); org.springframework.data.domain.Page pagedResult = this.endorsementCredentialRepository.findAll(paging); + if (pagedResult.hasContent()) { records.addAll(pagedResult.getContent()); + records.setRecordsTotal(pagedResult.getContent().size()); + } else { + records.setRecordsTotal(input.getLength()); } - records.setRecordsTotal(input.getLength()); records.setRecordsFiltered(endorsementCredentialRepository.count()); log.debug("Returning list of size: " + records.size()); @@ -282,8 +287,11 @@ public class CertificatePageController extends PageController { if (pagedResult.hasContent()) { records.addAll(pagedResult.getContent()); + records.setRecordsTotal(pagedResult.getContent().size()); + } else { + records.setRecordsTotal(input.getLength()); } - records.setRecordsTotal(input.getLength()); + records.setRecordsFiltered(caCredentialRepository.count()); log.debug("Returning list of size: " + records.size()); @@ -291,10 +299,14 @@ public class CertificatePageController extends PageController { } else if (certificateType.equals(ISSUEDCERTIFICATES)) { FilteredRecordsList records = new FilteredRecordsList<>(); org.springframework.data.domain.Page pagedResult = this.issuedCertificateRepository.findAll(paging); + if (pagedResult.hasContent()) { records.addAll(pagedResult.getContent()); + records.setRecordsTotal(pagedResult.getContent().size()); + } else { + records.setRecordsTotal(input.getLength()); } - records.setRecordsTotal(input.getLength()); + records.setRecordsFiltered(issuedCertificateRepository.count()); log.debug("Returning list of size: " + records.size()); From 03ee0bfda8bbc172d636a57b86e90e181cc91afd Mon Sep 17 00:00:00 2001 From: iadgovuser26 Date: Wed, 11 Oct 2023 19:56:36 +0000 Subject: [PATCH 22/26] Updated the dockerfile for Ubuntu 22 --- .ci/docker/Dockerfile.ubuntu22ci | 19 +++++++++++++++++++ package/scripts/aca/aca_check_setup.sh | 2 +- package/scripts/db/db_create.sh | 12 +++++++++--- package/scripts/db/mysql_util.sh | 10 ++++++++-- package/scripts/pki/pki_chain_gen.sh | 5 ++++- 5 files changed, 41 insertions(+), 7 deletions(-) diff --git a/.ci/docker/Dockerfile.ubuntu22ci b/.ci/docker/Dockerfile.ubuntu22ci index e69de29b..64a692d9 100644 --- a/.ci/docker/Dockerfile.ubuntu22ci +++ b/.ci/docker/Dockerfile.ubuntu22ci @@ -0,0 +1,19 @@ +FROM ubuntu:22.04 + +RUN apt-get update -y && apt-get upgrade -y && apt-get clean -y + +# Install packages for building HIRS ACA +RUN apt-get -y install openjdk-17-jdk mariadb-server +RUN apt-get -y install git curl nano cron + +# Ports needed for system-level tests +EXPOSE 8080 +EXPOSE 8443 + +# Checkout HIRS main branch and run gradlew to install gradlew dependencies, then delete HIRS +# Use '--depth=1' so as to not download the history of all commits +RUN git clone -b main --depth=1 https://github.com/nsacyber/HIRS.git /hirsTemp +WORKDIR "/hirsTemp" +RUN /bin/bash -c './gradlew clean build' +WORKDIR "/" +RUN rm -rf /hirsTemp diff --git a/package/scripts/aca/aca_check_setup.sh b/package/scripts/aca/aca_check_setup.sh index bf4ed0d5..d4a75c56 100755 --- a/package/scripts/aca/aca_check_setup.sh +++ b/package/scripts/aca/aca_check_setup.sh @@ -82,7 +82,7 @@ echo "Checking HIRS ACA Setup on this device..." rpm -q --quiet HIRS_AttestationCA elif [ $ID = 'ubuntu' ]; then echo "Ubuntu distro detected" - dpkg -l "HIRS_AttestationCA" > /dev/null + dpkg -l "hirs-attestationca" > /dev/null else echo "Unsupported OS Distro encountered" fi diff --git a/package/scripts/db/db_create.sh b/package/scripts/db/db_create.sh index 2976395d..f576d2dc 100755 --- a/package/scripts/db/db_create.sh +++ b/package/scripts/db/db_create.sh @@ -45,7 +45,11 @@ source /etc/os-release if [ $ID = "ubuntu" ]; then DB_SRV_CONF="/etc/mysql/mariadb.conf.d/50-server.cnf" DB_CLIENT_CONF="/etc/mysql/mariadb.conf.d/50-client.cnf" - echo log_error=/var/log/mysql/mysqld.log >> $DB_SRV_CONF + if [[ $(cat "$DB_SRV_CONF" | grep -c "log-error") < 1 ]]; then + echo log-error=/var/log/mysql/mysqld.log >> $DB_SRV_CONF + echo "ssl-cipher=TLSv1.3" >> $DB_SRV_CONF + echo "ssl=on" >> $DB_SRV_CONF + fi fi check_mysql_root_pwd () { @@ -131,7 +135,8 @@ fi # Process HIRS DB USER set_hirs_db_pwd () { - RESULT="$(mysql -u root --password=$DB_ADMIN_PWD -e "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'hirs_db')")" + RESULT="$(mysql -u root --password=$DB_ADMIN_PWD -e "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'hirs_db')")" + if [ "$RESULT" = 1 ]; then echo "hirs-db user exists" HIRS_DB_PWD=$hirs_db_password @@ -158,7 +163,8 @@ create_hirs_db_with_tls () { else mysql -u root --password=$DB_ADMIN_PWD < $MYSQL_DIR/db_create.sql mysql -u root --password=$DB_ADMIN_PWD < $MYSQL_DIR/secure_mysql.sql - mysql -u root --password=$DB_ADMIN_PWD -e "ALTER USER 'hirs_db'@'localhost' IDENTIFIED BY '"$HIRS_DB_PWD"'; FLUSH PRIVILEGES;"; +# mysql -u root --password=$DB_ADMIN_PWD -e "ALTER USER 'hirs_db'@'localhost' IDENTIFIED BY '"$HIRS_DB_PWD"'; FLUSH PRIVILEGES;"; + mysql -u root --password=$DB_ADMIN_PWD -e "SET PASSWORD FOR 'hirs_db'@'localhost' = PASSWORD('"$HIRS_DB_PWD"'); FLUSH PRIVILEGES;"; fi } diff --git a/package/scripts/db/mysql_util.sh b/package/scripts/db/mysql_util.sh index fdd31289..8cbb0391 100755 --- a/package/scripts/db/mysql_util.sh +++ b/package/scripts/db/mysql_util.sh @@ -79,9 +79,15 @@ start_mysqlsd () { # Basic check for marai db status, attempts restart if not running check_mysql () { + PROCESS="mysqld" + source /etc/os-release + if [ $ID = "ubuntu" ]; then + PROCESS="mariadb" + fi + echo "Checking mysqld status..." if [ $DOCKER_CONTAINER = true ]; then - if [[ $(pgrep -c -u mysql mysqld) -eq 0 ]]; then + if [[ $(pgrep -c -u mysql $PROCESS ) -eq 0 ]]; then echo "mariadb not running , attempting to restart" /usr/bin/mysqld_safe & >> "$LOG_FILE" fi @@ -96,7 +102,7 @@ check_mysql () { # Wait for mysql to start before continuing. count=1; - if [[ $PRINT_STATUS == "-p" ]]; then echo "Checking mysqld status..."| tee -a "$LOG_FILE"; fi + if [[ $PRINT_STATUS == "-p" ]]; then echo "Testing mysqld connection..."| tee -a "$LOG_FILE"; fi until mysqladmin ping -h "localhost" --silent ; do ((count++)) diff --git a/package/scripts/pki/pki_chain_gen.sh b/package/scripts/pki/pki_chain_gen.sh index c2e08893..9123199d 100755 --- a/package/scripts/pki/pki_chain_gen.sh +++ b/package/scripts/pki/pki_chain_gen.sh @@ -225,6 +225,9 @@ create_cert_chain () { -srcstorepass $PASS -destkeystore $DB_CLIENT.jks -deststoretype JKS -deststorepass $PASS >> "$LOG_FILE" 2>&1 } +# Needed for older versions of openssl + #openssl rand -writerand .rnd + if [ "$ASYM_ALG" == "rsa" ]; then # Create Root CA key pair and self signed cert echo "Generating RSA Root CA ...." | tee -a "$LOG_FILE" @@ -255,4 +258,4 @@ if [ "$ASYM_ALG" == "ecc" ]; then add_to_stores $PKI_ROOT # Create an intermediate CA, 2 Leaf CAs, and Signer Certs create_cert_chain -fi \ No newline at end of file +fi From 9bee292bd65fa69b917881d4c3391299c97ee721 Mon Sep 17 00:00:00 2001 From: iadgovuser26 Date: Thu, 12 Oct 2023 15:17:05 +0000 Subject: [PATCH 23/26] modified the container check --- package/scripts/db/mysql_util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/scripts/db/mysql_util.sh b/package/scripts/db/mysql_util.sh index 8cbb0391..597ef306 100755 --- a/package/scripts/db/mysql_util.sh +++ b/package/scripts/db/mysql_util.sh @@ -12,7 +12,7 @@ SQL_SERVICE="mariadb" check_for_container () { PRINT_STATUS=$1 # Check if we're in a Docker container - if [[ $(cat /proc/1/sched | head -n 1) == *"bash"* ]]; then + if [[ $(cat /proc/1/cgroup | head -n 1) == *"docker"* ]]; then #if [ -f /.dockerenv ]; then DOCKER_CONTAINER=true if [[ $PRINT_STATUS == "-p" ]]; then echo "ACA is running in a container..." | tee -a "$LOG_FILE"; fi From b018429b698f3ec92c1c787739dab24ad5498161 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Fri, 13 Oct 2023 09:39:20 -0400 Subject: [PATCH 24/26] Additional code to correctly display # of elements --- .../portal/page/controllers/DevicePageController.java | 8 +++----- .../controllers/ReferenceManifestPageController.java | 8 ++++++-- .../page/controllers/RimDatabasePageController.java | 9 +++------ .../controllers/ValidationReportsPageController.java | 5 ++++- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java index 693e85a2..4b475c35 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java @@ -84,10 +84,6 @@ public class DevicePageController extends PageController { // get all the devices FilteredRecordsList deviceList = new FilteredRecordsList<>(); -// OrderedListQueryDataTableAdapter.getOrderedList( -// Device.class, -// deviceRepository, -// input, orderColumnName); int currentPage = input.getStart() / input.getLength(); Pageable paging = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName)); @@ -95,8 +91,10 @@ public class DevicePageController extends PageController { if (pagedResult.hasContent()) { deviceList.addAll(pagedResult.getContent()); + deviceList.setRecordsTotal(pagedResult.getContent().size()); + } else { + deviceList.setRecordsTotal(input.getLength()); } - deviceList.setRecordsTotal(input.getLength()); deviceList.setRecordsFiltered(deviceRepository.count()); FilteredRecordsList> records diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java index 6a83348f..e9b53b74 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java @@ -115,22 +115,26 @@ public class ReferenceManifestPageController extends PageController records = new FilteredRecordsList<>(); int currentPage = input.getStart() / input.getLength(); Pageable paging = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName)); org.springframework.data.domain.Page pagedResult = referenceManifestRepository.findAll(paging); + int rimCount = 0; if (pagedResult.hasContent()) { for (ReferenceManifest manifest : pagedResult.getContent()) { if (!manifest.getRimType().equals(ReferenceManifest.MEASUREMENT_RIM)) { records.add(manifest); + rimCount++; } } + records.setRecordsTotal(rimCount); + } else { + records.setRecordsTotal(input.getLength()); } - records.setRecordsTotal(input.getLength()); + records.setRecordsFiltered(referenceManifestRepository.count()); log.debug("Returning list of size: " + records.size()); diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java index 0a2e76ed..36cd752c 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java @@ -116,15 +116,12 @@ public class RimDatabasePageController extends PageController { if (pagedResult.hasContent()) { referenceDigestValues.addAll(pagedResult.getContent()); + referenceDigestValues.setRecordsTotal(pagedResult.getContent().size()); + } else { + referenceDigestValues.setRecordsTotal(input.getLength()); } - referenceDigestValues.setRecordsTotal(input.getLength()); referenceDigestValues.setRecordsFiltered(referenceDigestValueRepository.count()); -// FilteredRecordsList referenceDigestValues = -// OrderedListQueryDataTableAdapter.getOrderedList( -// referenceDigestValueRepository, -// input, orderColumnName, criteriaModifier, entityManager); - // might be able to get rid of this, maybe right a query that looks for not updated SupportReferenceManifest support; for (ReferenceDigestValue rdv : referenceDigestValues) { 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 e2a5f5db..a2a1ccec 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 @@ -126,8 +126,11 @@ public class ValidationReportsPageController extends PageController(records, input); From b0cd8e5fb9ac02e2f88406633a028672012b3dc2 Mon Sep 17 00:00:00 2001 From: iadgovuser26 Date: Fri, 13 Oct 2023 15:42:54 +0000 Subject: [PATCH 25/26] enabled mysql log on Ubuntu and fixed TLS config for DB --- package/scripts/db/db_create.sh | 16 +++++++++------- package/scripts/db/mysql_util.sh | 13 +++++++------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/package/scripts/db/db_create.sh b/package/scripts/db/db_create.sh index f576d2dc..fa7d2878 100755 --- a/package/scripts/db/db_create.sh +++ b/package/scripts/db/db_create.sh @@ -8,6 +8,7 @@ ################################################################################ LOG_FILE=$1 +DB_LOG_FILE="/var/log/mariadb/mariadb.log" PKI_PASS=$2 UNATTENDED=$3 RSA_PATH=rsa_3k_sha384_certs @@ -29,10 +30,6 @@ SSL_DB_CLIENT_CHAIN="/etc/hirs/certificates/HIRS/rsa_3k_sha384_certs/HIRS_rsa_3k SSL_DB_CLIENT_CERT="/etc/hirs/certificates/HIRS/rsa_3k_sha384_certs/HIRS_db_client_rsa_3k_sha384.pem"; SSL_DB_CLIENT_KEY="/etc/hirs/certificates/HIRS/rsa_3k_sha384_certs/HIRS_db_client_rsa_3k_sha384.key"; -touch $ACA_PROP_FILE -touch $LOG_FILE -touch $DB_SRV_CONF - # Make sure required paths exist mkdir -p /etc/hirs/aca/ mkdir -p /var/log/hirs/ @@ -45,13 +42,18 @@ source /etc/os-release if [ $ID = "ubuntu" ]; then DB_SRV_CONF="/etc/mysql/mariadb.conf.d/50-server.cnf" DB_CLIENT_CONF="/etc/mysql/mariadb.conf.d/50-client.cnf" + mkdir -p /var/log/mariadb >> /dev/null if [[ $(cat "$DB_SRV_CONF" | grep -c "log-error") < 1 ]]; then - echo log-error=/var/log/mysql/mysqld.log >> $DB_SRV_CONF - echo "ssl-cipher=TLSv1.3" >> $DB_SRV_CONF - echo "ssl=on" >> $DB_SRV_CONF + echo "log_error=/var/log/mariadb/mariadb.log" >> $DB_SRV_CONF + echo "tls_version = TLSv1.2,TLSv1.3" >> $DB_SRV_CONF fi fi +touch $ACA_PROP_FILE +touch $LOG_FILE +touch $DB_SRV_CONF +touch $DB_LOG_FILE + check_mysql_root_pwd () { # Check if DB root password needs to be obtained diff --git a/package/scripts/db/mysql_util.sh b/package/scripts/db/mysql_util.sh index 597ef306..03acbd0e 100755 --- a/package/scripts/db/mysql_util.sh +++ b/package/scripts/db/mysql_util.sh @@ -57,13 +57,12 @@ start_mysqlsd () { chown -R mysql:mysql /var/lib/mysql/ >> "$LOG_FILE" fi if [[ $PRINT_STATUS == "-p" ]]; then echo "Starting mysql..."; fi - touch /var/log/mariadb/mariadb.log - chown mysql:mysql /var/log/mariadb/mariadb.log >> "$LOG_FILE"; - /usr/bin/mysqld_safe & >> "$LOG_FILE"; - echo "Attempting to start mariadb" + /usr/bin/mysqld_safe --skip-syslog & >> "$LOG_FILE"; + chown -R mysql:mysql /var/lib/mysql/ >> "$LOG_FILE" + echo "Attempting to start mariadb" else #not a container systemctl enable $SQL_SERVICE & >> "$LOG_FILE"; - systemctl start $SQL_SERVICE & >> "$LOG_FILE"; + systemctl start $SQL_SERVICE & >> "$LOG_FILE"; fi else # mysql process is running # check if mysql service is running @@ -89,7 +88,8 @@ check_mysql () { if [ $DOCKER_CONTAINER = true ]; then if [[ $(pgrep -c -u mysql $PROCESS ) -eq 0 ]]; then echo "mariadb not running , attempting to restart" - /usr/bin/mysqld_safe & >> "$LOG_FILE" + chown mysql:mysql /var/log/mariadb/mariadb.log >> "$LOG_FILE"; + /usr/bin/mysqld_safe --skip-syslog & >> "$LOG_FILE" fi else # not in a contianer DB_STATUS=$(systemctl status mysql |grep 'running' | wc -l ) @@ -113,6 +113,7 @@ check_mysql () { done if [[ $count -gt 20 ]]; then echo "Timed out waiting for Mariadb to respond" + exit 1; else echo "Mariadb started" fi From 5ea0aa88dde5acb6dade0c4892a9b8dfa38902ab Mon Sep 17 00:00:00 2001 From: iadgovuser26 Date: Fri, 13 Oct 2023 16:38:34 +0000 Subject: [PATCH 26/26] fixed call to mysqld_safe --- package/scripts/db/mysql_util.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/scripts/db/mysql_util.sh b/package/scripts/db/mysql_util.sh index 03acbd0e..08d62daf 100755 --- a/package/scripts/db/mysql_util.sh +++ b/package/scripts/db/mysql_util.sh @@ -57,7 +57,7 @@ start_mysqlsd () { chown -R mysql:mysql /var/lib/mysql/ >> "$LOG_FILE" fi if [[ $PRINT_STATUS == "-p" ]]; then echo "Starting mysql..."; fi - /usr/bin/mysqld_safe --skip-syslog & >> "$LOG_FILE"; + /usr/bin/mysqld_safe --skip-syslog >> "$LOG_FILE" & chown -R mysql:mysql /var/lib/mysql/ >> "$LOG_FILE" echo "Attempting to start mariadb" else #not a container @@ -89,7 +89,7 @@ check_mysql () { if [[ $(pgrep -c -u mysql $PROCESS ) -eq 0 ]]; then echo "mariadb not running , attempting to restart" chown mysql:mysql /var/log/mariadb/mariadb.log >> "$LOG_FILE"; - /usr/bin/mysqld_safe --skip-syslog & >> "$LOG_FILE" + /usr/bin/mysqld_safe --skip-syslog >> "$LOG_FILE" & fi else # not in a contianer DB_STATUS=$(systemctl status mysql |grep 'running' | wc -l ) @@ -179,5 +179,5 @@ mysqld_reboot () { mysql -u root --password=$DB_ADMIN_PWD -e "SHUTDOWN" sleep 2 check_for_container - start_mysqlsd + start_mysqlsd >> "$LOG_FILE"; }