Initial changes to refactor highlighting the failed components

This commit is contained in:
Cyrus 2024-02-14 16:24:01 -05:00
parent 19a10a612b
commit 12e6f48550
8 changed files with 89 additions and 37 deletions

View File

@ -12,5 +12,5 @@ import java.util.UUID;
public interface ComponentResultRepository extends JpaRepository<ComponentResult, UUID> { public interface ComponentResultRepository extends JpaRepository<ComponentResult, UUID> {
@Query(value = "SELECT * FROM ComponentResult where certificateId = ?1", nativeQuery = true) @Query(value = "SELECT * FROM ComponentResult where certificateId = ?1", nativeQuery = true)
List<ComponentResult> getComponentResultsByCertificate(UUID certificateId); List<ComponentResult> findByCertificateId(UUID certificateId);
} }

View File

@ -115,8 +115,7 @@ public class Device extends AbstractEntity {
public String toString() { public String toString() {
return String.format("Device Name: %s%nStatus: %s%nSummary: %s%n", return String.format("Device Name: %s%nStatus: %s%nSummary: %s%n",
name, healthStatus.getStatus(), name, healthStatus.getStatus(),
supplyChainValidationStatus.toString(), supplyChainValidationStatus.toString());
summaryId);
} }
@Override @Override

View File

@ -1,6 +1,8 @@
package hirs.attestationca.persist.entity.userdefined.certificate; package hirs.attestationca.persist.entity.userdefined.certificate;
import hirs.attestationca.persist.entity.AbstractEntity; import hirs.attestationca.persist.entity.AbstractEntity;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentClass;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.AttributeStatus;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -10,6 +12,10 @@ import lombok.NoArgsConstructor;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
/**
* A component result is a DO to hold the status of a component validation status. This will
* also be used to display this common information on the certificate details page.
*/
@EqualsAndHashCode(callSuper=false) @EqualsAndHashCode(callSuper=false)
@Getter @Getter
@Entity @Entity
@ -17,22 +23,71 @@ import java.util.UUID;
public class ComponentResult extends AbstractEntity { public class ComponentResult extends AbstractEntity {
private UUID certificateId; private UUID certificateId;
private int componentHash;
private String expected; private String expected;
private String actual; private String actual;
private boolean mismatched; private boolean mismatched;
public ComponentResult(final UUID certificateId, final int componentHash, // embedded component info
private String manufacturer;
private String model;
private String serialNumber;
private String revisionNumber;
private boolean fieldReplaceable;
private ComponentClass 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
*/
public ComponentResult(final UUID certificateId,
final String expected, final String actual) { final String expected, final String actual) {
this.certificateId = certificateId; this.certificateId = certificateId;
this.componentHash = componentHash;
this.expected = expected; this.expected = expected;
this.actual = actual; this.actual = actual;
this.mismatched = Objects.equals(expected, actual); this.mismatched = Objects.equals(expected, actual);
} }
/**
* The string method for log entries.
* @return a string for the component result
*/
public String toString() { public String toString() {
return String.format("ComponentResult[%d]: expected=[%s] actual=[%s]", return String.format("ComponentResult: expected=[%s] actual=[%s]",
componentHash, expected, actual); expected, actual);
} }
} }

View File

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

View File

@ -43,14 +43,14 @@ import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS;
@Log4j2 @Log4j2
public class CertificateAttributeScvValidator extends SupplyChainCredentialValidator { public class CertificateAttributeScvValidator extends SupplyChainCredentialValidator {
private static List<ComponentResult> componentResultList = new LinkedList<>(); private static Map<ComponentIdentifier, List<ComponentResult>> componentResultMap = new HashMap<>();
/** /**
* Getter for the list of components to verify. * Getter for the list of components to verify.
* @return a collection of components * @return a collection of components
*/ */
public static List<ComponentResult> getComponentResultList() { public static Map<ComponentIdentifier, List<ComponentResult>> getComponentResultMap() {
return Collections.unmodifiableList(componentResultList); return Collections.unmodifiableMap(componentResultMap);
} }
/** /**
@ -881,6 +881,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
final ComponentIdentifier pcComponent, final ComponentIdentifier pcComponent,
final ComponentInfo potentialMatch) { final ComponentInfo potentialMatch) {
boolean matchesSoFar = true; boolean matchesSoFar = true;
List<ComponentResult> componentResultList = new LinkedList<>();
matchesSoFar &= isMatchOrEmptyInPlatformCert( matchesSoFar &= isMatchOrEmptyInPlatformCert(
potentialMatch.getComponentManufacturer(), potentialMatch.getComponentManufacturer(),
@ -888,7 +889,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
); );
if (matchesSoFar) { if (matchesSoFar) {
componentResultList.add(new ComponentResult(certificateId, pcComponent.hashCode(), componentResultList.add(new ComponentResult(certificateId,
potentialMatch.getComponentSerial(), potentialMatch.getComponentSerial(),
pcComponent.getComponentSerial().getString())); pcComponent.getComponentSerial().getString()));
} }
@ -899,7 +900,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
); );
if (matchesSoFar) { if (matchesSoFar) {
componentResultList.add(new ComponentResult(certificateId, pcComponent.hashCode(), componentResultList.add(new ComponentResult(certificateId,
potentialMatch.getComponentSerial(), potentialMatch.getComponentSerial(),
pcComponent.getComponentSerial().getString())); pcComponent.getComponentSerial().getString()));
} }
@ -910,7 +911,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
); );
if (matchesSoFar) { if (matchesSoFar) {
componentResultList.add(new ComponentResult(certificateId, pcComponent.hashCode(), componentResultList.add(new ComponentResult(certificateId,
potentialMatch.getComponentSerial(), potentialMatch.getComponentSerial(),
pcComponent.getComponentSerial().getString())); pcComponent.getComponentSerial().getString()));
} }
@ -921,15 +922,16 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
); );
if (matchesSoFar) { if (matchesSoFar) {
componentResultList.add(new ComponentResult(certificateId, pcComponent.hashCode(), componentResultList.add(new ComponentResult(certificateId,
potentialMatch.getComponentSerial(), potentialMatch.getComponentSerial(),
pcComponent.getComponentSerial().getString())); pcComponent.getComponentSerial().getString()));
} }
componentResultMap.put(pcComponent, componentResultList);
return matchesSoFar; return matchesSoFar;
} }
/** /**
* Checks if the fields in the potentialMatch match the fields in the pcComponent, * Checks if the fields in the potentialMatch match the fields in the pcComponent,
* or if the relevant field in the pcComponent is empty. * or if the relevant field in the pcComponent is empty.

View File

@ -26,7 +26,7 @@ public class CredentialValidator extends SupplyChainCredentialValidator {
* Checks if the endorsement credential is valid. * Checks if the endorsement credential is valid.
* *
* @param ec the endorsement credential to verify. * @param ec the endorsement credential to verify.
* @param trustStore trust store holding trusted trusted certificates. * @param trustStore trust store holding trusted certificates.
* @param acceptExpired whether or not to accept expired and not yet valid certificates * @param acceptExpired whether or not to accept expired and not yet valid certificates
* as valid. * as valid.
* @return the result of the validation. * @return the result of the validation.

View File

@ -93,15 +93,13 @@ public class SupplyChainCredentialValidator {
} else if (trustStore.size() == 0) { } else if (trustStore.size() == 0) {
throw new SupplyChainValidatorException("Truststore is empty"); throw new SupplyChainValidatorException("Truststore is empty");
} }
} catch (KeyStoreException e) { } catch (KeyStoreException ksEx) {
log.error("Error accessing trust store: " + e.getMessage()); log.error("Error accessing trust store: " + ksEx.getMessage());
} }
try { try {
Set<X509Certificate> trustedCerts = new HashSet<>(); Set<X509Certificate> trustedCerts = new HashSet<>();
Enumeration<String> alias = trustStore.aliases(); Enumeration<String> alias = trustStore.aliases();
while (alias.hasMoreElements()) { while (alias.hasMoreElements()) {
trustedCerts.add((X509Certificate) trustStore.getCertificate(alias.nextElement())); trustedCerts.add((X509Certificate) trustStore.getCertificate(alias.nextElement()));
} }
@ -111,8 +109,8 @@ public class SupplyChainCredentialValidator {
log.error("Cert chain could not be validated"); log.error("Cert chain could not be validated");
} }
return certChainValidated; return certChainValidated;
} catch (KeyStoreException e) { } catch (KeyStoreException ksEx) {
throw new SupplyChainValidatorException("Error with the trust store", e); throw new SupplyChainValidatorException("Error with the trust store", ksEx);
} }
} }
@ -139,8 +137,8 @@ public class SupplyChainCredentialValidator {
} else if (trustStore.size() == 0) { } else if (trustStore.size() == 0) {
throw new SupplyChainValidatorException("Truststore is empty"); throw new SupplyChainValidatorException("Truststore is empty");
} }
} catch (KeyStoreException e) { } catch (KeyStoreException ksEx) {
log.error("Error accessing trust store: " + e.getMessage()); log.error("Error accessing trust store: " + ksEx.getMessage());
} }
try { try {
@ -152,9 +150,9 @@ public class SupplyChainCredentialValidator {
} }
return validateCertChain(cert, trustedCerts).isEmpty(); return validateCertChain(cert, trustedCerts).isEmpty();
} catch (KeyStoreException e) { } catch (KeyStoreException ksEx) {
log.error("Error accessing keystore", e); log.error("Error accessing keystore", ksEx);
throw new SupplyChainValidatorException("Error with the trust store", e); throw new SupplyChainValidatorException("Error with the trust store", ksEx);
} }
} }
@ -498,10 +496,10 @@ public class SupplyChainCredentialValidator {
PublicKey key = cert.getPublicKey(); PublicKey key = cert.getPublicKey();
cert.verify(key); cert.verify(key);
return true; return true;
} catch (SignatureException | InvalidKeyException e) { } catch (SignatureException | InvalidKeyException ex) {
return false; return false;
} catch (CertificateException | NoSuchAlgorithmException | NoSuchProviderException e) { } catch (CertificateException | NoSuchAlgorithmException | NoSuchProviderException ex) {
log.error("Exception occurred while checking if cert is self-signed", e); log.error("Exception occurred while checking if cert is self-signed", ex);
return false; return false;
} }
} }

View File

@ -372,8 +372,9 @@ public final class CertificateStringMapBuilder {
for (ComponentResult componentResult : componentResultRepository.findAll()) { for (ComponentResult componentResult : componentResultRepository.findAll()) {
if (componentResult.getCertificateId() if (componentResult.getCertificateId()
.equals(certificate.getId())) { .equals(certificate.getId())) {
results.put(componentResult.getComponentHash(), // results.put(componentResult.getComponentHash(),
componentResult.getExpected()); // componentResult.getExpected());
log.error(componentResult.toString());
} }
} }