These changes update the code to create component results for the

provisioning process.
This commit is contained in:
Cyrus 2024-02-16 09:50:32 -05:00
parent c674510a8d
commit c135d17934
8 changed files with 114 additions and 70 deletions

View File

@ -111,7 +111,7 @@ public abstract class AttestationCertificateAuthority {
certificateRepository, deviceRepository,
privateKey, acaCertificate, validDays, tpm2ProvisionerStateRepository);
this.identityClaimHandler = new IdentityClaimProcessor(supplyChainValidationService,
certificateRepository, referenceManifestRepository,
certificateRepository, componentResultRepository, referenceManifestRepository,
referenceDigestValueRepository,
deviceRepository, tpm2ProvisionerStateRepository, policyRepository);
}

View File

@ -4,13 +4,12 @@ import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.math.BigInteger;
import java.util.List;
import java.util.UUID;
@Repository
public interface ComponentResultRepository extends JpaRepository<ComponentResult, UUID> {
List<ComponentResult> findByCertificateSerialNumber(BigInteger certificateSerialNumber);
List<ComponentResult> findByCertificateSerialNumberAndMismatched(BigInteger certificateSerialNumber, boolean mismatched);
List<ComponentResult> findByBoardSerialNumber(String boardSerialNumber);
List<ComponentResult> findByCertificateSerialNumberAndMismatched(String boardSerialNumber, boolean mismatched);
}

View File

@ -1,6 +1,7 @@
package hirs.attestationca.persist.entity.userdefined.certificate;
import hirs.attestationca.persist.entity.AbstractEntity;
import hirs.attestationca.persist.entity.ArchivableEntity;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentAddress;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.AttributeStatus;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
@ -9,8 +10,9 @@ import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.math.BigInteger;
import java.util.List;
/**
* A component result is a DO to hold the status of a component validation status. This will
@ -20,12 +22,13 @@ import java.math.BigInteger;
@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ComponentResult extends AbstractEntity {
public class ComponentResult extends ArchivableEntity {
private BigInteger certificateSerialNumber;
private String boardSerialNumber;
@Setter
private String expected;
@Setter
private String actual;
private boolean mismatched;
// embedded component info
private String manufacturer;
@ -36,41 +39,57 @@ public class ComponentResult extends AbstractEntity {
// this is a string because component class doesn't inherit serializable.
private String componentClass;
private AttributeStatus attributeStatus;
private List<ComponentAddress> componentAddress;
private boolean version2 = false;
private String certificateType;
/**
* Default constructor.
* @param certificateSerialNumber associated platform certificate serial number.
* @param boardSerialNumber associated platform certificate serial number.
* @param componentIdentifier object with information from the platform certificate components.
*/
public ComponentResult(final BigInteger certificateSerialNumber,
public ComponentResult(final String boardSerialNumber, final String certificateType,
final ComponentIdentifier componentIdentifier) {
this.certificateSerialNumber = certificateSerialNumber;
this.boardSerialNumber = boardSerialNumber;
this.certificateType = certificateType;
this.manufacturer = componentIdentifier.getComponentManufacturer().toString();
this.model = componentIdentifier.getComponentModel().toString();
this.serialNumber = componentIdentifier.getComponentSerial().toString();
this.revisionNumber = componentIdentifier.getComponentRevision().toString();
this.fieldReplaceable = componentIdentifier.getFieldReplaceable().isTrue();
if (componentIdentifier.getFieldReplaceable() != null) {
this.fieldReplaceable = componentIdentifier.getFieldReplaceable().isTrue();
}
this.componentAddress.addAll(componentIdentifier.getComponentAddress());
// V2 fields
if (componentIdentifier.isVersion2()) {
ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) componentIdentifier;
this.componentClass = ciV2.getComponentClass().toString();
this.attributeStatus = ciV2.getAttributeStatus();
this.version2 = true;
}
}
/**
* This getting is used to set the component display to red.
* @return result of expected and actual string.
*/
public boolean isMismatched() {
return this.actual.equals(this.expected);
}
/**
* The string method for log entries.
* @return a string for the component result
*/
public String toString() {
if (mismatched) {
if (isMismatched()) {
return String.format("ComponentResult: expected=[%s] actual=[%s]",
expected, actual);
} else {
return String.format("ComponentResult: certificateSerialNumber=[%s] "
+ "manufacturer=[%s] model=[%s] componentClass=[%s]",
certificateSerialNumber.toString(), manufacturer, model, componentClass);
boardSerialNumber, manufacturer, model, componentClass);
}
}
}

View File

@ -103,13 +103,13 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
/**
* Constructor given the SEQUENCE that contains Component Identifier.
* @param sequence containing the the component identifier
* @param sequence containing the component identifier
* @throws IllegalArgumentException if there was an error on the parsing
*/
public ComponentIdentifierV2(final ASN1Sequence sequence)
throws IllegalArgumentException {
super();
// Check if it have a valid number of identifiers
// Check if it has a valid number of identifiers
if (sequence.size() < MANDATORY_ELEMENTS) {
throw new IllegalArgumentException("Component identifier do not have required values.");
}

View File

@ -3,18 +3,22 @@ package hirs.attestationca.persist.provision;
import com.google.protobuf.ByteString;
import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
import hirs.attestationca.persist.entity.manager.DeviceRepository;
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.entity.tpm.TPM2ProvisionerState;
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.ReferenceManifest;
import hirs.attestationca.persist.entity.userdefined.SupplyChainValidationSummary;
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.certificate.attributes.ComponentIdentifier;
import hirs.attestationca.persist.entity.userdefined.info.FirmwareInfo;
import hirs.attestationca.persist.entity.userdefined.info.HardwareInfo;
import hirs.attestationca.persist.entity.userdefined.info.NetworkInfo;
@ -70,6 +74,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
private SupplyChainValidationService supplyChainValidationService;
private CertificateRepository certificateRepository;
private ComponentResultRepository componentResultRepository;
private ReferenceManifestRepository referenceManifestRepository;
private ReferenceDigestValueRepository referenceDigestValueRepository;
private DeviceRepository deviceRepository;
@ -81,6 +86,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
public IdentityClaimProcessor(
final SupplyChainValidationService supplyChainValidationService,
final CertificateRepository certificateRepository,
final ComponentResultRepository componentResultRepository,
final ReferenceManifestRepository referenceManifestRepository,
final ReferenceDigestValueRepository referenceDigestValueRepository,
final DeviceRepository deviceRepository,
@ -88,6 +94,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
final PolicyRepository policyRepository) {
this.supplyChainValidationService = supplyChainValidationService;
this.certificateRepository = certificateRepository;
this.componentResultRepository = componentResultRepository;
this.referenceManifestRepository = referenceManifestRepository;
this.referenceDigestValueRepository = referenceDigestValueRepository;
this.deviceRepository = deviceRepository;
@ -203,6 +210,15 @@ public class IdentityClaimProcessor extends AbstractProcessor {
platformCredentials.addAll(tempList);
}
// store component results objects
for (PlatformCredential platformCredential : platformCredentials) {
List<ComponentResult> componentResults = componentResultRepository
.findByBoardSerialNumber(platformCredential.getPlatformSerial());
if (componentResults.isEmpty()) {
handlePlatformComponents(platformCredential);
}
}
// perform supply chain validation
SupplyChainValidationSummary summary = supplyChainValidationService.validateSupplyChain(
endorsementCredential, platformCredentials, device);
@ -583,44 +599,35 @@ public class IdentityClaimProcessor extends AbstractProcessor {
log.error(String.format("Patching value does not exist (%s)",
patchedValue));
} else {
/**
* Until we get patch examples, this is WIP
*/
// WIP - Until we get patch examples
dbRdv.setPatched(true);
}
}
}
} catch (CertificateException cEx) {
log.error(cEx);
} catch (NoSuchAlgorithmException noSaEx) {
log.error(noSaEx);
} catch (IOException ioEx) {
log.error(ioEx);
} catch (CertificateException | NoSuchAlgorithmException | IOException ex) {
log.error(ex);
}
}
return true;
}
private int handlePlatformComponents(final Certificate certificate) {
PlatformCredential platformCredential;
int componentResults = 0;
if (certificate instanceof PlatformCredential) {
platformCredential = (PlatformCredential) certificate;
ComponentResult componentResult;
for (ComponentIdentifier componentIdentifier : platformCredential
.getComponentIdentifiers()) {
private List<PlatformCredential> getPlatformCredentials(final CertificateRepository certificateRepository,
final EndorsementCredential ec) {
List<PlatformCredential> 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 = 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());
componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
platformCredential.getPlatformChainType(),
componentIdentifier);
componentResultRepository.save(componentResult);
componentResults++;
}
}
return credentials;
return componentResults;
}
}

View File

@ -4,14 +4,22 @@ import hirs.attestationca.persist.CriteriaModifier;
import hirs.attestationca.persist.DBManagerException;
import hirs.attestationca.persist.DBServiceException;
import hirs.attestationca.persist.FilteredRecordsList;
import hirs.attestationca.persist.entity.manager.*;
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.EndorsementCredentialRepository;
import hirs.attestationca.persist.entity.manager.IssuedCertificateRepository;
import hirs.attestationca.persist.entity.manager.PlatformCertificateRepository;
import hirs.attestationca.persist.entity.userdefined.Certificate;
import hirs.attestationca.persist.entity.userdefined.certificate.*;
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.IssuedAttestationCertificate;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
import hirs.attestationca.persist.util.CredentialHelper;
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.PageMessages;
@ -393,9 +401,11 @@ public class CertificatePageController extends PageController<NoPageParams> {
if (!pc.isPlatformBase()) {
pc.archive("User requested deletion via UI of the base certificate");
certificateRepository.save(pc);
deleteComponentResults(pc.getPlatformSerial());
}
}
}
deleteComponentResults(platformCertificate.getPlatformSerial());
}
certificate.archive("User requested deletion via UI");
@ -930,6 +940,15 @@ public class CertificatePageController extends PageController<NoPageParams> {
existingCertificate.resetCreateTime();
this.certificateRepository.save(existingCertificate);
List<ComponentResult> componentResults = componentResultRepository
.findByBoardSerialNumber(((PlatformCredential) existingCertificate)
.getPlatformSerial());
for (ComponentResult componentResult : componentResults) {
componentResult.restore();
componentResult.resetCreateTime();
this.componentResultRepository.save(componentResult);
}
final String successMsg = String.format("Pre-existing certificate "
+ "found and unarchived (%s): ", fileName);
messages.addSuccess(successMsg);
@ -961,7 +980,9 @@ public class CertificatePageController extends PageController<NoPageParams> {
ComponentResult componentResult;
for (ComponentIdentifier componentIdentifier : platformCredential
.getComponentIdentifiers()) {
componentResult = new ComponentResult(certificate.getSerialNumber(),
componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
platformCredential.getPlatformChainType(),
componentIdentifier);
componentResultRepository.save(componentResult);
componentResults++;
@ -969,4 +990,14 @@ public class CertificatePageController extends PageController<NoPageParams> {
}
return componentResults;
}
private void deleteComponentResults(final String platformSerial) {
List<ComponentResult> componentResults = componentResultRepository
.findByBoardSerialNumber(platformSerial);
for (ComponentResult componentResult : componentResults) {
componentResult.archive();
componentResultRepository.save(componentResult);
}
}
}

View File

@ -5,14 +5,13 @@ import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
import hirs.attestationca.persist.entity.userdefined.Certificate;
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.IssuedAttestationCertificate;
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.PlatformConfiguration;
import hirs.utils.BouncyCastleUtils;
import hirs.attestationca.persist.util.PciIds;
import hirs.utils.BouncyCastleUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@ -25,7 +24,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
@ -365,17 +363,8 @@ public final class CertificateStringMapBuilder {
data.put("x509Version", certificate.getX509CredentialVersion());
//CPSuri
data.put("CPSuri", certificate.getCPSuri());
if (!certificate.getComponentFailures().isEmpty()) {
data.put("failures", certificate.getComponentFailures());
// HashMap<Integer, String> results = new HashMap<>();
for (ComponentResult componentResult : componentResultRepository.findAll()) {
log.error(componentResult.toString());
}
// data.put("componentResults", results);
data.put("failureMessages", certificate.getComponentFailures());
}
data.put("componentResults", componentResultRepository
.findByBoardSerialNumber(certificate.getPlatformSerial()));
//Get platform Configuration values and set map with it
PlatformConfiguration platformConfiguration = certificate.getPlatformConfiguration();

View File

@ -615,12 +615,11 @@
<div id="componentIdentifiercollapse" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne" aria-expanded="true">
<div class="panel-body">
<div id="componentIdentifier" class="row">
<c:forEach items="${initialData.componentsIdentifier}" var="component">
<c:set var="combined" value="${component.hashCode()}" scope="page"/>
<c:forEach items="${initialData.componentResults}" var="component">
<div class="component col col-md-4">
<div class="panel panel-default">
<c:choose>
<c:when test="${fn:contains(initialData.failures, combined)}">
<c:when test="${fn:${component.isMismatched()=='TRUE'}">
<div class="panel-heading" style="background-color: red; color: white">
</c:when>
<c:otherwise>
@ -638,16 +637,16 @@
</div>
<div class="panel-body">
<span class="fieldHeader">Manufacturer:</span>
<span class="fieldValue">${component.getComponentManufacturer()}</span><br/>
<span class="fieldValue">${component.getManufacturer()}</span><br/>
<span class="fieldHeader">Model:</span>
<span class="fieldValue">${component.getComponentModel()}</span><br/>
<c:if test="${not empty fn:trim(component.getComponentSerial())}">
<span class="fieldValue">${component.getModel()}</span><br/>
<c:if test="${not empty fn:trim(component.getSerialNumber())}">
<span class="fieldHeader">Serial Number:</span>
<span class="fieldValue">${component.getComponentSerial()}</span><br/>
<span class="fieldValue">${component.getSerialNumber()}</span><br/>
</c:if>
<c:if test="${not empty fn:trim(component.getComponentRevision())}">
<c:if test="${not empty fn:trim(component.getRevisionNumber())}">
<span class="fieldHeader">Revision:</span>
<span class="fieldValue">${component.getComponentRevision()}</span><br/>
<span class="fieldValue">${component.getRevisionNumber()}</span><br/>
</c:if>
<c:forEach items="${component.getComponentAddress()}" var="address">
<span class="fieldHeader">${address.getAddressTypeValue()} address:</span>