These changes are set up to save component identifier to the db and

display.  This push it to test functionality
This commit is contained in:
Cyrus 2024-02-15 15:58:11 -05:00
parent 12e6f48550
commit c674510a8d
10 changed files with 134 additions and 160 deletions

View File

@ -2,15 +2,15 @@ package hirs.attestationca.persist.entity.manager;
import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
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> {
@Query(value = "SELECT * FROM ComponentResult where certificateId = ?1", nativeQuery = true)
List<ComponentResult> findByCertificateId(UUID certificateId);
List<ComponentResult> findByCertificateSerialNumber(BigInteger certificateSerialNumber);
List<ComponentResult> findByCertificateSerialNumberAndMismatched(BigInteger certificateSerialNumber, boolean mismatched);
}

View File

@ -1,16 +1,16 @@
package hirs.attestationca.persist.entity.userdefined.certificate;
import hirs.attestationca.persist.entity.AbstractEntity;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentClass;
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;
import jakarta.persistence.Entity;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.Objects;
import java.util.UUID;
import java.math.BigInteger;
/**
* A component result is a DO to hold the status of a component validation status. This will
@ -22,7 +22,7 @@ import java.util.UUID;
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ComponentResult extends AbstractEntity {
private UUID certificateId;
private BigInteger certificateSerialNumber;
private String expected;
private String actual;
private boolean mismatched;
@ -33,53 +33,30 @@ public class ComponentResult extends AbstractEntity {
private String serialNumber;
private String revisionNumber;
private boolean fieldReplaceable;
private ComponentClass componentClass;
// this is a string because component class doesn't inherit serializable.
private String componentClass;
private AttributeStatus attributeStatus;
/**
* default constructor.
* @param certificateId
* @param expected
* @param actual
* @param manufacturer
* @param model
* @param serialNumber
* @param revisionNumber
* @param fieldReplaceable
* @param componentClass
* @param attributeStatus
*/
public ComponentResult(final UUID certificateId,
final String expected, final String actual,
final String manufacturer, final String model,
final String serialNumber, final String revisionNumber,
final boolean fieldReplaceable, final ComponentClass componentClass,
final AttributeStatus attributeStatus) {
this.certificateId = certificateId;
this.expected = expected;
this.actual = actual;
this.mismatched = Objects.equals(expected, actual);
this.manufacturer = manufacturer;
this.model = model;
this.serialNumber = serialNumber;
this.revisionNumber = revisionNumber;
this.fieldReplaceable = fieldReplaceable;
this.componentClass = componentClass;
this.attributeStatus = attributeStatus;
}
/**
* default constructor.
* @param certificateId
* @param expected
* @param actual
* Default constructor.
* @param certificateSerialNumber associated platform certificate serial number.
* @param componentIdentifier object with information from the platform certificate components.
*/
public ComponentResult(final UUID certificateId,
final String expected, final String actual) {
this.certificateId = certificateId;
this.expected = expected;
this.actual = actual;
this.mismatched = Objects.equals(expected, actual);
public ComponentResult(final BigInteger certificateSerialNumber,
final ComponentIdentifier componentIdentifier) {
this.certificateSerialNumber = certificateSerialNumber;
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();
// V2 fields
if (componentIdentifier.isVersion2()) {
ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) componentIdentifier;
this.componentClass = ciV2.getComponentClass().toString();
this.attributeStatus = ciV2.getAttributeStatus();
}
}
/**
@ -87,7 +64,13 @@ public class ComponentResult extends AbstractEntity {
* @return a string for the component result
*/
public String toString() {
return String.format("ComponentResult: expected=[%s] actual=[%s]",
expected, actual);
if (mismatched) {
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);
}
}
}

View File

@ -483,7 +483,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
Map<String, Object> attributes = new HashMap<>();
ASN1Sequence attributeSequence;
// Check all attributes for Platform Configuration
for (ASN1Encodable enc: getAttributeCertificate().getAcinfo().getAttributes().toArray()) {
for (ASN1Encodable enc : getAttributeCertificate().getAcinfo().getAttributes().toArray()) {
Attribute attr = Attribute.getInstance(enc);
attributeSequence
= ASN1Sequence.getInstance(attr.getAttrValues().getObjectAt(0));

View File

@ -25,7 +25,7 @@ public class PlatformConfigurationV1 extends PlatformConfiguration {
/**
* Constructor given the SEQUENCE that contains Platform Configuration.
* @param sequence containing the the Platform Configuration.
* @param sequence containing the Platform Configuration.
* @throws IllegalArgumentException if there was an error on the parsing
*/
public PlatformConfigurationV1(final ASN1Sequence sequence) throws IllegalArgumentException {

View File

@ -159,7 +159,7 @@ public class AbstractProcessor {
* @param endorsementCredential an endorsement credential to check if platform credentials
* exist
* @param certificateRepository db connector from certificates
* @return the Set of Platform Credentials, if they exist, an empty set otherwise
* @return the List of Platform Credentials, if they exist, an empty set otherwise
*/
protected List<PlatformCredential> parsePcsFromIdentityClaim(
final ProvisionerTpm2.IdentityClaim identityClaim,

View File

@ -302,7 +302,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
pcrValues = dv.getPcrslist().toStringUtf8();
}
// check for RIM Base and Support files, if they don't exists in the database, load them
// check for RIM Base and Support files, if they don't exist in the database, load them
String defaultClientName = String.format("%s_%s",
dv.getHw().getManufacturer(),
dv.getHw().getProductName());
@ -314,7 +314,6 @@ public class IdentityClaimProcessor extends AbstractProcessor {
Pattern pattern = Pattern.compile("([^\\s]+(\\.(?i)(rimpcr|rimel|bin|log))$)");
Matcher matcher;
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
// List<ReferenceManifest> listOfSavedRims = new LinkedList<>();
if (dv.getLogfileCount() > 0) {
for (ByteString logFile : dv.getLogfileList()) {
@ -424,11 +423,9 @@ public class IdentityClaimProcessor extends AbstractProcessor {
dbSupport.setUpdated(true);
dbSupport.setAssociatedRim(dbBaseRim.getId());
this.referenceManifestRepository.save(dbSupport);
// listOfSavedRims.add(dbSupport);
}
}
this.referenceManifestRepository.save(dbBaseRim);
// listOfSavedRims.add(dbBaseRim);
}
}

View File

@ -126,7 +126,6 @@ public class ValidationService {
pc.setComponentFailures(result.getAdditionalInfo());
pc.setComponentFailureMessage(result.getMessage());
certificateRepository.save(pc);
log.error(CertificateAttributeScvValidator.getComponentResultMap().size());
}
return buildValidationRecord(validationType, AppraisalStatus.Status.FAIL,
result.getMessage(), pc, Level.WARN);

View File

@ -2,7 +2,6 @@ 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;
@ -43,16 +42,6 @@ import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS;
@Log4j2
public class CertificateAttributeScvValidator extends SupplyChainCredentialValidator {
private static Map<ComponentIdentifier, List<ComponentResult>> componentResultMap = new HashMap<>();
/**
* Getter for the list of components to verify.
* @return a collection of components
*/
public static Map<ComponentIdentifier, List<ComponentResult>> getComponentResultMap() {
return Collections.unmodifiableMap(componentResultMap);
}
/**
* Checks if the delta credential's attributes are valid.
* @param deltaPlatformCredential the delta credential to verify
@ -881,53 +870,53 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
final ComponentIdentifier pcComponent,
final ComponentInfo potentialMatch) {
boolean matchesSoFar = true;
List<ComponentResult> componentResultList = new LinkedList<>();
// List<ComponentResult> componentResultList = new LinkedList<>();
matchesSoFar &= isMatchOrEmptyInPlatformCert(
potentialMatch.getComponentManufacturer(),
pcComponent.getComponentManufacturer()
);
if (matchesSoFar) {
componentResultList.add(new ComponentResult(certificateId,
potentialMatch.getComponentSerial(),
pcComponent.getComponentSerial().getString()));
}
// if (matchesSoFar) {
// componentResultList.add(new ComponentResult(certificateId,
// potentialMatch.getComponentSerial(),
// pcComponent.getComponentSerial().getString()));
// }
matchesSoFar &= isMatchOrEmptyInPlatformCert(
potentialMatch.getComponentModel(),
pcComponent.getComponentModel()
);
if (matchesSoFar) {
componentResultList.add(new ComponentResult(certificateId,
potentialMatch.getComponentSerial(),
pcComponent.getComponentSerial().getString()));
}
// if (matchesSoFar) {
// componentResultList.add(new ComponentResult(certificateId,
// potentialMatch.getComponentSerial(),
// pcComponent.getComponentSerial().getString()));
// }
matchesSoFar &= isMatchOrEmptyInPlatformCert(
potentialMatch.getComponentSerial(),
pcComponent.getComponentSerial()
);
if (matchesSoFar) {
componentResultList.add(new ComponentResult(certificateId,
potentialMatch.getComponentSerial(),
pcComponent.getComponentSerial().getString()));
}
// if (matchesSoFar) {
// componentResultList.add(new ComponentResult(certificateId,
// potentialMatch.getComponentSerial(),
// pcComponent.getComponentSerial().getString()));
// }
matchesSoFar &= isMatchOrEmptyInPlatformCert(
potentialMatch.getComponentRevision(),
pcComponent.getComponentRevision()
);
if (matchesSoFar) {
componentResultList.add(new ComponentResult(certificateId,
potentialMatch.getComponentSerial(),
pcComponent.getComponentSerial().getString()));
}
// if (matchesSoFar) {
// componentResultList.add(new ComponentResult(certificateId,
// potentialMatch.getComponentSerial(),
// pcComponent.getComponentSerial().getString()));
// }
componentResultMap.put(pcComponent, componentResultList);
// componentResultMap.put(pcComponent, componentResultList);
return matchesSoFar;
}

View File

@ -4,16 +4,10 @@ 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.CACredentialRepository;
import hirs.attestationca.persist.entity.manager.CertificateRepository;
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.manager.*;
import hirs.attestationca.persist.entity.userdefined.Certificate;
import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential;
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.*;
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;
@ -83,6 +77,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
private CertificateAuthorityCredential certificateAuthorityCredential;
private final CertificateRepository certificateRepository;
private final PlatformCertificateRepository platformCertificateRepository;
private final ComponentResultRepository componentResultRepository;
private final EndorsementCredentialRepository endorsementCredentialRepository;
private final IssuedCertificateRepository issuedCertificateRepository;
private final CACredentialRepository caCredentialRepository;
@ -100,23 +95,26 @@ public class CertificatePageController extends PageController<NoPageParams> {
/**
* Constructor providing the Page's display and routing specification.
*
* @param certificateRepository the general certificate manager
* @param platformCertificateRepository the platform credential manager
* @param certificateRepository the general certificate manager
* @param platformCertificateRepository the platform credential manager
* @param componentResultRepository the component result repo
* @param endorsementCredentialRepository the endorsement credential manager
* @param issuedCertificateRepository the issued certificate manager
* @param caCredentialRepository the ca credential manager
* @param acaCertificate the ACA's X509 certificate
* @param issuedCertificateRepository the issued certificate manager
* @param caCredentialRepository the ca credential manager
* @param acaCertificate the ACA's X509 certificate
*/
@Autowired
public CertificatePageController(final CertificateRepository certificateRepository,
final PlatformCertificateRepository platformCertificateRepository,
final ComponentResultRepository componentResultRepository,
final EndorsementCredentialRepository endorsementCredentialRepository,
final IssuedCertificateRepository issuedCertificateRepository,
final CACredentialRepository caCredentialRepository,
final X509Certificate acaCertificate) {
final X509Certificate acaCertificate) {
super(Page.TRUST_CHAIN);
this.certificateRepository = certificateRepository;
this.platformCertificateRepository = platformCertificateRepository;
this.componentResultRepository = componentResultRepository;
this.endorsementCredentialRepository = endorsementCredentialRepository;
this.issuedCertificateRepository = issuedCertificateRepository;
this.caCredentialRepository = caCredentialRepository;
@ -135,8 +133,8 @@ public class CertificatePageController extends PageController<NoPageParams> {
* Returns the path for the view and the data model for the page.
*
* @param params The object to map url parameters into.
* @param model The data model for the request. Can contain data from
* redirect.
* @param model The data model for the request. Can contain data from
* redirect.
* @return the path for the view and data model for the page.
*/
@Override
@ -149,9 +147,9 @@ public class CertificatePageController extends PageController<NoPageParams> {
* Returns the path for the view and the data model for the page.
*
* @param certificateType String containing the certificate type
* @param params The object to map url parameters into.
* @param model The data model for the request. Can contain data from
* redirect.
* @param params The object to map url parameters into.
* @param model The data model for the request. Can contain data from
* redirect.
* @return the path for the view and data model for the page.
*/
@RequestMapping("/{certificateType}")
@ -192,7 +190,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
* with the records.
*
* @param certificateType String containing the certificate type
* @param input the DataTables search/query parameters
* @param input the DataTables search/query parameters
* @return the data table
*/
@ResponseBody
@ -320,8 +318,8 @@ public class CertificatePageController extends PageController<NoPageParams> {
* Upload and processes a credential.
*
* @param certificateType String containing the certificate type
* @param files the files to process
* @param attr the redirection attributes
* @param files the files to process
* @param attr the redirection attributes
* @return the redirection view
* @throws URISyntaxException if malformed URI
*/
@ -357,9 +355,9 @@ public class CertificatePageController extends PageController<NoPageParams> {
* Archives (soft delete) the credential.
*
* @param certificateType String containing the certificate type
* @param id the UUID of the cert to delete
* @param attr RedirectAttributes used to forward data back to the original
* page.
* @param id the UUID of the cert to delete
* @param attr RedirectAttributes used to forward data back to the original
* page.
* @return redirect to this page
* @throws URISyntaxException if malformed URI
*/
@ -426,9 +424,9 @@ public class CertificatePageController extends PageController<NoPageParams> {
* for download.
*
* @param certificateType String containing the certificate type
* @param id the UUID of the cert to download
* @param response the response object (needed to update the header with the
* file name)
* @param id the UUID of the cert to download
* @param response the response object (needed to update the header with the
* file name)
* @throws java.io.IOException when writing to response output stream
*/
@RequestMapping(value = "/{certificateType}/download", method = RequestMethod.GET)
@ -475,8 +473,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
* stream for download.
*
* @param response the response object (needed to update the header with the
* file name)
*
* file name)
* @throws java.io.IOException when writing to response output stream
*/
@ResponseBody
@ -497,7 +494,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
* for download in bulk.
*
* @param response the response object (needed to update the header with the
* file name)
* file name)
* @throws java.io.IOException when writing to response output stream
*/
@RequestMapping(value = "/trust-chain/bulk", method = RequestMethod.GET)
@ -528,7 +525,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
* for download in bulk.
*
* @param response the response object (needed to update the header with the
* file name)
* file name)
* @throws java.io.IOException when writing to response output stream
*/
@RequestMapping(value = "/platform-credentials/bulk", method = RequestMethod.GET)
@ -560,7 +557,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
* for download in bulk.
*
* @param response the response object (needed to update the header with the
* file name)
* file name)
* @throws java.io.IOException when writing to response output stream
*/
@RequestMapping(value = "/issued-certificates/bulk", method = RequestMethod.GET)
@ -592,7 +589,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
* for download in bulk.
*
* @param response the response object (needed to update the header with the
* file name)
* file name)
* @throws java.io.IOException when writing to response output stream
*/
@RequestMapping(value = "/endorsement-key-credentials/bulk", method = RequestMethod.GET)
@ -619,8 +616,8 @@ public class CertificatePageController extends PageController<NoPageParams> {
}
private ZipOutputStream bulkDownload(final ZipOutputStream zipOut,
final List<Certificate> certificates,
final String singleFileName) throws IOException {
final List<Certificate> certificates,
final String singleFileName) throws IOException {
String zipFileName;
// get all files
for (Certificate certificate : certificates) {
@ -729,7 +726,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
* Gets the certificate by the platform serial number.
*
* @param certificateType String containing the certificate type
* @param serialNumber the platform serial number
* @param serialNumber the platform serial number
* @return the certificate or null if none is found
*/
private List<PlatformCredential> getCertificateByBoardSN(
@ -737,7 +734,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
final String serialNumber) {
List<PlatformCredential> associatedCertificates = new LinkedList<>();
if (serialNumber != null){
if (serialNumber != null) {
switch (certificateType) {
case PLATFORMCREDENTIAL:
associatedCertificates.addAll(this.certificateRepository
@ -754,8 +751,8 @@ public class CertificatePageController extends PageController<NoPageParams> {
* with error messages if parsing fails.
*
* @param certificateType String containing the certificate type
* @param file the file being uploaded from the portal
* @param messages contains any messages that will be display on the page
* @param file the file being uploaded from the portal
* @param messages contains any messages that will be display on the page
* @return the parsed certificate or null if parsing failed.
*/
private Certificate parseCertificate(
@ -793,7 +790,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
storeCertificate(
certificateType,
file.getOriginalFilename(),
messages, new CertificateAuthorityCredential(((java.security.cert.Certificate)i.next()).getEncoded()));
messages, new CertificateAuthorityCredential(((java.security.cert.Certificate) i.next()).getEncoded()));
}
// stop the main thread from saving/storing
@ -841,11 +838,10 @@ public class CertificatePageController extends PageController<NoPageParams> {
* Store the given certificate in the database.
*
* @param certificateType String containing the certificate type
* @param fileName contain the name of the file of the certificate to
* be stored
* @param messages contains any messages that will be display on the page
* @param certificate the certificate to store
* @return the messages for the page
* @param fileName contain the name of the file of the certificate to
* be stored
* @param messages contains any messages that will be display on the page
* @param certificate the certificate to store
*/
private void storeCertificate(
final String certificateType,
@ -877,19 +873,16 @@ public class CertificatePageController extends PageController<NoPageParams> {
List<PlatformCredential> sharedCertificates = getCertificateByBoardSN(
certificateType,
platformCertificate.getPlatformSerial());
if (sharedCertificates != null) {
for (PlatformCredential pc : sharedCertificates) {
if (pc.isPlatformBase()) {
final String failMessage = "Storing certificate failed: "
+ "platform credential "
+ "chain (" + pc.getPlatformSerial()
+ ") base already exists in this chain ("
+ fileName + ")";
messages.addError(failMessage);
log.error(failMessage);
return;
}
for (PlatformCredential pc : sharedCertificates) {
if (pc.isPlatformBase()) {
final String failMessage = "Storing certificate failed: "
+ "platform credential "
+ "chain (" + pc.getPlatformSerial()
+ ") base already exists in this chain ("
+ fileName + ")";
messages.addError(failMessage);
log.error(failMessage);
return;
}
}
} /**else {
@ -913,6 +906,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
}
this.certificateRepository.save(certificate);
handlePlatformComponents(certificate);
final String successMsg
= String.format("New certificate successfully uploaded (%s): ", fileName);
@ -958,4 +952,21 @@ public class CertificatePageController extends PageController<NoPageParams> {
messages.addError(failMessage);
log.error(failMessage);
}
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()) {
componentResult = new ComponentResult(certificate.getSerialNumber(),
componentIdentifier);
componentResultRepository.save(componentResult);
componentResults++;
}
}
return componentResults;
}
}

View File

@ -368,17 +368,12 @@ public final class CertificateStringMapBuilder {
if (!certificate.getComponentFailures().isEmpty()) {
data.put("failures", certificate.getComponentFailures());
HashMap<Integer, String> results = new HashMap<>();
// HashMap<Integer, String> results = new HashMap<>();
for (ComponentResult componentResult : componentResultRepository.findAll()) {
if (componentResult.getCertificateId()
.equals(certificate.getId())) {
// results.put(componentResult.getComponentHash(),
// componentResult.getExpected());
log.error(componentResult.toString());
}
log.error(componentResult.toString());
}
data.put("componentResults", results);
// data.put("componentResults", results);
data.put("failureMessages", certificate.getComponentFailures());
}