Validation bug (#263)

* Updated code to correctly match up the PCR to the baseline PCR.  Also updated values of error messages and reduced firmware error message.
This commit is contained in:
Cyrus 2020-06-15 11:55:05 -04:00 committed by GitHub
parent 7ab7408b59
commit 49e4ce4db4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 39 additions and 41 deletions

View File

@ -7,7 +7,6 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import hirs.data.persist.TPMMeasurementRecord; import hirs.data.persist.TPMMeasurementRecord;
import hirs.data.persist.baseline.TPMBaseline;
import hirs.data.persist.SwidResource; import hirs.data.persist.SwidResource;
import hirs.validation.SupplyChainCredentialValidator; import hirs.validation.SupplyChainCredentialValidator;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@ -119,6 +118,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
supplyChainAppraiser); supplyChainAppraiser);
boolean acceptExpiredCerts = policy.isExpiredCertificateValidationEnabled(); boolean acceptExpiredCerts = policy.isExpiredCertificateValidationEnabled();
PlatformCredential baseCredential = null; PlatformCredential baseCredential = null;
String componentFailures = "";
List<SupplyChainValidation> validations = new LinkedList<>(); List<SupplyChainValidation> validations = new LinkedList<>();
Map<PlatformCredential, SupplyChainValidation> deltaMapping = new HashMap<>(); Map<PlatformCredential, SupplyChainValidation> deltaMapping = new HashMap<>();
SupplyChainValidation platformScv = null; SupplyChainValidation platformScv = null;
@ -221,6 +221,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
String.format("%s%n%s", platformScv.getMessage(), String.format("%s%n%s", platformScv.getMessage(),
attributeScv.getMessage()))); attributeScv.getMessage())));
} }
componentFailures = attributeScv.getMessage();
} }
pc.setDevice(device); pc.setDevice(device);
@ -235,12 +236,10 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
// compare tpm quote with what is pulled from RIM associated file // compare tpm quote with what is pulled from RIM associated file
IssuedAttestationCertificate attCert = IssuedAttestationCertificate IssuedAttestationCertificate attCert = IssuedAttestationCertificate
.select(this.certificateManager) .select(this.certificateManager)
.byDeviceId(device.getId()) .byDeviceId(device.getId()).getCertificate();
.getCertificate();
PlatformCredential pc = PlatformCredential PlatformCredential pc = PlatformCredential
.select(this.certificateManager) .select(this.certificateManager)
.byDeviceId(device.getId()) .byDeviceId(device.getId()).getCertificate();
.getCertificate();
validations.add(validateFirmware(pc, attCert)); validations.add(validateFirmware(pc, attCert));
} }
@ -249,7 +248,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
SupplyChainValidationSummary summary SupplyChainValidationSummary summary
= new SupplyChainValidationSummary(device, validations); = new SupplyChainValidationSummary(device, validations);
if (baseCredential != null) { if (baseCredential != null) {
baseCredential.setComponentFailures(summary.getMessage()); baseCredential.setComponentFailures(componentFailures);
this.certificateManager.update(baseCredential); this.certificateManager.update(baseCredential);
} }
try { try {
@ -325,29 +324,17 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
private SupplyChainValidation validateFirmware(final PlatformCredential pc, private SupplyChainValidation validateFirmware(final PlatformCredential pc,
final IssuedAttestationCertificate attCert) { final IssuedAttestationCertificate attCert) {
TPMBaseline tpmBline; ReferenceManifest rim = null;
String[] baseline = new String[Integer.SIZE]; String[] baseline = new String[Integer.SIZE];
Level level = Level.ERROR; Level level = Level.ERROR;
AppraisalStatus fwStatus; AppraisalStatus fwStatus;
if (attCert != null) { if (attCert != null) {
LOGGER.error(attCert.getPcrValues());
String[] pcrsSet = attCert.getPcrValues().split("\\+"); String[] pcrsSet = attCert.getPcrValues().split("\\+");
String[] pcrs1 = pcrsSet[0].split("\\n"); String[] pcrs1 = pcrsSet[0].split("\\n");
String[] pcrs256 = pcrsSet[1].split("\\n"); String[] pcrs256 = pcrsSet[1].split("\\n");
for (int i = 0; i < pcrs1.length; i++) {
if (pcrs1[i].contains(":")) {
pcrs1[i].split(":");
}
}
for (int i = 0; i < pcrs256.length; i++) { rim = ReferenceManifest.select(
if (pcrs256[i].contains(":")) {
pcrs256[i].split(":");
}
}
ReferenceManifest rim = ReferenceManifest.select(
this.referenceManifestManager) this.referenceManifestManager)
.byManufacturer(pc.getManufacturer()) .byManufacturer(pc.getManufacturer())
.getRIM(); .getRIM();
@ -360,34 +347,31 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
fwStatus = new AppraisalStatus(PASS, fwStatus = new AppraisalStatus(PASS,
SupplyChainCredentialValidator.FIRMWARE_VALID); SupplyChainCredentialValidator.FIRMWARE_VALID);
String failureMsg = "Firmware validation failed: PCR %d does not" String failureMsg = "Firmware validation failed: PCR %s does not"
+ " match%n%tBaseline [%s] <> Device [%s]%n"; + " match%n";
List<SwidResource> swids = rim.parseResource(); List<SwidResource> swids = rim.parseResource();
for (SwidResource swid : swids) { for (SwidResource swid : swids) {
baseline = swid.getPcrValues() baseline = swid.getPcrValues()
.toArray(new String[swid.getPcrValues().size()]); .toArray(new String[swid.getPcrValues().size()]);
} }
/**
* baseline is null. The purpose of the if check was to String pcrNum;
* determine to process doing pcrs1 or pcrs256. So I have to String pcrValue;
* rethink this. if (baseline[0].length() == TPMMeasurementRecord.SHA_BYTE_LENGTH) {
*
* this goes back to not knowing if I should do one or the other
* and how to make that a setting of some kind.
*/
if (baseline[0].length() == pcrs1[0].length()) {
for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) { for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) {
if (!baseline[i].equals(pcrs1[i])) { pcrNum = pcrs1[i + 1].split(":")[0].trim();
sb.append(String.format(failureMsg, i, baseline[i], pcrs1[i])); pcrValue = pcrs1[i + 1].split(":")[1].trim();
break; if (!baseline[i].equals(pcrValue)) {
sb.append(String.format(failureMsg, pcrNum));
} }
} }
} else if (baseline[0].length() == pcrs256[0].length()) { } else if (baseline[0].length() == TPMMeasurementRecord.SHA_256_BYTE_LENGTH) {
for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) { for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) {
if (!baseline[i].equals(pcrs256[i])) { pcrNum = pcrs256[i + 1].split(":")[0].trim();
sb.append(String.format(failureMsg, i, baseline[i], pcrs256[i])); pcrValue = pcrs256[i + 1].split(":")[1].trim();
break; if (!baseline[i].equals(pcrValue)) {
sb.append(String.format(failureMsg, pcrNum));
} }
} }
} }

View File

@ -10,6 +10,11 @@ import javax.persistence.MappedSuperclass;
@MappedSuperclass @MappedSuperclass
public abstract class ArchivableEntity extends AbstractEntity { public abstract class ArchivableEntity extends AbstractEntity {
/**
* Defining the size of a message field for error display.
*/
public static final int MAX_MESSAGE_LENGTH = 520;
@Column(name = "archived_time") @Column(name = "archived_time")
private Date archivedTime; private Date archivedTime;

View File

@ -53,7 +53,7 @@ public class SupplyChainValidation extends ArchivableEntity {
joinColumns = { @JoinColumn(name = "validation_id", nullable = false) }) joinColumns = { @JoinColumn(name = "validation_id", nullable = false) })
private final List<Certificate> certificatesUsed; private final List<Certificate> certificatesUsed;
@Column @Column(length = MAX_MESSAGE_LENGTH)
private final String message; private final String message;
/** /**

View File

@ -248,7 +248,6 @@ public class SupplyChainValidationSummary extends ArchivableEntity {
default: default:
break; break;
} }
} }
// if failures, but no error, indicate failure result. // if failures, but no error, indicate failure result.
if (hasAnyFailures) { if (hasAnyFailures) {

View File

@ -34,6 +34,16 @@ public final class TPMMeasurementRecord extends ExaminableRecord {
*/ */
public static final int MAX_PCR_ID = 23; public static final int MAX_PCR_ID = 23;
/**
* String length of a SHA 1 PCR value.
*/
public static final int SHA_BYTE_LENGTH = 40;
/**
* String length of a 256 SHA PCR value.
*/
public static final int SHA_256_BYTE_LENGTH = 64;
private static final Logger LOGGER = private static final Logger LOGGER =
LogManager.getLogger(TPMMeasurementRecord.class); LogManager.getLogger(TPMMeasurementRecord.class);

View File

@ -240,7 +240,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
@Column @Column
private String platformClass = null; private String platformClass = null;
@Column @Column(length = MAX_MESSAGE_LENGTH)
private String componentFailures = Strings.EMPTY; private String componentFailures = Strings.EMPTY;
@Transient @Transient