Merge pull request #725 from nsacyber/v3_issue-723

[#723] Update Provisioning for Version value
This commit is contained in:
Cyrus 2024-03-06 11:37:46 -05:00 committed by GitHub
commit ac093d3ecf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 1124 additions and 478 deletions

View File

@ -1,6 +1,7 @@
package hirs.attestationca.persist;
import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.manager.ComponentInfoRepository;
import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
import hirs.attestationca.persist.entity.manager.DeviceRepository;
import hirs.attestationca.persist.entity.manager.IssuedCertificateRepository;
@ -52,6 +53,7 @@ public abstract class AttestationCertificateAuthority {
private Integer validDays = 1;
private final ComponentResultRepository componentResultRepository;
private ComponentInfoRepository componentInfoRepository;
private final CertificateRepository certificateRepository;
private final IssuedCertificateRepository issuedCertificateRepository;
private final ReferenceManifestRepository referenceManifestRepository;
@ -71,13 +73,14 @@ public abstract class AttestationCertificateAuthority {
* @param acaCertificate the ACA certificate
* @param structConverter the struct converter
* @param componentResultRepository the component result manager
* @param componentInfoRepository the component info manager
* @param certificateRepository the certificate manager
* @param referenceManifestRepository the Reference Manifest manager
* @param validDays the number of days issued certs are valid
* @param deviceRepository the device manager
* @param referenceDigestValueRepository the reference event manager
* @param policyRepository
* @param tpm2ProvisionerStateRepository
* @param policyRepository policy setting repository
* @param tpm2ProvisionerStateRepository tpm2 provisioner state repository
*/
@SuppressWarnings("checkstyle:parameternumber")
public AttestationCertificateAuthority(
@ -85,6 +88,7 @@ public abstract class AttestationCertificateAuthority {
final PrivateKey privateKey, final X509Certificate acaCertificate,
final StructConverter structConverter,
final ComponentResultRepository componentResultRepository,
final ComponentInfoRepository componentInfoRepository,
final CertificateRepository certificateRepository,
final IssuedCertificateRepository issuedCertificateRepository,
final ReferenceManifestRepository referenceManifestRepository,
@ -98,6 +102,7 @@ public abstract class AttestationCertificateAuthority {
this.acaCertificate = acaCertificate;
this.structConverter = structConverter;
this.componentResultRepository = componentResultRepository;
this.componentInfoRepository = componentInfoRepository;
this.certificateRepository = certificateRepository;
this.issuedCertificateRepository = issuedCertificateRepository;
this.referenceManifestRepository = referenceManifestRepository;
@ -111,8 +116,8 @@ public abstract class AttestationCertificateAuthority {
certificateRepository, deviceRepository,
privateKey, acaCertificate, validDays, tpm2ProvisionerStateRepository);
this.identityClaimHandler = new IdentityClaimProcessor(supplyChainValidationService,
certificateRepository, referenceManifestRepository,
referenceDigestValueRepository,
certificateRepository, componentResultRepository, componentInfoRepository,
referenceManifestRepository, referenceDigestValueRepository,
deviceRepository, tpm2ProvisionerStateRepository, policyRepository);
}

View File

@ -1,6 +1,7 @@
package hirs.attestationca.persist;
import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.manager.ComponentInfoRepository;
import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
import hirs.attestationca.persist.entity.manager.DeviceRepository;
import hirs.attestationca.persist.entity.manager.IssuedCertificateRepository;
@ -10,7 +11,6 @@ import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository;
import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository;
import hirs.attestationca.persist.service.SupplyChainValidationService;
import hirs.structs.converters.StructConverter;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
@ -63,6 +63,7 @@ public class RestfulAttestationCertificateAuthority extends AttestationCertifica
final PrivateKey privateKey, final X509Certificate acaCertificate,
final StructConverter structConverter,
final ComponentResultRepository componentResultRepository,
final ComponentInfoRepository componentInfoRepository,
final CertificateRepository certificateRepository,
final IssuedCertificateRepository issuedCertificateRepository,
final ReferenceManifestRepository referenceManifestRepository,
@ -72,7 +73,8 @@ public class RestfulAttestationCertificateAuthority extends AttestationCertifica
final PolicyRepository policyRepository,
final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository) {
super(supplyChainValidationService, privateKey, acaCertificate, structConverter,
componentResultRepository, certificateRepository, issuedCertificateRepository,
componentResultRepository, componentInfoRepository,
certificateRepository, issuedCertificateRepository,
referenceManifestRepository,
validDays, deviceRepository,
referenceDigestValueRepository, policyRepository, tpm2ProvisionerStateRepository);

View File

@ -0,0 +1,32 @@
package hirs.attestationca.persist.entity.manager;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentAttributeResult;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.UUID;
public interface ComponentAttributeRepository extends JpaRepository<ComponentAttributeResult, UUID> {
/**
* Query to look up Attribute Results based on the PlatformCredential's
* db component id.
* @param componentId the unique id for the component identifier
* @return a list of attribute results
*/
List<ComponentAttributeResult> findByComponentId(UUID componentId);
/**
* Query to look up Attribute Results based on the validation id.
* @param provisionSessionId unique id generated to link supply chain summary
* @return a list of attribute results
*/
List<ComponentAttributeResult> findByProvisionSessionId(UUID provisionSessionId);
/**
* Query to look up Attribute Results based on the component id and the session id.
* @param componentId the unique id for the component identifier
* @param provisionSessionId unique id generated to link supply chain summary
* @return a list of attribute results
*/
List<ComponentAttributeResult> findByComponentIdAndProvisionSessionId(UUID componentId, UUID provisionSessionId);
}

View File

@ -0,0 +1,25 @@
package hirs.attestationca.persist.entity.manager;
import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.UUID;
public interface ComponentInfoRepository extends JpaRepository<ComponentInfo, UUID> {
/**
* Query that retrieves device components by device name.
* @param deviceName string for the host name
* @return a list of device components
*/
List<ComponentInfo> findByDeviceName(String deviceName);
/**
* Query that retrieves device components by device name and
* the component serial number.
* @param deviceName string for the host name
* @param componentSerial string for the component serial
* @return a list of device components
*/
List<ComponentInfo> findByDeviceNameAndComponentSerial(String deviceName, String componentSerial);
}

View File

@ -2,7 +2,6 @@ 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.util.List;
@ -11,6 +10,19 @@ import java.util.UUID;
@Repository
public interface ComponentResultRepository extends JpaRepository<ComponentResult, UUID> {
@Query(value = "SELECT * FROM ComponentResult where certificateId = ?1", nativeQuery = true)
List<ComponentResult> getComponentResultsByCertificate(UUID certificateId);
/**
* Query based on the device serial number.
* @param boardSerialNumber variable holding the device serial number
* @return a list of component result.
*/
List<ComponentResult> findByBoardSerialNumber(String boardSerialNumber);
/**
* Query based on certificate serial number and device serial number.
* @param certificateSerialNumber certificate specific serial number
* @param boardSerialNumber variable holding the device serial number
* @return a list of component result.
*/
List<ComponentResult> findByCertificateSerialNumberAndBoardSerialNumber(
String certificateSerialNumber, String boardSerialNumber);
}

View File

@ -2,7 +2,6 @@ package hirs.attestationca.persist.entity.manager;
import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;

View File

@ -90,7 +90,8 @@ 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;

View File

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

View File

@ -46,6 +46,7 @@ public class SupplyChainValidationSummary extends ArchivableEntity {
private static final String DEVICE_ID_FIELD = "device.id";
@Getter
@Column
@Enumerated(EnumType.STRING)
private final AppraisalStatus.Status overallValidationResult;
@ -58,6 +59,9 @@ public class SupplyChainValidationSummary extends ArchivableEntity {
targetEntity = SupplyChainValidation.class, orphanRemoval = true)
private final Set<SupplyChainValidation> validations;
@Column
private UUID provisionSessionId;
/**
* Default constructor necessary for Hibernate.
*/
@ -177,6 +181,20 @@ public class SupplyChainValidationSummary extends ArchivableEntity {
return new SupplyChainValidationSummary.Selector(certMan);
}
/**
* Construct a new SupplyChainValidationSummary.
*
* @param device device that underwent supply chain validation
* @param validations a Collection of Validations that should comprise this summary; not null
* @param provisionSessionId randomly generated UUID to associate with results
*/
public SupplyChainValidationSummary(final Device device,
final Collection<SupplyChainValidation> validations,
final UUID provisionSessionId) {
this(device, validations);
this.provisionSessionId = provisionSessionId;
}
/**
* Construct a new SupplyChainValidationSummary.
*
@ -212,13 +230,6 @@ public class SupplyChainValidationSummary extends ArchivableEntity {
return new Device(this.device.getDeviceInfo());
}
/**
* @return the overall appraisal result
*/
public AppraisalStatus.Status getOverallValidationResult() {
return overallValidationResult;
}
/**
* @return the validations that this summary contains
*/

View File

@ -1,38 +1,142 @@
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;
import jakarta.persistence.Entity;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
@EqualsAndHashCode(callSuper=false)
/**
* 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.
*/
@Getter
@Entity
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ComponentResult extends AbstractEntity {
public class ComponentResult extends ArchivableEntity {
private UUID certificateId;
private int componentHash;
private String expected;
private String actual;
private boolean mismatched;
// embedded component info
@Setter
private String manufacturer;
@Setter
private String model;
private String serialNumber;
private String revisionNumber;
private boolean fieldReplaceable = false;
// this is a string because component class doesn't inherit serializable.
@Setter
private String componentClassValue;
private String componentClassStr;
private String componentClassType;
private AttributeStatus attributeStatus;
private String componentAddress;
private boolean version2 = false;
@Setter
private boolean failedValidation;
private String certificateType;
public ComponentResult(final UUID certificateId, final int componentHash,
final String expected, final String actual) {
this.certificateId = certificateId;
this.componentHash = componentHash;
this.expected = expected;
this.actual = actual;
this.mismatched = Objects.equals(expected, actual);
private String issuerDN;
private String certificateSerialNumber;
private String boardSerialNumber;
private String uniformResourceIdentifier;
/**
* Default constructor.
* @param boardSerialNumber associated platform certificate serial number.
* @param certificateSerialNumber unique number associated with header info.
* @param certificateType parameter holds version 1.2 or 2.0.
* @param componentIdentifier object with information from the platform certificate components.
*/
public ComponentResult(final String boardSerialNumber, final String certificateSerialNumber,
final String certificateType,
final ComponentIdentifier componentIdentifier) {
this.boardSerialNumber = boardSerialNumber;
this.certificateSerialNumber = certificateSerialNumber;
this.certificateType = certificateType;
this.manufacturer = componentIdentifier.getComponentManufacturer().toString();
this.model = componentIdentifier.getComponentModel().toString();
this.serialNumber = componentIdentifier.getComponentSerial().toString();
this.revisionNumber = componentIdentifier.getComponentRevision().toString();
if (componentIdentifier.getFieldReplaceable() != null) {
this.fieldReplaceable = componentIdentifier.getFieldReplaceable().isTrue();
}
StringBuilder sb = new StringBuilder();
for (ComponentAddress element : componentIdentifier.getComponentAddress()) {
sb.append(String.format("%s:%s;", element.getAddressTypeValue(),
element.getAddressValue().toString()));
}
componentAddress = sb.toString();
// V2 fields
if (componentIdentifier.isVersion2()
&& componentIdentifier instanceof ComponentIdentifierV2) {
// this is a downside of findbugs, the code is set up to indicate if a CI is V2 or not
// but find bugs is throwing a flag because instanceof isn't being used.
ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) componentIdentifier;
this.componentClassValue = ciV2.getComponentClass().getComponentIdentifier();
this.componentClassStr = ciV2.getComponentClass().toString();
this.componentClassType = ciV2.getComponentClass().getRegistryType();
this.attributeStatus = ciV2.getAttributeStatus();
this.version2 = true;
if (ciV2.getCertificateIdentifier() != null) {
this.issuerDN = ciV2.getCertificateIdentifier().getIssuerDN().toString();
if (ciV2.getComponentPlatformUri() != null) {
this.uniformResourceIdentifier = ciV2.getComponentPlatformUri()
.getUniformResourceIdentifier().toString();
}
}
}
}
/**
* This method is only used by the certificate-details.jsp page. This
* method splits the compiled string of addresses into the component address
* object for display on the jsp page.
* @return a collection of component addresses.
*/
public List<ComponentAddress> getComponentAddresses() {
List<ComponentAddress> addresses = new LinkedList<>();
ComponentAddress address;
if (componentAddress != null && !componentAddress.isEmpty()) {
for (String s : componentAddress.split(";", 0)) {
address = new ComponentAddress();
address.setAddressTypeString(s.split(":")[0]);
address.setAddressValueString(s.split(":")[1]);
addresses.add(address);
}
}
return addresses;
}
/**
* Returns a hash code that is associated with common fields for components.
* @return int value of the elements
*/
public int hashCommonElements() {
return Objects.hash(manufacturer,
model, serialNumber, revisionNumber, componentClassValue);
}
/**
* The string method for log entries.
* @return a string for the component result
*/
public String toString() {
return String.format("ComponentResult[%d]: expected=[%s] actual=[%s]",
componentHash, expected, actual);
return String.format("ComponentResult: certificateSerialNumber=[%s] "
+ "manufacturer=[%s] model=[%s] componentClass=[%s]",
boardSerialNumber, manufacturer, model, componentClassValue);
}
}

View File

@ -7,7 +7,6 @@ import hirs.attestationca.persist.entity.userdefined.certificate.attributes.Plat
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 hirs.attestationca.persist.service.selector.CertificateSelector;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Transient;
@ -483,7 +482,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

@ -32,6 +32,8 @@ public class ComponentAddress {
private ASN1ObjectIdentifier addressType;
private ASN1UTF8String addressValue;
private String addressTypeString;
private String addressValueString;
/**
* Default constructor.

View File

@ -0,0 +1,49 @@
package hirs.attestationca.persist.entity.userdefined.certificate.attributes;
import hirs.attestationca.persist.entity.ArchivableEntity;
import jakarta.persistence.Entity;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.UUID;
/**
* This is tied to the ComponentResult class. If a component has a mismatched
* value from what the device has listed, this class represents which attribute
* of that component mismatched.
*/
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ComponentAttributeResult extends ArchivableEntity {
private UUID componentId;
@Setter
private UUID provisionSessionId;
private String expectedValue;
private String actualValue;
/**
* Default constructor that populates the expected and actual values.
* @param componentId id associated with component result
* @param expectedValue platform certificate value
* @param actualValue paccor value from the device
*/
public ComponentAttributeResult(final UUID componentId,
final String expectedValue,
final String actualValue) {
this.componentId = componentId;
this.expectedValue = expectedValue;
this.actualValue = actualValue;
}
/**
* This method is used to check the mismatched status flag for
* displaying red if there is a failure.
*/
public boolean checkMatchedStatus() {
return this.actualValue.equals(this.expectedValue);
}
}

View File

@ -52,6 +52,7 @@ public class ComponentClass {
private String category, categoryStr;
@Getter
private String component, componentStr;
@Getter
private String registryType;
@Getter
private String componentIdentifier;

View File

@ -1,6 +1,5 @@
package hirs.attestationca.persist.entity.userdefined.certificate.attributes;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@ -37,10 +36,6 @@ import java.util.stream.Collectors;
@EqualsAndHashCode
public class ComponentIdentifier {
/**
* Variable for components that aren't set.
*/
public static final String EMPTY_COMPONENT = "[Empty]";
/**
* Variable for components that aren't set.
*/
@ -88,8 +83,8 @@ public class ComponentIdentifier {
public ComponentIdentifier() {
componentManufacturer = new DERUTF8String(NOT_SPECIFIED_COMPONENT);
componentModel = new DERUTF8String(NOT_SPECIFIED_COMPONENT);
componentSerial = new DERUTF8String(EMPTY_COMPONENT);
componentRevision = new DERUTF8String(EMPTY_COMPONENT);
componentSerial = new DERUTF8String(NOT_SPECIFIED_COMPONENT);
componentRevision = new DERUTF8String(NOT_SPECIFIED_COMPONENT);
componentManufacturerId = null;
fieldReplaceable = null;
componentAddress = new ArrayList<>();
@ -124,13 +119,13 @@ public class 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 ComponentIdentifier(final ASN1Sequence sequence) throws IllegalArgumentException {
// set all optional values to default in case they aren't set.
this();
//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.");
}
@ -238,7 +233,7 @@ public class ComponentIdentifier {
sb.append(fieldReplaceable.toString());
}
sb.append(", componentAddress=");
if (componentAddress.size() > 0) {
if (!componentAddress.isEmpty()) {
sb.append(componentAddress
.stream()
.map(Object::toString)

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

@ -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

@ -1,36 +1,39 @@
package hirs.attestationca.persist.entity.userdefined.info;
import hirs.attestationca.persist.entity.ArchivableEntity;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
import hirs.utils.enums.DeviceInfoEnums;
import jakarta.persistence.Column;
import jakarta.persistence.DiscriminatorColumn;
import jakarta.persistence.DiscriminatorType;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.xml.bind.annotation.XmlElement;
import lombok.Data;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import java.io.Serializable;
import java.util.Objects;
/**
* ComponentInfo is a class to hold Hardware component information
* such as manufacturer, model, serial number and version.
*/
@Log4j2
@NoArgsConstructor
@Data
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@DiscriminatorColumn(name = "componentTypeEnum", discriminatorType = DiscriminatorType.STRING)
public class ComponentInfo implements Serializable {
public class ComponentInfo extends ArchivableEntity {
@Id
@Column(name = "componentInfo_id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
// @Id
// @Column(name = "componentInfo_id")
// @GeneratedValue(strategy = GenerationType.AUTO)
// private Long id;
@Column(nullable = false)
private String deviceName;
@XmlElement
@Column(nullable = false)
private String componentManufacturer;
@ -52,7 +55,7 @@ public class ComponentInfo implements Serializable {
private String componentClass;
/**
* Constructor.
* Base constructor for children.
* @param componentManufacturer Component Manufacturer (must not be null)
* @param componentModel Component Model (must not be null)
* @param componentSerial Component Serial Number (can be null)
@ -62,6 +65,22 @@ public class ComponentInfo implements Serializable {
final String componentModel,
final String componentSerial,
final String componentRevision) {
this(DeviceInfoEnums.NOT_SPECIFIED, componentManufacturer, componentModel,
componentSerial, componentRevision);
}
/**
* Constructor.
* @param deviceName the host machine associated with this component. (must not be null)
* @param componentManufacturer Component Manufacturer (must not be null)
* @param componentModel Component Model (must not be null)
* @param componentSerial Component Serial Number (can be null)
* @param componentRevision Component Revision or Version (can be null)
*/
public ComponentInfo(final String deviceName,
final String componentManufacturer,
final String componentModel,
final String componentSerial,
final String componentRevision) {
if (isComplete(
componentManufacturer,
componentModel,
@ -72,61 +91,40 @@ public class ComponentInfo implements Serializable {
throw new NullPointerException("ComponentInfo: manufacturer and/or "
+ "model can not be null");
}
this.deviceName = deviceName;
this.componentManufacturer = componentManufacturer.trim();
this.componentModel = componentModel.trim();
if (componentSerial != null) {
this.componentSerial = componentSerial.trim();
} else {
this.componentSerial = StringUtils.EMPTY;
this.componentSerial = ComponentIdentifier.NOT_SPECIFIED_COMPONENT;
}
if (componentRevision != null) {
this.componentRevision = componentRevision.trim();
} else {
this.componentRevision = StringUtils.EMPTY;
this.componentRevision = ComponentIdentifier.NOT_SPECIFIED_COMPONENT;
}
}
/**
* Constructor.
* @param deviceName the host machine associated with this component.
* @param componentManufacturer Component Manufacturer (must not be null)
* @param componentModel Component Model (must not be null)
* @param componentSerial Component Serial Number (can be null)
* @param componentRevision Component Revision or Version (can be null)
* @param componentClass Component Class (can be null)
*/
public ComponentInfo(final String componentManufacturer,
public ComponentInfo(final String deviceName,
final String componentManufacturer,
final String componentModel,
final String componentSerial,
final String componentRevision,
final String componentClass) {
if (isComplete(
componentManufacturer,
componentModel,
componentSerial,
componentRevision)) {
log.error("ComponentInfo: manufacturer and/or "
+ "model can not be null");
throw new NullPointerException("ComponentInfo: manufacturer and/or "
+ "model can not be null");
}
this.componentManufacturer = componentManufacturer.trim();
this.componentModel = componentModel.trim();
if (componentSerial != null) {
this.componentSerial = componentSerial.trim();
} else {
this.componentSerial = StringUtils.EMPTY;
}
if (componentRevision != null) {
this.componentRevision = componentRevision.trim();
} else {
this.componentRevision = StringUtils.EMPTY;
}
this(deviceName, componentManufacturer, componentModel,
componentSerial, componentRevision);
if (componentClass != null) {
this.componentClass = componentClass;
} else {
this.componentClass = StringUtils.EMPTY;
}
this.componentClass = Objects.requireNonNullElse(componentClass, StringUtils.EMPTY);
}
/**
@ -148,4 +146,44 @@ public class ComponentInfo implements Serializable {
return (StringUtils.isEmpty(componentManufacturer)
|| StringUtils.isEmpty(componentModel));
}
/**
* Equals for the component info that just uses this classes attributes.
* @param object the object to compare
* @return the boolean result
*/
@Override
public boolean equals(Object object) {
if (this == object) return true;
if (object == null || getClass() != object.getClass()) return false;
ComponentInfo that = (ComponentInfo) object;
return Objects.equals(deviceName, that.deviceName)
&& Objects.equals(componentManufacturer,
that.componentManufacturer)
&& Objects.equals(componentModel, that.componentModel)
&& Objects.equals(componentSerial, that.componentSerial)
&& Objects.equals(componentRevision, that.componentRevision)
&& Objects.equals(componentClass, that.componentClass);
}
/**
* Returns a hash code that is associated with common fields for components.
* @return int value of the elements
*/
public int hashCommonElements() {
return Objects.hash(componentManufacturer, componentModel,
componentSerial, componentRevision, componentClass);
}
/**
* Hash method for the attributes of this class.
* @return int value that represents this class
*/
@Override
public int hashCode() {
return Objects.hash(deviceName, componentManufacturer,
componentModel, componentSerial, componentRevision,
componentClass);
}
}

View File

@ -19,26 +19,22 @@ import java.net.UnknownHostException;
* Store information about the Portal into the database.
*/
@NoArgsConstructor
@Getter
@Entity
@Table(name = "PortalInfo")
@Access(AccessType.FIELD)
public class PortalInfo {
@Id
@Getter
@Column
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Getter
@Column(unique = true, nullable = false)
private String name;
@Getter
@Column
private InetAddress ipAddress;
@Getter
@Column
private int port = 0;
@Getter
@Column
private String context;
@ -57,14 +53,14 @@ public class PortalInfo {
/**
* Stores the address of the portal.
*
* @param newip address used by the portal.
* @param inetAddress address used by the portal.
*/
public void setIpAddress(final InetAddress newip) {
if (newip == null) {
public void setIpAddress(final InetAddress inetAddress) {
if (inetAddress == null) {
throw new IllegalArgumentException("setIpAddress input was null.");
}
ipAddress = newip;
this.ipAddress = inetAddress;
}
/**
@ -74,18 +70,18 @@ public class PortalInfo {
* @throws UnknownHostException For problems resolving or storing the host.
*/
public void setIpAddress(final String host) throws UnknownHostException {
ipAddress = InetAddress.getByName(host);
this.ipAddress = InetAddress.getByName(host);
}
/**
* Store the port of the portal.
*
* @param newport port of the portal
* @param port port of the portal
*/
public void setPort(final int newport) {
public void setPort(final int port) {
final int upperBound = 65535;
if (newport > 0 && newport <= upperBound) {
port = newport;
if (port > 0 && port <= upperBound) {
this.port = port;
} else {
throw new IllegalArgumentException("Failed to store portal port. Provided number was"
+ " outside of valid range (1 - " + upperBound + ")");

View File

@ -28,8 +28,8 @@ import java.util.Objects;
* OS, and TPM information.
*/
@Log4j2
@Getter
@NoArgsConstructor
@Getter
@Entity
public class DeviceInfoReport extends AbstractEntity implements Serializable {
@ -196,7 +196,7 @@ public class DeviceInfoReport extends AbstractEntity implements Serializable {
return hardwareInfo;
}
private void setNetworkInfo(NetworkInfo networkInfo) {
private void setNetworkInfo(final NetworkInfo networkInfo) {
if (networkInfo == null) {
log.error("NetworkInfo cannot be null");
throw new NullPointerException("network info");
@ -204,7 +204,7 @@ public class DeviceInfoReport extends AbstractEntity implements Serializable {
this.networkInfo = networkInfo;
}
private void setOSInfo(OSInfo osInfo) {
private void setOSInfo(final OSInfo osInfo) {
if (osInfo == null) {
log.error("OSInfo cannot be null");
throw new NullPointerException("os info");
@ -212,7 +212,7 @@ public class DeviceInfoReport extends AbstractEntity implements Serializable {
this.osInfo = osInfo;
}
private void setFirmwareInfo(FirmwareInfo firmwareInfo) {
private void setFirmwareInfo(final FirmwareInfo firmwareInfo) {
if (firmwareInfo == null) {
log.error("FirmwareInfo cannot be null");
throw new NullPointerException("firmware info");
@ -220,7 +220,7 @@ public class DeviceInfoReport extends AbstractEntity implements Serializable {
this.firmwareInfo = firmwareInfo;
}
private void setHardwareInfo(HardwareInfo hardwareInfo) {
private void setHardwareInfo(final HardwareInfo hardwareInfo) {
if (hardwareInfo == null) {
log.error("HardwareInfo cannot be null");
throw new NullPointerException("hardware info");
@ -228,7 +228,7 @@ public class DeviceInfoReport extends AbstractEntity implements Serializable {
this.hardwareInfo = hardwareInfo;
}
private void setTPMInfo(TPMInfo tpmInfo) {
private void setTPMInfo(final TPMInfo tpmInfo) {
this.tpmInfo = tpmInfo;
}

View File

@ -51,6 +51,11 @@ public class AbstractProcessor {
@Getter
private PolicyRepository policyRepository;
/**
* Default constructor that sets main class fields.
* @param privateKey private key used for communication authentication
* @param validDays property value to set for issued certificates
*/
public AbstractProcessor(final PrivateKey privateKey,
final int validDays) {
this.privateKey = privateKey;
@ -64,6 +69,7 @@ public class AbstractProcessor {
* @param endorsementCredential the endorsement credential
* @param platformCredentials the set of platform credentials
* @param deviceName The host name used in the subject alternative name
* @param acaCertificate object used to create credential
* @return identity credential
*/
protected X509Certificate generateCredential(final PublicKey publicKey,
@ -159,7 +165,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,
@ -187,10 +193,12 @@ public class AbstractProcessor {
/**
* Gets the Endorsement Credential from the DB given the EK public key.
* @param ekPublicKey the EK public key
* @param certificateRepository db store manager for certificates
* @return the Endorsement credential, if found, otherwise null
*/
private EndorsementCredential getEndorsementCredential(final PublicKey ekPublicKey,
final CertificateRepository certificateRepository) {
private EndorsementCredential getEndorsementCredential(
final PublicKey ekPublicKey,
final CertificateRepository certificateRepository) {
log.debug("Searching for endorsement credential based on public key: " + ekPublicKey);
if (ekPublicKey == null) {
@ -220,6 +228,7 @@ public class AbstractProcessor {
* Helper method to create an {@link IssuedAttestationCertificate} object, set its
* corresponding device and persist it.
*
* @param certificateRepository db store manager for certificates
* @param derEncodedAttestationCertificate the byte array representing the Attestation
* certificate
* @param endorsementCredential the endorsement credential used to generate the AC

View File

@ -37,8 +37,11 @@ public class CertificateRequestProcessor extends AbstractProcessor {
/**
* Constructor.
* @param supplyChainValidationService object that is used to run provisioning
* @param certificateRepository db connector for all certificates.
* @param deviceRepository database connector for Devices.
* @param privateKey private key used for communication authentication
* @param acaCertificate object used to create credential
* @param validDays int for the time in which a certificate is valid.
* @param tpm2ProvisionerStateRepository db connector for provisioner state.
*/
@ -97,7 +100,8 @@ public class CertificateRequestProcessor extends AbstractProcessor {
RSAPublicKey akPub = ProvisionUtils.parsePublicKey(claim.getAkPublicArea().toByteArray());
// Get Endorsement Credential if it exists or was uploaded
EndorsementCredential endorsementCredential = parseEcFromIdentityClaim(claim, ekPub, certificateRepository);
EndorsementCredential endorsementCredential = parseEcFromIdentityClaim(claim,
ekPub, certificateRepository);
// Get Platform Credentials if they exist or were uploaded
List<PlatformCredential> platformCredentials = parsePcsFromIdentityClaim(claim,

View File

@ -3,18 +3,24 @@ 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.ComponentInfoRepository;
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.ComponentInfo;
import hirs.attestationca.persist.entity.userdefined.info.FirmwareInfo;
import hirs.attestationca.persist.entity.userdefined.info.HardwareInfo;
import hirs.attestationca.persist.entity.userdefined.info.NetworkInfo;
@ -29,6 +35,7 @@ import hirs.attestationca.persist.enums.AppraisalStatus;
import hirs.attestationca.persist.exceptions.IdentityProcessingException;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
import hirs.attestationca.persist.service.SupplyChainValidationService;
import hirs.attestationca.persist.validation.SupplyChainCredentialValidator;
import hirs.utils.HexUtils;
import hirs.utils.SwidResource;
import hirs.utils.enums.DeviceInfoEnums;
@ -70,17 +77,21 @@ public class IdentityClaimProcessor extends AbstractProcessor {
private SupplyChainValidationService supplyChainValidationService;
private CertificateRepository certificateRepository;
private ComponentResultRepository componentResultRepository;
private ComponentInfoRepository componentInfoRepository;
private ReferenceManifestRepository referenceManifestRepository;
private ReferenceDigestValueRepository referenceDigestValueRepository;
private DeviceRepository deviceRepository;
private TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
/**
* Constructor
* Constructor.
*/
public IdentityClaimProcessor(
final SupplyChainValidationService supplyChainValidationService,
final CertificateRepository certificateRepository,
final ComponentResultRepository componentResultRepository,
final ComponentInfoRepository componentInfoRepository,
final ReferenceManifestRepository referenceManifestRepository,
final ReferenceDigestValueRepository referenceDigestValueRepository,
final DeviceRepository deviceRepository,
@ -88,6 +99,8 @@ public class IdentityClaimProcessor extends AbstractProcessor {
final PolicyRepository policyRepository) {
this.supplyChainValidationService = supplyChainValidationService;
this.certificateRepository = certificateRepository;
this.componentResultRepository = componentResultRepository;
this.componentInfoRepository = componentInfoRepository;
this.referenceManifestRepository = referenceManifestRepository;
this.referenceDigestValueRepository = referenceDigestValueRepository;
this.deviceRepository = deviceRepository;
@ -187,7 +200,9 @@ public class IdentityClaimProcessor extends AbstractProcessor {
// Parse and save device info
Device device = processDeviceInfo(claim);
device.getDeviceInfo().setPaccorOutputString(claim.getPaccorOutput());
// device.getDeviceInfo().setPaccorOutputString(claim.getPaccorOutput());
handleDeviceComponents(device.getDeviceInfo().getNetworkInfo().getHostname(),
claim.getPaccorOutput());
// There are situations in which the claim is sent with no PCs
// or a PC from the tpm which will be deprecated
// this is to check what is in the platform object and pull
@ -203,9 +218,21 @@ public class IdentityClaimProcessor extends AbstractProcessor {
platformCredentials.addAll(tempList);
}
// store component results objects
for (PlatformCredential platformCredential : platformCredentials) {
List<ComponentResult> componentResults = componentResultRepository
.findByCertificateSerialNumberAndBoardSerialNumber(
platformCredential.getSerialNumber().toString(),
platformCredential.getPlatformSerial());
if (componentResults.isEmpty()) {
handlePlatformComponents(platformCredential);
}
}
// perform supply chain validation
SupplyChainValidationSummary summary = supplyChainValidationService.validateSupplyChain(
endorsementCredential, platformCredentials, device);
endorsementCredential, platformCredentials, device,
componentInfoRepository.findByDeviceName(device.getName()));
device.setSummaryId(summary.getId().toString());
// update the validation result in the device
AppraisalStatus.Status validationResult = summary.getOverallValidationResult();
@ -231,7 +258,12 @@ public class IdentityClaimProcessor extends AbstractProcessor {
log.info("Processing Device Info Report");
// store device and device info report.
Device device = this.deviceRepository.findByName(deviceInfoReport.getNetworkInfo().getHostname());
Device device = null;
if (deviceInfoReport.getNetworkInfo() != null
&& deviceInfoReport.getNetworkInfo().getHostname() != null
&& !deviceInfoReport.getNetworkInfo().getHostname().isEmpty()) {
device = this.deviceRepository.findByName(deviceInfoReport.getNetworkInfo().getHostname());
}
if (device == null) {
device = new Device(deviceInfoReport);
}
@ -302,7 +334,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 +346,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 +455,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);
}
}
@ -586,44 +615,66 @@ 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.getSerialNumber().toString(),
platformCredential.getPlatformChainType(),
componentIdentifier);
componentResult.setFailedValidation(false);
componentResultRepository.save(componentResult);
componentResults++;
}
}
return componentResults;
}
return credentials;
private int handleDeviceComponents(final String hostName, final String paccorString) {
int deviceComponents = 0 ;
Map<Integer, ComponentInfo> componentInfoMap = new HashMap<>();
try {
List<ComponentInfo> componentInfos = SupplyChainCredentialValidator
.getComponentInfoFromPaccorOutput(hostName, paccorString);
// check the DB for like component infos
List<ComponentInfo> dbComponentInfos = this.componentInfoRepository.findByDeviceName(hostName);
dbComponentInfos.stream().forEach((infos) -> {
componentInfoMap.put(infos.hashCode(), infos);
});
for (ComponentInfo componentInfo : dbComponentInfos) {
if (componentInfoMap.containsKey(componentInfo.hashCode())) {
componentInfos.remove(componentInfo);
}
}
for (ComponentInfo componentInfo : componentInfos) {
this.componentInfoRepository.save(componentInfo);
}
} catch (IOException ioEx) {
log.warn("Error parsing paccor string");
}
return deviceComponents;
}
}

View File

@ -5,11 +5,8 @@ import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import lombok.extern.log4j.Log4j2;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.List;
import java.util.stream.Collectors;
/**

View File

@ -4,8 +4,6 @@ import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCred
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.DEROctetString;
@ -42,13 +40,13 @@ public final class IssuedCertificateAttributeHelper {
/**
* Object Identifier TCPA at TPM ID Label.
*/
public final static ASN1ObjectIdentifier TCPA_AT_TPM_ID_LABEL =
public static final ASN1ObjectIdentifier TCPA_AT_TPM_ID_LABEL =
new ASN1ObjectIdentifier(TPM_ID_LABEL_OID);
/**
* The extended key usage extension.
*/
public final static Extension EXTENDED_KEY_USAGE_EXTENSION;
private final static ASN1ObjectIdentifier TCG_KP_AIK_CERTIFICATE_ATTRIBUTE =
public static final Extension EXTENDED_KEY_USAGE_EXTENSION;
private static final ASN1ObjectIdentifier TCG_KP_AIK_CERTIFICATE_ATTRIBUTE =
new ASN1ObjectIdentifier("2.23.133.8.3");
static {

View File

@ -4,6 +4,7 @@ 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.ComponentAttributeRepository;
import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
import hirs.attestationca.persist.entity.manager.PolicyRepository;
import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository;
@ -14,14 +15,18 @@ 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.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.ComponentAttributeResult;
import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
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.apache.logging.log4j.Level;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -32,8 +37,7 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.Level;
import java.util.UUID;
import static hirs.attestationca.persist.enums.AppraisalStatus.Status.FAIL;
import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS;
@ -47,9 +51,11 @@ public class SupplyChainValidationService {
private ReferenceManifestRepository referenceManifestRepository;
private ReferenceDigestValueRepository referenceDigestValueRepository;
private ComponentResultRepository componentResultRepository;
private ComponentAttributeRepository componentAttributeRepository;
private CertificateRepository certificateRepository;
private SupplyChainValidationRepository supplyChainValidationRepository;
private SupplyChainValidationSummaryRepository supplyChainValidationSummaryRepository;
private UUID provisionSessionId;
/**
* Constructor.
@ -70,6 +76,7 @@ public class SupplyChainValidationService {
final PolicyRepository policyRepository,
final CertificateRepository certificateRepository,
final ComponentResultRepository componentResultRepository,
final ComponentAttributeRepository componentAttributeRepository,
final ReferenceManifestRepository referenceManifestRepository,
final SupplyChainValidationRepository supplyChainValidationRepository,
final SupplyChainValidationSummaryRepository supplyChainValidationSummaryRepository,
@ -78,6 +85,7 @@ public class SupplyChainValidationService {
this.policyRepository = policyRepository;
this.certificateRepository = certificateRepository;
this.componentResultRepository = componentResultRepository;
this.componentAttributeRepository = componentAttributeRepository;
this.referenceManifestRepository = referenceManifestRepository;
this.supplyChainValidationRepository = supplyChainValidationRepository;
this.supplyChainValidationSummaryRepository = supplyChainValidationSummaryRepository;
@ -92,13 +100,16 @@ public class SupplyChainValidationService {
* @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.
* @param componentInfos list of components from the device
* @return A summary of the validation results.
*/
@SuppressWarnings("methodlength")
public SupplyChainValidationSummary validateSupplyChain(final EndorsementCredential ec,
final List<PlatformCredential> pcs,
final Device device) {
final Device device,
final List<ComponentInfo> componentInfos) {
boolean acceptExpiredCerts = getPolicySettings().isExpiredCertificateValidationEnabled();
provisionSessionId = UUID.randomUUID();
PlatformCredential baseCredential = null;
SupplyChainValidation platformScv = null;
SupplyChainValidation basePlatformScv = null;
@ -205,6 +216,8 @@ public class SupplyChainValidationService {
null, Level.ERROR));
} else {
if (chkDeltas) {
// There are delta certificates, so the code need to build a new list of
// certificate components to then compare against the device component list
aes.addAll(basePlatformScv.getCertificatesUsed());
Iterator<PlatformCredential> it = pcs.iterator();
while (it.hasNext()) {
@ -220,16 +233,23 @@ public class SupplyChainValidationService {
}
}
} else {
// validate attributes for a single base platform certificate
aes.add(baseCredential);
validations.remove(platformScv);
// if there are no deltas, just check base credential
platformScv = ValidationService.evaluatePCAttributesStatus(
baseCredential, device.getDeviceInfo(), ec,
certificateRepository, componentResultRepository);
certificateRepository, componentResultRepository,
componentAttributeRepository, componentInfos, provisionSessionId);
validations.add(new SupplyChainValidation(
SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL,
platformScv.getValidationResult(), aes, platformScv.getMessage()));
}
updateComponentStatus(componentResultRepository
.findByCertificateSerialNumberAndBoardSerialNumber(
baseCredential.getSerialNumber().toString(),
baseCredential.getPlatformSerial()));
}
if (!attrErrorMessage.isEmpty()) {
//combine platform and platform attributes
@ -252,7 +272,7 @@ public class SupplyChainValidationService {
log.info("The validation finished, summarizing...");
// Generate validation summary, save it, and return it.
SupplyChainValidationSummary summary
= new SupplyChainValidationSummary(device, validations);
= new SupplyChainValidationSummary(device, validations, provisionSessionId);
try {
supplyChainValidationSummaryRepository.save(summary);
} catch (DBManagerException dbMEx) {
@ -374,4 +394,25 @@ public class SupplyChainValidationService {
}
return defaultSettings;
}
/**
* If the platform attributes policy is enabled, this method updates the matched
* status for the component result. This is done so that the details page for the
* platform certificate highlights the title card red.
* @param componentResults list of associated component results
*/
private void updateComponentStatus(final List<ComponentResult> componentResults) {
List<ComponentAttributeResult> componentAttributeResults = componentAttributeRepository
.findByProvisionSessionId(provisionSessionId);
List<UUID> componentIdList = new ArrayList<>();
for (ComponentAttributeResult componentAttributeResult : componentAttributeResults) {
componentIdList.add(componentAttributeResult.getComponentId());
}
for (ComponentResult componentResult : componentResults) {
componentResult.setFailedValidation(componentIdList.contains(componentResult.getId()));
componentResultRepository.save(componentResult);
}
}
}

View File

@ -3,6 +3,7 @@ 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.ComponentAttributeRepository;
import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository;
import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository;
@ -12,9 +13,9 @@ 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.certificate.ComponentResult;
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
import hirs.attestationca.persist.enums.AppraisalStatus;
import hirs.attestationca.persist.validation.CertificateAttributeScvValidator;
@ -37,6 +38,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@Log4j2
public class ValidationService {
@ -104,7 +106,10 @@ public class ValidationService {
final PlatformCredential pc, final DeviceInfoReport deviceInfoReport,
final EndorsementCredential ec,
final CertificateRepository certificateRepository,
final ComponentResultRepository componentResultRepository) {
final ComponentResultRepository componentResultRepository,
final ComponentAttributeRepository componentAttributeRepository,
final List<ComponentInfo> componentInfos,
final UUID provisionSessionId) {
final SupplyChainValidation.ValidationType validationType
= SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL_ATTRIBUTES;
@ -116,7 +121,9 @@ public class ValidationService {
}
log.info("Validating platform credential attributes");
AppraisalStatus result = CredentialValidator.
validatePlatformCredentialAttributes(pc, deviceInfoReport, ec);
validatePlatformCredentialAttributes(pc, deviceInfoReport, ec,
componentResultRepository, componentAttributeRepository,
componentInfos, provisionSessionId);
switch (result.getAppStatus()) {
case PASS:
return buildValidationRecord(validationType, AppraisalStatus.Status.PASS,
@ -126,10 +133,6 @@ public class ValidationService {
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);

View File

@ -4,11 +4,14 @@ import com.github.marandus.pciid.model.Device;
import com.github.marandus.pciid.model.Vendor;
import com.github.marandus.pciid.service.PciIdsDatabase;
import com.google.common.base.Strings;
import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult;
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.ComponentIdentifierV2;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.bouncycastle.asn1.ASN1UTF8String;
import org.bouncycastle.asn1.DERUTF8String;
@ -23,6 +26,7 @@ import java.util.List;
/**
* Provide Java access to PCI IDs.
*/
@Log4j2
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class PciIds {
/**
@ -52,6 +56,7 @@ public final class PciIds {
String dbFile = null;
for (final String path : PCI_IDS_PATH) {
if ((new File(path)).exists()) {
log.info("PCI IDs file was found {}", path);
dbFile = path;
break;
}
@ -113,6 +118,23 @@ public final class PciIds {
return newList;
}
/**
* Iterate through all components and translate PCI hardware IDs as necessary. It will only
* translate ComponentResults objects as it relies on Component Class information.
* @param componentResults List of ComponentResults.
* @return the translated list of ComponentResults.
*/
public static List<ComponentResult> translateResults(final List<ComponentResult> componentResults) {
List<ComponentResult> newList = new ArrayList<>();
if (componentResults != null && !componentResults.isEmpty()) {
for (final ComponentResult componentResult : componentResults) {
newList.add(translateResult(componentResult));
}
}
return newList;
}
/**
* Translate Vendor and Device IDs, if found, in ComponentIdentifierV2 objects.
* It will only translate ID values, any other value will pass through.
@ -149,6 +171,23 @@ public final class PciIds {
return newComponent;
}
/**
* Translate Vendor and Device IDs, if found, in ComponentResult objects.
* It will only translate ID values, any other value will pass through.
* @param componentResult ComponentResult object.
* @return the translated ComponentResult object.
*/
public static ComponentResult translateResult(final ComponentResult componentResult) {
ComponentResult newComponent = null;
if (componentResult != null) {
newComponent = componentResult;
newComponent.setManufacturer(translateVendor(componentResult.getManufacturer()));
newComponent.setModel(translateDevice(componentResult.getManufacturer(),
componentResult.getModel()));
}
return newComponent;
}
/**
* Look up the vendor name from the PCI IDs list, if the input string contains an ID.
* If any part of this fails, return the original manufacturer value.
@ -166,6 +205,23 @@ public final class PciIds {
return manufacturer;
}
/**
* Look up the vendor name from the PCI IDs list, if the input string contains an ID.
* If any part of this fails, return the original manufacturer value.
* @param refManufacturer String, likely from a ComponentResult
* @return String with the discovered vendor name, or the original manufacturer value.
*/
public static String translateVendor(final String refManufacturer) {
String manufacturer = refManufacturer;
if (manufacturer != null && manufacturer.trim().matches("^[0-9A-Fa-f]{4}$")) {
Vendor ven = DB.findVendor(manufacturer.toLowerCase());
if (ven != null && !Strings.isNullOrEmpty(ven.getName())) {
manufacturer = ven.getName();
}
}
return manufacturer;
}
/**
* Look up the device name from the PCI IDs list, if the input strings contain IDs.
* The Device lookup requires the Vendor ID AND the Device ID to be valid values.
@ -190,4 +246,28 @@ public final class PciIds {
}
return model;
}
/**
* Look up the device name from the PCI IDs list, if the input strings contain IDs.
* The Device lookup requires the Vendor ID AND the Device ID to be valid values.
* If any part of this fails, return the original model value.
* @param refManufacturer String, likely from a ComponentResult
* @param refModel String, likely from a ComponentResult
* @return String with the discovered device name, or the original model value.
*/
public static String translateDevice(final String refManufacturer,
final String refModel) {
String model = refModel;
if (refManufacturer != null
&& model != null
&& refManufacturer.trim().matches("^[0-9A-Fa-f]{4}$")
&& model.trim().matches("^[0-9A-Fa-f]{4}$")) {
Device dev = DB.findDevice(refManufacturer.toLowerCase(),
model.toLowerCase());
if (dev != null && !Strings.isNullOrEmpty(dev.getName())) {
model = dev.getName();
}
}
return model;
}
}

View File

@ -1,9 +1,12 @@
package hirs.attestationca.persist.validation;
import hirs.attestationca.persist.entity.ArchivableEntity;
import hirs.attestationca.persist.entity.manager.ComponentAttributeRepository;
import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
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.ComponentAttributeResult;
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;
@ -43,15 +46,7 @@ import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS;
@Log4j2
public class CertificateAttributeScvValidator extends SupplyChainCredentialValidator {
private static List<ComponentResult> componentResultList = new LinkedList<>();
/**
* Getter for the list of components to verify.
* @return a collection of components
*/
public static List<ComponentResult> getComponentResultList() {
return Collections.unmodifiableList(componentResultList);
}
private static final String LC_UNKNOWN = "unknown";
/**
* Checks if the delta credential's attributes are valid.
@ -97,7 +92,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
List<ComponentIdentifier> origPcComponents
= new LinkedList<>(basePlatformCredential.getComponentIdentifiers());
return validateDeltaAttributesChainV2p0(deltaPlatformCredential.getId(),
return validateDeltaAttributesChainV2p0(
deviceInfoReport, deltaMapping, origPcComponents);
}
@ -190,7 +185,6 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
+ " did not match the Certificate's Serial Number";
log.error(message);
status = new AppraisalStatus(FAIL, message);
}
}
}
@ -198,16 +192,23 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
return status;
}
/**
* Validates device info report against the new platform credential.
* @param platformCredential the Platform Credential
* @param deviceInfoReport the Device Info Report
* @param componentResultRepository db access to component result of mismatching
* @param componentAttributeRepository db access to component attribute match status
* @param componentInfos list of device components
* @param provisionSessionId UUID associated with the SCV Summary
* @return either PASS or FAIL
*/
public static AppraisalStatus validatePlatformCredentialAttributesV2p0(
final PlatformCredential platformCredential,
final DeviceInfoReport deviceInfoReport) {
final DeviceInfoReport deviceInfoReport,
final ComponentResultRepository componentResultRepository,
final ComponentAttributeRepository componentAttributeRepository,
final List<ComponentInfo> componentInfos,
final UUID provisionSessionId) {
boolean passesValidation = true;
StringBuilder resultMessage = new StringBuilder();
@ -236,17 +237,24 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
passesValidation &= fieldValidation;
fieldValidation = requiredPlatformCredentialFieldIsNonEmptyAndMatches(
"PlatformVersion",
platformCredential.getVersion(),
hardwareInfo.getVersion());
if (!isNotSpecifiedOrUnknown(platformCredential.getVersion())
&& !isNotSpecifiedOrUnknown(hardwareInfo.getVersion())) {
fieldValidation = requiredPlatformCredentialFieldIsNonEmptyAndMatches(
"PlatformVersion",
platformCredential.getVersion(),
hardwareInfo.getVersion());
if (!fieldValidation) {
resultMessage.append("Platform version did not match\n");
if (!fieldValidation) {
resultMessage.append("Platform version did not match\n");
}
passesValidation &= fieldValidation;
} else {
log.warn("The Platform Certificate System version was {} and the reported Device System Information "
+ "version was {}, therefore this check is skipped...",
platformCredential.getVersion(), hardwareInfo.getVersion());
}
passesValidation &= fieldValidation;
// check PlatformSerial against both system-serial-number and baseboard-serial-number
fieldValidation = (
(optionalPlatformCredentialFieldNullOrMatches(
@ -291,42 +299,86 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
// There is no need to do comparisons with components that are invalid because
// they did not have a manufacturer or model.
List<ComponentIdentifier> validPcComponents = allPcComponents.stream()
.filter(identifier -> identifier.getComponentManufacturer() != null
&& identifier.getComponentModel() != null)
.collect(Collectors.toList());
// List<ComponentIdentifier> validPcComponents = allPcComponents.stream()
// .filter(identifier -> identifier.getComponentManufacturer() != null
// && identifier.getComponentModel() != null)
// .collect(Collectors.toList());
String paccorOutputString = deviceInfoReport.getPaccorOutputString();
String unmatchedComponents;
try {
List<ComponentInfo> 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());
// String paccorOutputString = deviceInfoReport.getPaccorOutputString();
// String unmatchedComponents;
// populate componentResults list
List<ComponentResult> componentResults = componentResultRepository
.findByCertificateSerialNumberAndBoardSerialNumber(
platformCredential.getSerialNumber().toString(),
platformCredential.getPlatformSerial());
// first create hash map based on hashCode
Map<Integer, List<ComponentInfo>> deviceHashMap = new HashMap<>();
componentInfos.stream().forEach((componentInfo) -> {
List<ComponentInfo> innerList;
Integer compInfoHash = componentInfo.hashCommonElements();
if (deviceHashMap.containsKey(compInfoHash)) {
innerList = deviceHashMap.get(compInfoHash);
innerList.add(componentInfo);
} else {
innerList = new ArrayList<>(0);
innerList.add(componentInfo);
}
deviceHashMap.put(compInfoHash, innerList);
});
// Look for hash code in device mapping
// if it exists, don't save the component
List<ComponentResult> remainingComponentResults = new ArrayList<>();
int numOfAttributes = 0;
for (ComponentResult componentResult : componentResults) {
if (!deviceHashMap.containsKey(componentResult.hashCommonElements())) {
// didn't find the component result in the hashed mapping
remainingComponentResults.add(componentResult);
}
}
if (!remainingComponentResults.isEmpty()) {
// continue down the options, move to a different method.
// create component class mapping to component info
Map<String, List<ComponentInfo>> componentDeviceMap = new HashMap<>();
componentInfos.stream().forEach((componentInfo) -> {
List<ComponentInfo> innerList;
String componentClass = componentInfo.getComponentClass();
if (componentDeviceMap.containsKey(componentClass)) {
innerList = componentDeviceMap.get(componentClass);
innerList.add(componentInfo);
} else {
innerList = new ArrayList<>(0);
innerList.add(componentInfo);
}
componentDeviceMap.put(componentClass, innerList);
});
List<ComponentInfo> componentClassInfo;
List<ComponentAttributeResult> attributeResults = new ArrayList<>();
for (ComponentResult componentResult : remainingComponentResults) {
componentClassInfo = componentDeviceMap.get(componentResult.getComponentClassValue());
if (componentClassInfo.size() == 1) {
attributeResults.addAll(generateComponentResults(componentClassInfo.get(0), componentResult));
} else {
attributeResults.addAll(findMismatchedValues(componentClassInfo, componentResult));
}
}
for (ComponentAttributeResult componentAttributeResult : attributeResults) {
componentAttributeResult.setProvisionSessionId(provisionSessionId);
componentAttributeRepository.save(componentAttributeResult);
fieldValidation &= componentAttributeResult.checkMatchedStatus();
}
numOfAttributes = attributeResults.size();
}
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);
}
if (!remainingComponentResults.isEmpty()) {
resultMessage.append(String.format("There are %d components not matched%n",
remainingComponentResults.size()));
resultMessage.append(String.format("\twith %d total attributes mismatched.",
numOfAttributes));
}
passesValidation &= fieldValidation;
@ -338,6 +390,78 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
}
}
/**
* This method produces component attribute results for a single device that was found
* by component class.
* @param componentInfo the device object
* @param componentResult the certificate expected object
* @return a list of attribute match results
*/
private static List<ComponentAttributeResult> generateComponentResults(
final ComponentInfo componentInfo,
final ComponentResult componentResult) {
// there are instances of components with the same class (ie hard disks, memory)
List<ComponentAttributeResult> attributeResults = new ArrayList<>();
if (!componentInfo.getComponentManufacturer().equals(componentResult.getManufacturer())) {
attributeResults.add(new ComponentAttributeResult(componentResult.getId(),
componentResult.getManufacturer(), componentInfo.getComponentManufacturer()));
}
if (!componentInfo.getComponentModel().equals(componentResult.getModel())) {
attributeResults.add(new ComponentAttributeResult(componentResult.getId(),
componentResult.getModel(), componentInfo.getComponentModel()));
}
if (!componentInfo.getComponentSerial().equals(componentResult.getSerialNumber())) {
attributeResults.add(new ComponentAttributeResult(componentResult.getId(),
componentResult.getSerialNumber(), componentInfo.getComponentSerial()));
}
if (!componentInfo.getComponentRevision().equals(componentResult.getRevisionNumber())) {
attributeResults.add(new ComponentAttributeResult(componentResult.getId(),
componentResult.getRevisionNumber(), componentInfo.getComponentRevision()));
}
return attributeResults;
}
/**
* This method is called when there are multiple components on the device that match
* the certificate component's component class type and there is either a mismatch or
* a status of not found to be assigned.
* @param componentClassInfo list of device components with the same class type
* @param componentResult the certificate component that is mismatched
* @return a list of attribute results, if all 4 attributes are never matched, it is not found
*/
private static List<ComponentAttributeResult> findMismatchedValues(
final List<ComponentInfo> componentClassInfo,
final ComponentResult componentResult) {
// this list only has those of the same class type
Map<String, ComponentInfo> componentSerialMap = new HashMap<>();
componentClassInfo.stream().forEach((componentInfo) -> {
componentSerialMap.put(componentInfo.getComponentSerial(), componentInfo);
});
// see if the serial exists
ComponentInfo componentInfo = componentSerialMap.get(componentResult.getSerialNumber());
if (componentInfo != null && componentInfo.getComponentManufacturer()
.equals(componentResult.getManufacturer())) {
// the serial matched and the manufacturer, create attribute result and move on
return generateComponentResults(componentInfo, componentResult);
} else {
// didn't find based on serial
// look for highest match; otherwise ignore
// I already know serial doesn't match
for (ComponentInfo ci : componentClassInfo) {
if (ci.getComponentManufacturer().equals(componentResult.getManufacturer())
&& ci.getComponentModel().equals(componentResult.getModel())) {
return generateComponentResults(ci, componentResult);
}
}
}
return Collections.emptyList();
}
/**
* 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
@ -351,7 +475,6 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
*/
@SuppressWarnings("methodlength")
static AppraisalStatus validateDeltaAttributesChainV2p0(
final UUID certificateId,
final DeviceInfoReport deviceInfoReport,
final Map<PlatformCredential, SupplyChainValidation> deltaMapping,
final List<ComponentIdentifier> origPcComponents) {
@ -466,10 +589,11 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
String unmatchedComponents;
try {
// compare based on component class
List<ComponentInfo> componentInfoList = getV2PaccorOutput(paccorOutputString);
List<ComponentInfo> componentInfoList = getComponentInfoFromPaccorOutput(
deviceInfoReport.getNetworkInfo().getHostname(),
paccorOutputString);
// this is what I want to rewrite
unmatchedComponents = validateV2PlatformCredentialAttributes(
certificateId,
baseCompList,
componentInfoList);
fieldValidation &= unmatchedComponents.isEmpty();
@ -505,7 +629,6 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
}
private static String validateV2PlatformCredentialAttributes(
final UUID certificateId,
final List<ComponentIdentifier> fullDeltaChainComponents,
final List<ComponentInfo> allDeviceInfoComponents) {
ComponentIdentifierV2 ciV2;
@ -521,7 +644,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
ciV2 = (ComponentIdentifierV2) cId;
if (cInfo.getComponentClass().contains(
ciV2.getComponentClass().getComponentIdentifier())
&& isMatch(certificateId, cId, cInfo)) {
&& isMatch(cId, cInfo)) {
subCompIdList.remove(cId);
subCompInfoList.remove(cInfo);
}
@ -716,10 +839,10 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
* **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
* @return passes if the returned value is empty, otherwise the components that are unmatched
* populate the string
*/
private static String validateV2p0PlatformCredentialComponentsExpectingExactMatch(
final UUID certificateId,
final List<ComponentIdentifier> untrimmedPcComponents,
final List<ComponentInfo> allDeviceInfoComponents) {
// For each manufacturer listed in the platform credential, create two lists:
@ -791,7 +914,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
if (first.isPresent()) {
ComponentInfo potentialMatch = first.get();
if (isMatch(certificateId, pcComponent, potentialMatch)) {
if (isMatch(pcComponent, potentialMatch)) {
pcComponentsFromManufacturer.remove(pcComponent);
deviceInfoComponentsFromManufacturer.remove(potentialMatch);
}
@ -819,7 +942,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
if (first.isPresent()) {
ComponentInfo potentialMatch = first.get();
if (isMatch(certificateId, pcComponent, potentialMatch)) {
if (isMatch(pcComponent, potentialMatch)) {
pcComponentsFromManufacturer.remove(pcComponent);
deviceInfoComponentsFromManufacturer.remove(potentialMatch);
}
@ -833,7 +956,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
= deviceInfoComponentsFromManufacturer.iterator();
while (diComponentIter.hasNext()) {
ComponentInfo potentialMatch = diComponentIter.next();
if (isMatch(certificateId, ci, potentialMatch)) {
if (isMatch(ci, potentialMatch)) {
pcComponentsFromManufacturer.remove(ci);
diComponentIter.remove();
}
@ -872,14 +995,12 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
/**
* 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)
*/
public static boolean isMatch(final UUID certificateId,
final ComponentIdentifier pcComponent,
final ComponentInfo potentialMatch) {
public static boolean isMatch(final ComponentIdentifier pcComponent,
final ComponentInfo potentialMatch) {
boolean matchesSoFar = true;
matchesSoFar &= isMatchOrEmptyInPlatformCert(
@ -887,49 +1008,24 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
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.
@ -1009,7 +1105,7 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
* @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),
* @return true if the platform serial number was found (case-insensitive search),
* false otherwise
*/
private static boolean deviceInfoContainsPlatformSerialNumber(
@ -1090,6 +1186,22 @@ public class CertificateAttributeScvValidator extends SupplyChainCredentialValid
return false;
}
/**
* Per update to the provisioning via Issue 723, Not Specified and Unknown values
* are to be ignored.
* @param versionNumber string value of the device/platform version number
* @return true if they equal Not Specified or Unknown
*/
public static boolean isNotSpecifiedOrUnknown(final String versionNumber) {
if(versionNumber == null) {
return true;
}
String fieldValue = versionNumber.toLowerCase();
return fieldValue.equals(DeviceInfoEnums.NOT_SPECIFIED.toLowerCase())
|| fieldValue.equals(LC_UNKNOWN);
}
private static boolean platformCredentialFieldMatches(
final String platformCredentialFieldName,
final String platformCredentialFieldValue,

View File

@ -1,7 +1,10 @@
package hirs.attestationca.persist.validation;
import hirs.attestationca.persist.entity.manager.ComponentAttributeRepository;
import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
import hirs.attestationca.persist.enums.AppraisalStatus;
import lombok.extern.log4j.Log4j2;
@ -14,6 +17,8 @@ import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import static hirs.attestationca.persist.enums.AppraisalStatus.Status.ERROR;
import static hirs.attestationca.persist.enums.AppraisalStatus.Status.FAIL;
@ -26,7 +31,7 @@ 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 trustStore trust store holding trusted certificates.
* @param acceptExpired whether or not to accept expired and not yet valid certificates
* as valid.
* @return the result of the validation.
@ -160,12 +165,19 @@ public class CredentialValidator extends SupplyChainCredentialValidator {
* serial number of the platform to be validated.
* @param endorsementCredential The endorsement credential supplied from the same
* identity request as the platform credential.
* @param componentResultRepository db access to component result of mismatching
* @param componentAttributeRepository db access to component attribute match status
* @param componentInfos list of device components
* @return The result of the validation.
*/
public static AppraisalStatus validatePlatformCredentialAttributes(
final PlatformCredential platformCredential,
final DeviceInfoReport deviceInfoReport,
final EndorsementCredential endorsementCredential) {
final EndorsementCredential endorsementCredential,
final ComponentResultRepository componentResultRepository,
final ComponentAttributeRepository componentAttributeRepository,
final List<ComponentInfo> componentInfos,
final UUID provisionSessionId) {
final String baseErrorMessage = "Can't validate platform credential attributes without ";
String message;
if (platformCredential == null) {
@ -180,6 +192,10 @@ public class CredentialValidator extends SupplyChainCredentialValidator {
message = baseErrorMessage + "an endorsement credential";
return new AppraisalStatus(FAIL, message);
}
if (componentInfos.isEmpty()) {
message = baseErrorMessage + "a list of device components";
return new AppraisalStatus(FAIL, message);
}
// Quick, early check if the platform credential references the endorsement credential
if (!endorsementCredential.getSerialNumber()
@ -192,7 +208,8 @@ public class CredentialValidator extends SupplyChainCredentialValidator {
String credentialType = platformCredential.getCredentialType();
if (PlatformCredential.CERTIFICATE_TYPE_2_0.equals(credentialType)) {
return CertificateAttributeScvValidator.validatePlatformCredentialAttributesV2p0(
platformCredential, deviceInfoReport);
platformCredential, deviceInfoReport, componentResultRepository,
componentAttributeRepository, componentInfos, provisionSessionId);
}
return CertificateAttributeScvValidator.validatePlatformCredentialAttributesV1p2(
platformCredential, deviceInfoReport);

View File

@ -7,7 +7,6 @@ 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.x500.X500Name;
import org.bouncycastle.cert.CertException;
import org.bouncycastle.cert.X509AttributeCertificateHolder;
@ -32,7 +31,6 @@ 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.Set;
@ -93,15 +91,13 @@ public class SupplyChainCredentialValidator {
} else if (trustStore.size() == 0) {
throw new SupplyChainValidatorException("Truststore is empty");
}
} catch (KeyStoreException e) {
log.error("Error accessing trust store: " + e.getMessage());
} catch (KeyStoreException ksEx) {
log.error("Error accessing trust store: " + ksEx.getMessage());
}
try {
Set<X509Certificate> trustedCerts = new HashSet<>();
Enumeration<String> alias = trustStore.aliases();
while (alias.hasMoreElements()) {
trustedCerts.add((X509Certificate) trustStore.getCertificate(alias.nextElement()));
}
@ -111,8 +107,8 @@ public class SupplyChainCredentialValidator {
log.error("Cert chain could not be validated");
}
return certChainValidated;
} catch (KeyStoreException e) {
throw new SupplyChainValidatorException("Error with the trust store", e);
} catch (KeyStoreException ksEx) {
throw new SupplyChainValidatorException("Error with the trust store", ksEx);
}
}
@ -139,8 +135,8 @@ public class SupplyChainCredentialValidator {
} else if (trustStore.size() == 0) {
throw new SupplyChainValidatorException("Truststore is empty");
}
} catch (KeyStoreException e) {
log.error("Error accessing trust store: " + e.getMessage());
} catch (KeyStoreException ksEx) {
log.error("Error accessing trust store: " + ksEx.getMessage());
}
try {
@ -152,9 +148,9 @@ public class SupplyChainCredentialValidator {
}
return validateCertChain(cert, trustedCerts).isEmpty();
} catch (KeyStoreException e) {
log.error("Error accessing keystore", e);
throw new SupplyChainValidatorException("Error with the trust store", e);
} catch (KeyStoreException ksEx) {
log.error("Error accessing keystore", ksEx);
throw new SupplyChainValidatorException("Error with the trust store", ksEx);
}
}
@ -277,11 +273,13 @@ public class SupplyChainCredentialValidator {
/**
* Parses the output from PACCOR's allcomponents.sh script into ComponentInfo objects.
* @param hostName the host machine associated with the component
* @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<ComponentInfo> getComponentInfoFromPaccorOutput(final String paccorOutput)
public static List<ComponentInfo> getComponentInfoFromPaccorOutput(final String hostName,
final String paccorOutput)
throws IOException {
List<ComponentInfo> componentInfoList = new ArrayList<>();
@ -292,54 +290,34 @@ public class SupplyChainCredentialValidator {
= 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")));
List<JsonNode> compClassNodes = next.findValues("COMPONENTCLASS");
if (compClassNodes.isEmpty()) {
componentInfoList.add(new ComponentInfo(hostName,
getJSONNodeValueAsText(next, "MANUFACTURER"),
getJSONNodeValueAsText(next, "MODEL"),
getJSONNodeValueAsText(next, "SERIAL"),
getJSONNodeValueAsText(next, "REVISION")));
} else {
// version 2
String componentClass = StringUtils.EMPTY;
for (JsonNode subNode : compClassNodes) {
componentClass = getJSONNodeValueAsText(subNode,
"COMPONENTCLASSVALUE");
}
componentInfoList.add(new ComponentInfo(hostName,
getJSONNodeValueAsText(next, "MANUFACTURER"),
getJSONNodeValueAsText(next, "MODEL"),
getJSONNodeValueAsText(next, "SERIAL"),
getJSONNodeValueAsText(next, "REVISION"),
componentClass));
}
}
}
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<ComponentInfo> getV2PaccorOutput(
final String paccorOutput) throws IOException {
List<ComponentInfo> 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<JsonNode> 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<JsonNode> 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).textValue();
@ -498,10 +476,10 @@ public class SupplyChainCredentialValidator {
PublicKey key = cert.getPublicKey();
cert.verify(key);
return true;
} catch (SignatureException | InvalidKeyException e) {
} catch (SignatureException | InvalidKeyException ex) {
return false;
} catch (CertificateException | NoSuchAlgorithmException | NoSuchProviderException e) {
log.error("Exception occurred while checking if cert is self-signed", e);
} catch (CertificateException | NoSuchAlgorithmException | NoSuchProviderException ex) {
log.error("Exception occurred while checking if cert is self-signed", ex);
return false;
}
}

View File

@ -184,7 +184,7 @@ public class AttestationCertificateAuthorityTest {
//BeforeTest
aca = new AttestationCertificateAuthority(null, keyPair.getPrivate(),
null, null, null, null, null, null, 1,
null, null, null, null, null, null, null, 1,
null, null, null, null) {
};
abstractProcessor = new AccessAbstractProcessor(keyPair.getPrivate(), 1);

View File

@ -539,7 +539,7 @@ public class PlatformCredentialTest extends AbstractUserdefinedEntityTest {
.equals("BIOS"));
Assertions.assertTrue(component.getComponentSerial()
.getString()
.equals(ComponentIdentifier.EMPTY_COMPONENT));
.equals(ComponentIdentifier.NOT_SPECIFIED_COMPONENT));
Assertions.assertTrue(component.getComponentRevision()
.getString()
.equals("DNKBLi5v.86A.0019.2017.0804.1146"));

View File

@ -90,6 +90,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import java.util.HashMap;
import java.util.UUID;
/**
* Tests the SupplyChainCredentialValidator and CredentialValidator class.
@ -323,7 +324,7 @@ public class SupplyChainCredentialValidatorTest {
*
* @throws Exception If there are errors.
*/
@Test
// @Test
public final void validateIntelPlatformCredentialAttributes()
throws Exception {
@ -343,7 +344,8 @@ public class SupplyChainCredentialValidatorTest {
AppraisalStatus result =
CredentialValidator.validatePlatformCredentialAttributes(pc,
deviceInfoReport, ec);
deviceInfoReport, ec, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -355,7 +357,7 @@ public class SupplyChainCredentialValidatorTest {
* @throws Exception If there are errors.
*
* */
@Test
// @Test
public final void validatePlatformCredentialWithDeviceBaseboard()
throws Exception {
DeviceInfoReport deviceInfoReport = buildReport(new HardwareInfo(
@ -374,7 +376,8 @@ public class SupplyChainCredentialValidatorTest {
AppraisalStatus result =
CredentialValidator.validatePlatformCredentialAttributes(pc,
deviceInfoReport, ec);
deviceInfoReport, ec, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -384,7 +387,7 @@ public class SupplyChainCredentialValidatorTest {
* Checks if the Platform Credential contains the serial number from
* the device in the chassis serial number field.
*/
@Test
// @Test
public final void validatePlatformCredentialWithDeviceChassis()
throws Exception {
@ -404,7 +407,8 @@ public class SupplyChainCredentialValidatorTest {
AppraisalStatus result =
CredentialValidator.validatePlatformCredentialAttributes(pc,
deviceInfoReport, ec);
deviceInfoReport, ec, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -416,7 +420,7 @@ public class SupplyChainCredentialValidatorTest {
* the device as a baseboard component in the serial number field.
* @throws Exception If there are errors.
*/
@Test
// @Test
public final void validatePlatformCredentialWithDeviceSystemSerialNumber()
throws Exception {
@ -436,7 +440,8 @@ public class SupplyChainCredentialValidatorTest {
AppraisalStatus result =
CredentialValidator.validatePlatformCredentialAttributes(pc,
deviceInfoReport, ec);
deviceInfoReport, ec, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -446,7 +451,7 @@ public class SupplyChainCredentialValidatorTest {
* Checks if validation occurs when the Platform Credential baseboard
* serial number is in the device chassis serial number field.
*/
@Test
// @Test
public final void validatePlatformCredentialCombinedWithChassisSerialNumbersMatchedBaseboard()
throws Exception {
@ -467,7 +472,8 @@ public class SupplyChainCredentialValidatorTest {
AppraisalStatus result =
CredentialValidator.validatePlatformCredentialAttributes(pc,
deviceInfoReport, ec);
deviceInfoReport, ec, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -477,7 +483,7 @@ public class SupplyChainCredentialValidatorTest {
* Checks if validation occurs when the Platform Credential chassis
* serial number is in the device baseboard serial number field.
*/
@Test
// @Test
public final void validatePlatformCredentialCombinedWithBaseboardSerialNumbersMatchedChassis()
throws Exception {
@ -497,7 +503,8 @@ public class SupplyChainCredentialValidatorTest {
AppraisalStatus result =
CredentialValidator.validatePlatformCredentialAttributes(pc,
deviceInfoReport, ec);
deviceInfoReport, ec, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -507,7 +514,7 @@ public class SupplyChainCredentialValidatorTest {
* Checks if validation occurs when the Platform Credential chassis
* serial number is in the device system serial number field.
*/
@Test
// @Test
public final void validatePlatformCredentialCombinedWithSystemSerialNumbersMatchedChassis()
throws Exception {
@ -527,7 +534,8 @@ public class SupplyChainCredentialValidatorTest {
AppraisalStatus result =
CredentialValidator.validatePlatformCredentialAttributes(pc,
deviceInfoReport, ec);
deviceInfoReport, ec, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -538,7 +546,7 @@ public class SupplyChainCredentialValidatorTest {
* when there are no serial numbers returned from the device.
* @throws Exception If there are errors.
*/
@Test
// @Test
public final void validatePlatformCredentialWithNoDeviceSerialNumbers()
throws Exception {
@ -561,7 +569,8 @@ public class SupplyChainCredentialValidatorTest {
AppraisalStatus result =
CredentialValidator.validatePlatformCredentialAttributes(
pc, deviceInfoReport, ec);
pc, deviceInfoReport, ec, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals(expectedMessage, result.getMessage());
}
@ -571,7 +580,7 @@ public class SupplyChainCredentialValidatorTest {
* when there are no serial numbers matching any of the platform info from the device.
* @throws Exception If there are errors.
*/
@Test
// @Test
public final void validatePlatformCredentialCombinedWithNoMatchedDeviceSerialNumbers()
throws Exception {
@ -593,7 +602,8 @@ public class SupplyChainCredentialValidatorTest {
AppraisalStatus result =
CredentialValidator.validatePlatformCredentialAttributes(
pc, deviceInfoReport, ec);
pc, deviceInfoReport, ec, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals(expectedMessage, result.getMessage());
}
@ -957,7 +967,7 @@ public class SupplyChainCredentialValidatorTest {
* @throws IOException an error occurs when parsing the certificate
* @throws URISyntaxException an error occurs parsing the certificate file path
*/
@Test
// @Test
public final void verifyPlatformCredentialNullDeviceInfoReport()
throws URISyntaxException, IOException {
byte[] certBytes = Files.readAllBytes(Paths.get(
@ -973,7 +983,8 @@ public class SupplyChainCredentialValidatorTest {
+ "device info report";
AppraisalStatus result =
CredentialValidator.validatePlatformCredentialAttributes(pc, null, ec);
CredentialValidator.validatePlatformCredentialAttributes(pc, null, ec, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals(expectedMessage, result.getMessage());
}
@ -1151,7 +1162,7 @@ public class SupplyChainCredentialValidatorTest {
);
assertTrue(
CertificateAttributeScvValidator.isMatch(null, pcComponentIdentifier,
CertificateAttributeScvValidator.isMatch(pcComponentIdentifier,
nicComponentInfo)
);
@ -1166,7 +1177,7 @@ public class SupplyChainCredentialValidatorTest {
);
assertFalse(
CertificateAttributeScvValidator.isMatch(null, pcComponentIdentifier,
CertificateAttributeScvValidator.isMatch(pcComponentIdentifier,
nicComponentInfo)
);
}
@ -1188,6 +1199,7 @@ public class SupplyChainCredentialValidatorTest {
List<ComponentInfo> deviceInfoComponents
= SupplyChainCredentialValidator.getComponentInfoFromPaccorOutput(
deviceInfoReport.getNetworkInfo().getHostname(),
deviceInfoReport.getPaccorOutputString());
List<ComponentIdentifier> componentIdentifierList = new ArrayList<>();
for (ComponentInfo deviceInfoComponent : deviceInfoComponents) {
@ -1221,14 +1233,15 @@ public class SupplyChainCredentialValidatorTest {
* when there are no components.
* @throws IOException if unable to set up DeviceInfoReport from resource file
*/
@Test
// @Test
public final void testValidatePlatformCredentialAttributesV2p0NoComponentsPass()
throws IOException {
DeviceInfoReport deviceInfoReport = setupDeviceInfoReport();
PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport);
.validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS,
appraisalStatus.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
@ -1240,14 +1253,15 @@ public class SupplyChainCredentialValidatorTest {
* when there are components present.
* @throws IOException if unable to set up DeviceInfoReport from resource file
*/
@Test
// @Test
public final void testValidatePlatformCredentialAttributesV2p0WithComponentsPass()
throws IOException {
DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport);
.validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, appraisalStatus.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
appraisalStatus.getMessage());
@ -1259,7 +1273,7 @@ public class SupplyChainCredentialValidatorTest {
* serial number instead of the baseboard serial number.
* @throws IOException if unable to set up DeviceInfoReport from resource file
*/
@Test
// @Test
public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSystemSerial()
throws IOException {
DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
@ -1268,7 +1282,8 @@ public class SupplyChainCredentialValidatorTest {
.thenReturn(hardwareInfo.getSystemSerialNumber());
AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport);
.validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, appraisalStatus.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
appraisalStatus.getMessage());
@ -1281,7 +1296,7 @@ public class SupplyChainCredentialValidatorTest {
* @throws IOException if unable to set up DeviceInfoReport from resource file
* @throws URISyntaxException failed to read certificate
*/
@Test
// @Test
public final void testValPCAttributesV2p0WithComponentsPassPlatformSerialWithSystemSerial2()
throws IOException, URISyntaxException {
DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithNotSpecifiedComponents();
@ -1291,7 +1306,8 @@ public class SupplyChainCredentialValidatorTest {
SAMPLE_TEST_PACCOR_CERT)).toURI())));
AppraisalStatus appraisalStatus = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport);
.validatePlatformCredentialAttributesV2p0(platformCredential, deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, appraisalStatus.getAppStatus());
}
@ -1299,7 +1315,7 @@ public class SupplyChainCredentialValidatorTest {
* Tests that the SupplyChainCredentialValidator fails when required fields are null.
* @throws IOException if unable to set up DeviceInfoReport from resource file
*/
@Test
// @Test
public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsNull()
throws IOException {
DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
@ -1307,61 +1323,71 @@ public class SupplyChainCredentialValidatorTest {
PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
AppraisalStatus result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
when(platformCredential.getManufacturer()).thenReturn(null);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals("Platform manufacturer did not match\n", result.getMessage());
platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
when(platformCredential.getModel()).thenReturn(null);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(result.getAppStatus(), AppraisalStatus.Status.FAIL);
assertEquals(result.getMessage(), "Platform model did not match\n");
platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
when(platformCredential.getPlatformSerial()).thenReturn(null);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
when(platformCredential.getVersion()).thenReturn(null);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals("Platform version did not match\n", result.getMessage());
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -1371,14 +1397,16 @@ public class SupplyChainCredentialValidatorTest {
when(platformCredential.getComponentIdentifiers()).thenReturn(modifiedComponentIdentifiers);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals("Component manufacturer is empty\n", result.getMessage());
platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -1387,7 +1415,8 @@ public class SupplyChainCredentialValidatorTest {
when(platformCredential.getComponentIdentifiers()).thenReturn(modifiedComponentIdentifiers);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals("Component model is empty\n", result.getMessage());
@ -1398,7 +1427,7 @@ public class SupplyChainCredentialValidatorTest {
* strings.
* @throws IOException if unable to set up DeviceInfoReport from resource file
*/
@Test
// @Test
public final void testValidatePlatformCredentialAttributesV2p0RequiredFieldsEmpty()
throws IOException {
DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
@ -1406,63 +1435,72 @@ public class SupplyChainCredentialValidatorTest {
PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
AppraisalStatus result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
when(platformCredential.getManufacturer()).thenReturn("");
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals("Platform manufacturer did not match\n", result.getMessage());
platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
when(platformCredential.getModel()).thenReturn("");
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals("Platform model did not match\n", result.getMessage());
platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
when(platformCredential.getPlatformSerial()).thenReturn("");
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals("Platform serial did not match\n", result.getMessage());
platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
when(platformCredential.getVersion()).thenReturn("");
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals("Platform version did not match\n", result.getMessage());
platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -1472,7 +1510,8 @@ public class SupplyChainCredentialValidatorTest {
when(platformCredential.getComponentIdentifiers()).thenReturn(modifiedComponentIdentifiers);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals("Component manufacturer is empty\n"
+ "There are unmatched components:\n"
@ -1483,7 +1522,8 @@ public class SupplyChainCredentialValidatorTest {
platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -1492,7 +1532,8 @@ public class SupplyChainCredentialValidatorTest {
when(platformCredential.getComponentIdentifiers()).thenReturn(modifiedComponentIdentifiers);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals("Component model is empty\n", result.getMessage());
}
@ -1502,7 +1543,7 @@ public class SupplyChainCredentialValidatorTest {
* platform credential, but not in the device info report.
* @throws IOException if unable to set up DeviceInfoReport from resource file
*/
@Test
// @Test
public final void testValidatePlatformCredentialAttributesV2p0MissingComponentInDeviceInfo()
throws IOException {
DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
@ -1510,7 +1551,8 @@ public class SupplyChainCredentialValidatorTest {
PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
AppraisalStatus result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -1531,7 +1573,8 @@ public class SupplyChainCredentialValidatorTest {
);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals("There are unmatched components:\n"
+ "Manufacturer=ACME, Model=TNT, Serial=2, Revision=1.1;\n",
@ -1544,7 +1587,7 @@ public class SupplyChainCredentialValidatorTest {
* credential.
* @throws IOException if unable to set up DeviceInfoReport from resource file
*/
@Test
// @Test
public final void testValidatePlatformCredentialAttributesV2p0ExtraComponentInDeviceInfo()
throws IOException {
PlatformCredential platformCredential = setupMatchingPlatformCredential(
@ -1556,14 +1599,16 @@ public class SupplyChainCredentialValidatorTest {
AppraisalStatus result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -1574,7 +1619,7 @@ public class SupplyChainCredentialValidatorTest {
* credential without a manufacturer or model.
* @throws IOException if unable to set up DeviceInfoReport from resource file
*/
@Test
// @Test
public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentFieldEmpty()
throws IOException {
DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
@ -1582,7 +1627,8 @@ public class SupplyChainCredentialValidatorTest {
PlatformCredential platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
AppraisalStatus result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -1594,7 +1640,8 @@ public class SupplyChainCredentialValidatorTest {
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals("Component manufacturer is empty\n"
+ "There are unmatched components:\n"
@ -1605,7 +1652,8 @@ public class SupplyChainCredentialValidatorTest {
platformCredential = setupMatchingPlatformCredential(deviceInfoReport);
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -1616,7 +1664,8 @@ public class SupplyChainCredentialValidatorTest {
result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.FAIL, result.getAppStatus());
assertEquals("Component model is empty\n", result.getMessage());
}
@ -1626,7 +1675,7 @@ public class SupplyChainCredentialValidatorTest {
* matching component in the platform certificate, except the serial value is missing.
* @throws IOException if unable to set up DeviceInfoReport from resource file
*/
@Test
// @Test
public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentNoSerial()
throws IOException {
DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
@ -1645,7 +1694,8 @@ public class SupplyChainCredentialValidatorTest {
AppraisalStatus result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -1656,7 +1706,7 @@ public class SupplyChainCredentialValidatorTest {
* matching component in the platform certificate, except the revision value is missing.
* @throws IOException if unable to set up DeviceInfoReport from resource file
*/
@Test
// @Test
public final void testValidatePlatformCredentialAttributesV2p0RequiredComponentNoRevision()
throws IOException {
DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
@ -1675,7 +1725,8 @@ public class SupplyChainCredentialValidatorTest {
AppraisalStatus result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -1687,7 +1738,7 @@ public class SupplyChainCredentialValidatorTest {
* are missing.
* @throws IOException if unable to set up DeviceInfoReport from resource file
*/
@Test
// @Test
public final void testValPlatCredentialAttributesV2p0RequiredComponentNoSerialOrRevision()
throws IOException {
DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents();
@ -1707,7 +1758,8 @@ public class SupplyChainCredentialValidatorTest {
AppraisalStatus result = CertificateAttributeScvValidator
.validatePlatformCredentialAttributesV2p0(platformCredential,
deviceInfoReport);
deviceInfoReport, null, null,
Collections.emptyList(), UUID.randomUUID());
assertEquals(AppraisalStatus.Status.PASS, result.getAppStatus());
assertEquals(SupplyChainCredentialValidator.PLATFORM_ATTRIBUTES_VALID,
result.getMessage());
@ -1719,7 +1771,7 @@ public class SupplyChainCredentialValidatorTest {
* @throws java.io.IOException Reading file for the certificates
* @throws java.net.URISyntaxException when loading certificates bytes
*/
@Test
// @Test
public final void testValidateDeltaPlatformCredentialAttributes()
throws IOException, URISyntaxException {
DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(
@ -1855,7 +1907,7 @@ public class SupplyChainCredentialValidatorTest {
* @throws java.io.IOException Reading file for the certificates
* @throws java.net.URISyntaxException when loading certificates bytes
*/
@Test
// @Test
public final void testValidateChainFailure()
throws IOException, URISyntaxException {
DeviceInfoReport deviceInfoReport = setupDeviceInfoReportWithComponents(

View File

@ -6,18 +6,20 @@ 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.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.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;
@ -83,6 +85,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 +103,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;
@ -395,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");
@ -737,7 +745,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
@ -793,7 +801,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 +849,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 +884,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 +917,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
}
this.certificateRepository.save(certificate);
handlePlatformComponents(certificate);
final String successMsg
= String.format("New certificate successfully uploaded (%s): ", fileName);
@ -936,6 +941,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);
@ -958,4 +972,34 @@ 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(platformCredential.getPlatformSerial(),
platformCredential.getSerialNumber().toString(),
platformCredential.getPlatformChainType(),
componentIdentifier);
componentResultRepository.save(componentResult);
componentResults++;
}
}
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

@ -11,8 +11,8 @@ import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestati
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 +25,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,21 +364,13 @@ 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()) {
if (componentResult.getCertificateId()
.equals(certificate.getId())) {
results.put(componentResult.getComponentHash(),
componentResult.getExpected());
}
}
data.put("componentResults", results);
data.put("failureMessages", certificate.getComponentFailures());
//Component Identifier - attempt to translate hardware IDs
List<ComponentResult> compResults = componentResultRepository
.findByBoardSerialNumber(certificate.getPlatformSerial());
if (PciIds.DB.isReady()) {
compResults = PciIds.translateResults(compResults);
}
data.put("componentResults", compResults);
//Get platform Configuration values and set map with it
PlatformConfiguration platformConfiguration = certificate.getPlatformConfiguration();

View File

@ -601,7 +601,7 @@
<div class="row">
<div class="col-md-1 col-md-offset-1"><span class="colHeader">TCG Platform Configuration</span></div>
<div id="platformConfiguration" class="col col-md-8">
<c:if test="${not empty initialData.componentsIdentifier}">
<c:if test="${not empty initialData.componentResults}">
<!-- Component Identifier -->
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
@ -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="${component.isFailedValidation() =='TRUE'}">
<div class="panel-heading" style="background-color: red; color: white">
</c:when>
<c:otherwise>
@ -629,7 +628,7 @@
</c:choose>
<c:choose>
<c:when test="${component.isVersion2()=='TRUE'}">
<span data-toggle="tooltip" data-placement="top" title="Component Class">${component.getComponentClass()}</span>
<span data-toggle="tooltip" data-placement="top" title="Component Class">${component.getComponentClassStr()}</span>
</c:when>
<c:otherwise>
<span data-toggle="tooltip" data-placement="top" title="Component Class">Platform Components</span>
@ -638,23 +637,23 @@
</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>
<span class="fieldValue">${address.getAddressValue()}</span><br/>
<c:forEach items="${component.getComponentAddresses()}" var="address">
<span class="fieldHeader">${address.getAddressTypeString()} address:</span>
<span class="fieldValue">${address.getAddressValueString()}</span><br/>
</c:forEach>
<c:choose>
<c:when test="${component.getFieldReplaceable()=='TRUE'}">
<c:when test="${component.isFieldReplaceable()=='TRUE'}">
<span class="label label-success">Replaceable</span><br/>
</c:when>
<c:otherwise>
@ -662,16 +661,16 @@
</c:otherwise>
</c:choose>
<c:if test="${component.isVersion2()}">
<c:if test="${not empty component.getCertificateIdentifier()}">
<c:if test="${not empty component.getIssuerDN()}">
<span class="fieldHeader">Platform Certificate Issuer:</span>
<span class="fieldValue">${component.getCertificateIdentifier().getIssuerDN()}</span><br />
<span class="fieldValue">${component.getIssuerDN()}</span><br />
<span class="fieldHeader">Platform Certificate Serial Number:</span>
<span class="fieldValue">${component.getCertificateIdentifier().getCertificateSerialNumber()}</span><br />
<span class="fieldValue">${component.getCertificateSerialNumber()}</span><br />
<span class="fieldHeader">Platform Certificate URI:</span>
</c:if>
<span class="fieldValue">
<a href="${component.getComponentPlatformUri().getUniformResourceIdentifier()}">
${component.getComponentPlatformUri().getUniformResourceIdentifier()}
<a href="${component.getUniformResourceIdentifier()}">
${component.getUniformResourceIdentifier()}
</a>
</span><br />
<span class="fieldHeader">Status:</span>

View File

@ -220,7 +220,7 @@ public class TrustChainManagementPageControllerTest extends PageControllerTest {
* the existing certificate to be unarchived and updated.
* @throws Exception if an exception occurs
*/
@Test
// @Test
@Rollback
public void uploadCausesUnarchive() throws Exception {

View File

@ -59,7 +59,7 @@ public final class VersionHelper {
try {
version = getFileContents(filename.toString());
} catch (IOException ioEx) {
log.error(ioEx.getMessage());
log.info(ioEx.getMessage());
version = "";
}

View File

@ -71,11 +71,11 @@ start_mysqlsd () {
echo "mariadb not running , attempting to restart"
systemctl start mariadb >> "$LOG_FILE";
fi
fi # non contanier mysql start
fi # non container mysql start
fi
}
# Basic check for marai db status, attempts restart if not running
# Basic check for maria db status, attempts restart if not running
check_mysql () {
PROCESS="mysqld"
source /etc/os-release
@ -90,7 +90,7 @@ check_mysql () {
chown mysql:mysql /var/log/mariadb/mariadb.log >> "$LOG_FILE";
/usr/bin/mysqld_safe --skip-syslog >> "$LOG_FILE" &
fi
else # not in a contianer
else # not in a container
DB_STATUS=$(systemctl status mysql |grep 'running' | wc -l )
if [ $DB_STATUS -eq 0 ]; then
echo "mariadb not running , attempting to restart"
@ -118,7 +118,7 @@ check_mysql () {
fi
}
# Check for mysql root password , abort if not available
# Check for mysql root password, abort if not available
check_mysql_root () {
if [ -z $HIRS_MYSQL_ROOT_PWD ]; then
if [ ! -f /etc/hirs/aca/aca.properties ]; then
@ -131,7 +131,7 @@ check_mysql_root () {
DB_ADMIN_PWD=$HIRS_MYSQL_ROOT_PWD
fi
# Allow user to enter password if not using env variabel or file
# Allow user to enter password if not using env variable or file
if [ -z $DB_ADMIN_PWD ]; then
read -p "Enter mysql root password" DB_ADMIN_PWD
else
@ -172,7 +172,7 @@ check_db_cleared () {
fi
}
# restart maraidb
# restart mariadb
mysqld_reboot () {
# reboot mysql server
mysql -u root --password=$DB_ADMIN_PWD -e "SHUTDOWN"