mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-04-08 11:54:27 +00:00
This is the next stage of changes that doesn't cause a 404 error. This has a compile error because the PCRPolicy class references PCRComposite and PCRInfoShort. Both of the later classes had changes to add new constructors, and these new constructors are the source of the problem.
This commit is contained in:
parent
ee294e4562
commit
905f12052d
@ -166,8 +166,8 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
private final DeviceRegister deviceRegister;
|
||||
private final DeviceManager deviceManager;
|
||||
private final DBManager<TPM2ProvisionerState> tpm2ProvisionerStateDBManager;
|
||||
private String tpmQuoteHash;
|
||||
private String tpmSignatureHash;
|
||||
private String tpmQuoteHash = "";
|
||||
private String tpmSignatureHash = "";
|
||||
private String pcrValues;
|
||||
|
||||
/**
|
||||
@ -463,6 +463,32 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs supply chain validation for just the quote under Firmware validation.
|
||||
* Performed after main supply chain validation and a certificate request.
|
||||
*
|
||||
* @param device associated device to validate.
|
||||
* @return the {@link AppraisalStatus} of the supply chain validation
|
||||
*/
|
||||
private AppraisalStatus.Status doQuoteValidation(final Device device) {
|
||||
// perform supply chain validation
|
||||
SupplyChainValidationSummary scvs = supplyChainValidationService.validateQuote(device);
|
||||
AppraisalStatus.Status validationResult;
|
||||
|
||||
// either validation wasn't enabled or device already failed
|
||||
if (scvs == null) {
|
||||
// this will just allow for the certificate to be saved.
|
||||
validationResult = AppraisalStatus.Status.PASS;
|
||||
} else {
|
||||
// update the validation result in the device
|
||||
validationResult = scvs.getOverallValidationResult();
|
||||
device.setSupplyChainStatus(validationResult);
|
||||
deviceManager.updateDevice(device);
|
||||
}
|
||||
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic implementation of the ACA processCertificateRequest method.
|
||||
* Parses the nonce, validates its correctness, generates the signed,
|
||||
|
@ -1,9 +1,6 @@
|
||||
package hirs.attestationca.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@ -40,7 +37,6 @@ import hirs.data.persist.certificate.Certificate;
|
||||
import hirs.data.persist.certificate.CertificateAuthorityCredential;
|
||||
import hirs.data.persist.certificate.EndorsementCredential;
|
||||
import hirs.data.persist.certificate.PlatformCredential;
|
||||
import hirs.data.persist.certificate.IssuedAttestationCertificate;
|
||||
import hirs.data.persist.ReferenceManifest;
|
||||
import hirs.persist.AppraiserManager;
|
||||
import hirs.persist.CertificateManager;
|
||||
@ -274,7 +270,8 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
SupplyChainPolicy policy = (SupplyChainPolicy) policyManager.getDefaultPolicy(
|
||||
supplyChainAppraiser);
|
||||
SupplyChainValidation quoteScv = null;
|
||||
SupplyChainValidationSummary summary = supplyChainValidatorSummaryManager.get(device.getId());
|
||||
SupplyChainValidationSummary summary = supplyChainValidatorSummaryManager
|
||||
.get(device.getId());
|
||||
Level level = Level.ERROR;
|
||||
AppraisalStatus fwStatus = new AppraisalStatus(FAIL,
|
||||
SupplyChainCredentialValidator.FIRMWARE_VALID);
|
||||
@ -313,7 +310,8 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
// byte[] signature = device.getDeviceInfo().getTPMInfo().getTpmQuoteHash();
|
||||
//
|
||||
// if (!pcrPolicy.validateQuote(hash)) {
|
||||
// quoteScv = buildValidationRecord(SupplyChainValidation.ValidationType.FIRMWARE,
|
||||
// quoteScv = buildValidationRecord(SupplyChainValidation
|
||||
// .ValidationType.FIRMWARE,
|
||||
// fwStatus.getAppStatus(),
|
||||
// "Firmware validation of TPM Quote failed.", rim, level);
|
||||
// }
|
||||
@ -397,9 +395,6 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
String manufacturer = device.getDeviceInfo()
|
||||
.getHardwareInfo().getManufacturer();
|
||||
|
||||
IssuedAttestationCertificate attCert = IssuedAttestationCertificate
|
||||
.select(this.certificateManager)
|
||||
.byDeviceId(device.getId()).getCertificate();
|
||||
ReferenceManifest rim = ReferenceManifest.select(
|
||||
this.referenceManifestManager)
|
||||
.byManufacturer(manufacturer)
|
||||
@ -420,18 +415,15 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
}
|
||||
pcrPolicy.setBaselinePcrs(baseline);
|
||||
|
||||
if (attCert != null) {
|
||||
Path pcrPath = Paths.get("");
|
||||
if (device != null) {
|
||||
String pcrContent = "";
|
||||
if (Files.exists(pcrPath)) {
|
||||
try {
|
||||
pcrContent = new String(Files.readAllBytes(pcrPath), "UTF8");
|
||||
} catch (IOException ioEx) {
|
||||
LOGGER.error(ioEx);
|
||||
}
|
||||
try {
|
||||
pcrContent = new String(device.getDeviceInfo().getTPMInfo().getPcrValues());
|
||||
} catch (NullPointerException npEx) {
|
||||
LOGGER.error(npEx);
|
||||
}
|
||||
String[] pcrSet = null;
|
||||
String[] quote = null;
|
||||
String[] storedPcrs = null;
|
||||
int algorithmLength = baseline[0].length();
|
||||
|
||||
if (pcrContent.isEmpty()) {
|
||||
@ -440,11 +432,11 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
+ "provide pcr values.");
|
||||
LOGGER.warn(String.format(
|
||||
"Firmware validation failed: Client (%s) did not "
|
||||
+ "provide pcr values.", attCert.getDevice().getName()));
|
||||
+ "provide pcr values.", device.getName()));
|
||||
} else {
|
||||
// we have a full set of PCR values
|
||||
pcrSet = pcrContent.split("\\n");
|
||||
quote = new String[TPMMeasurementRecord.MAX_PCR_ID + 1];
|
||||
storedPcrs = new String[TPMMeasurementRecord.MAX_PCR_ID + 1];
|
||||
|
||||
// we need to scroll through the entire list until we find
|
||||
// a matching hash length
|
||||
@ -457,14 +449,14 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
== algorithmLength) {
|
||||
// found the matching set
|
||||
for (int j = 0; j <= TPMMeasurementRecord.MAX_PCR_ID; j++) {
|
||||
quote[j] = pcrSet[++i].split(":")[1].trim();
|
||||
storedPcrs[j] = pcrSet[++i].split(":")[1].trim();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (quote[0].isEmpty()) {
|
||||
if (storedPcrs[0].isEmpty()) {
|
||||
// validation fail
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
"Firmware validation failed: "
|
||||
@ -472,7 +464,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
+ "values are not the same algorithm "
|
||||
+ "as associated RIM.");
|
||||
} else {
|
||||
StringBuilder sb = pcrPolicy.validatePcrs(quote);
|
||||
StringBuilder sb = pcrPolicy.validatePcrs(storedPcrs);
|
||||
if (sb.length() > 0) {
|
||||
level = Level.ERROR;
|
||||
fwStatus = new AppraisalStatus(FAIL, sb.toString());
|
||||
|
@ -3,8 +3,18 @@ package hirs.data.persist;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import static org.apache.logging.log4j.LogManager.getLogger;
|
||||
|
||||
import hirs.data.persist.tpm.PcrComposite;
|
||||
import hirs.data.persist.tpm.PcrInfoShort;
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The class handles the flags that ignore certain PCRs for validation.
|
||||
*/
|
||||
@ -28,23 +38,28 @@ public final class PCRPolicy extends Policy {
|
||||
private boolean linuxOs = false;
|
||||
|
||||
private String[] baselinePcrs;
|
||||
private List<TPMMeasurementRecord> measurements;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public PCRPolicy() {
|
||||
baselinePcrs = new String[TPMMeasurementRecord.MAX_PCR_ID + 1];
|
||||
measurements = new ArrayList<>(baselinePcrs.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to parse PCR values.
|
||||
*
|
||||
* @param pcrValues RIM provided baseline PCRs
|
||||
* @throws DecoderException if byte array could not be decoded.
|
||||
*/
|
||||
public PCRPolicy(final String[] pcrValues) {
|
||||
public PCRPolicy(final String[] pcrValues) throws DecoderException {
|
||||
baselinePcrs = new String[TPMMeasurementRecord.MAX_PCR_ID + 1];
|
||||
measurements = new ArrayList<>(baselinePcrs.length);
|
||||
for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) {
|
||||
baselinePcrs[i] = pcrValues[i];
|
||||
measurements.add(new TPMMeasurementRecord(i, pcrValues[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,10 +67,10 @@ public final class PCRPolicy extends Policy {
|
||||
* Compares the baseline pcr list and the quote pcr list. If the
|
||||
* ignore flags are set, 10 and 17-19 will be skipped for comparison.
|
||||
*
|
||||
* @param quotePcrs non-baseline pcr list
|
||||
* @param storedPcrs non-baseline pcr list
|
||||
* @return a StringBuilder that is empty if everything passes.
|
||||
*/
|
||||
public StringBuilder validatePcrs(final String[] quotePcrs) {
|
||||
public StringBuilder validatePcrs(final String[] storedPcrs) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String failureMsg = "PCR %d does not match%n";
|
||||
|
||||
@ -70,7 +85,7 @@ public final class PCRPolicy extends Policy {
|
||||
i += NUM_OF_TBOOT_PCR;
|
||||
}
|
||||
|
||||
if (!baselinePcrs[i].equals(quotePcrs[i])) {
|
||||
if (!baselinePcrs[i].equals(storedPcrs[i])) {
|
||||
sb.append(String.format(failureMsg, i));
|
||||
}
|
||||
}
|
||||
@ -78,6 +93,40 @@ public final class PCRPolicy extends Policy {
|
||||
return sb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares hashs to validate the quote from the client.
|
||||
*
|
||||
* @param tpmQuote the provided quote
|
||||
* @return true if validated, false if not
|
||||
*/
|
||||
public boolean validateQuote(final byte[] tpmQuote) {
|
||||
boolean validated = false;
|
||||
|
||||
short localityAtRelease = 0;
|
||||
PcrComposite pcrComposite = new PcrComposite(this.measurements);
|
||||
PcrInfoShort pcrInfoShort = new PcrInfoShort(localityAtRelease,
|
||||
tpmQuote, pcrComposite);
|
||||
|
||||
try {
|
||||
if (!Arrays.equals(pcrInfoShort.getCalculatedDigest(),
|
||||
pcrInfoShort.getCompositeHash())) {
|
||||
LOGGER.error("This is NOT matching: ");
|
||||
LOGGER.error(new String(pcrInfoShort.getCalculatedDigest(), "UTF-8"));
|
||||
LOGGER.error(new String(pcrInfoShort.getCompositeHash(), "UTF-8"));
|
||||
} else {
|
||||
LOGGER.error("This is matching: ");
|
||||
LOGGER.error(new String(pcrInfoShort.getCalculatedDigest(), "UTF-8"));
|
||||
LOGGER.error(new String(pcrInfoShort.getCompositeHash(), "UTF-8"));
|
||||
}
|
||||
} catch (NoSuchAlgorithmException naEx) {
|
||||
LOGGER.error(naEx);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return validated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the array of baseline PCRs.
|
||||
* @return instance of the PCRs.
|
||||
|
@ -24,6 +24,7 @@ import org.hibernate.annotations.Type;
|
||||
@Embeddable
|
||||
public class TPMInfo implements Serializable {
|
||||
private static final Logger LOGGER = LogManager.getLogger(TPMInfo.class);
|
||||
private static final int MAX_BLOB_SIZE = 65535;
|
||||
|
||||
@XmlElement
|
||||
@Column(length = DeviceInfoReport.MED_STRING_LENGTH, nullable = true)
|
||||
@ -52,6 +53,15 @@ public class TPMInfo implements Serializable {
|
||||
@JsonIgnore
|
||||
private X509Certificate identityCertificate;
|
||||
|
||||
@Column(nullable = true, length = MAX_BLOB_SIZE)
|
||||
private byte[] pcrValues;
|
||||
|
||||
@Column(nullable = true, length = MAX_BLOB_SIZE)
|
||||
private byte[] tpmQuoteHash;
|
||||
|
||||
@Column(nullable = true, length = MAX_BLOB_SIZE)
|
||||
private byte[] tpmQuoteSignature;
|
||||
|
||||
/**
|
||||
* Constructor used to create a TPMInfo object.
|
||||
*
|
||||
@ -68,17 +78,65 @@ public class TPMInfo implements Serializable {
|
||||
* short representing the minor revision number for the TPM
|
||||
* @param identityCertificate
|
||||
* byte array with the value of the identity certificate
|
||||
* @param pcrValues
|
||||
* short representing the major revision number for the TPM
|
||||
* @param tpmQuoteHash
|
||||
* short representing the minor revision number for the TPM
|
||||
* @param tpmQuoteSignature
|
||||
* byte array with the value of the identity certificate
|
||||
*/
|
||||
@SuppressWarnings("parameternumber")
|
||||
public TPMInfo(final String tpmMake, final short tpmVersionMajor,
|
||||
final short tpmVersionMinor, final short tpmVersionRevMajor,
|
||||
final short tpmVersionRevMinor,
|
||||
final X509Certificate identityCertificate) {
|
||||
final X509Certificate identityCertificate, final byte[] pcrValues,
|
||||
final byte[] tpmQuoteHash, final byte[] tpmQuoteSignature) {
|
||||
setTPMMake(tpmMake);
|
||||
setTPMVersionMajor(tpmVersionMajor);
|
||||
setTPMVersionMinor(tpmVersionMinor);
|
||||
setTPMVersionRevMajor(tpmVersionRevMajor);
|
||||
setTPMVersionRevMinor(tpmVersionRevMinor);
|
||||
setIdentityCertificate(identityCertificate);
|
||||
setPcrValues(pcrValues);
|
||||
setTpmQuoteHash(tpmQuoteHash);
|
||||
setTpmQuoteSignature(tpmQuoteSignature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used to create a TPMInfo object without an identity
|
||||
* certificate.
|
||||
*
|
||||
* @param tpmMake
|
||||
* String representing the make information for the TPM,
|
||||
* NullPointerException thrown if null
|
||||
* @param tpmVersionMajor
|
||||
* short representing the major version number for the TPM
|
||||
* @param tpmVersionMinor
|
||||
* short representing the minor version number for the TPM
|
||||
* @param tpmVersionRevMajor
|
||||
* short representing the major revision number for the TPM
|
||||
* @param tpmVersionRevMinor
|
||||
* short representing the minor revision number for the TPM
|
||||
* @param pcrValues
|
||||
* short representing the major revision number for the TPM
|
||||
* @param tpmQuoteHash
|
||||
* short representing the minor revision number for the TPM
|
||||
* @param tpmQuoteSignature
|
||||
* byte array with the value of the identity certificate
|
||||
*/
|
||||
@SuppressWarnings("parameternumber")
|
||||
public TPMInfo(final String tpmMake, final short tpmVersionMajor,
|
||||
final short tpmVersionMinor, final short tpmVersionRevMajor,
|
||||
final short tpmVersionRevMinor, final byte[] pcrValues,
|
||||
final byte[] tpmQuoteHash, final byte[] tpmQuoteSignature) {
|
||||
setTPMMake(tpmMake);
|
||||
setTPMVersionMajor(tpmVersionMajor);
|
||||
setTPMVersionMinor(tpmVersionMinor);
|
||||
setTPMVersionRevMajor(tpmVersionRevMajor);
|
||||
setTPMVersionRevMinor(tpmVersionRevMinor);
|
||||
setPcrValues(pcrValues);
|
||||
setTpmQuoteHash(tpmQuoteHash);
|
||||
setTpmQuoteSignature(tpmQuoteSignature);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,13 +156,38 @@ public class TPMInfo implements Serializable {
|
||||
* short representing the minor revision number for the TPM
|
||||
*/
|
||||
public TPMInfo(final String tpmMake, final short tpmVersionMajor,
|
||||
final short tpmVersionMinor, final short tpmVersionRevMajor,
|
||||
final short tpmVersionRevMinor) {
|
||||
setTPMMake(tpmMake);
|
||||
setTPMVersionMajor(tpmVersionMajor);
|
||||
setTPMVersionMinor(tpmVersionMinor);
|
||||
setTPMVersionRevMajor(tpmVersionRevMajor);
|
||||
setTPMVersionRevMinor(tpmVersionRevMinor);
|
||||
final short tpmVersionMinor, final short tpmVersionRevMajor,
|
||||
final short tpmVersionRevMinor) {
|
||||
this(tpmMake, tpmVersionMajor, tpmVersionMinor, tpmVersionRevMajor,
|
||||
tpmVersionRevMinor, null,
|
||||
new byte[0], new byte[0], new byte[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used to create a TPMInfo object without an identity
|
||||
* certificate.
|
||||
*
|
||||
* @param tpmMake
|
||||
* String representing the make information for the TPM,
|
||||
* NullPointerException thrown if null
|
||||
* @param tpmVersionMajor
|
||||
* short representing the major version number for the TPM
|
||||
* @param tpmVersionMinor
|
||||
* short representing the minor version number for the TPM
|
||||
* @param tpmVersionRevMajor
|
||||
* short representing the major revision number for the TPM
|
||||
* @param tpmVersionRevMinor
|
||||
* short representing the minor revision number for the TPM
|
||||
* @param identityCertificate
|
||||
* byte array with the value of the identity certificate
|
||||
*/
|
||||
public TPMInfo(final String tpmMake, final short tpmVersionMajor,
|
||||
final short tpmVersionMinor, final short tpmVersionRevMajor,
|
||||
final short tpmVersionRevMinor,
|
||||
final X509Certificate identityCertificate) {
|
||||
this(tpmMake, tpmVersionMajor, tpmVersionMinor, tpmVersionRevMajor,
|
||||
tpmVersionRevMinor, identityCertificate,
|
||||
new byte[0], new byte[0], new byte[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,10 +195,13 @@ public class TPMInfo implements Serializable {
|
||||
*/
|
||||
public TPMInfo() {
|
||||
this(DeviceInfoReport.NOT_SPECIFIED,
|
||||
(short) 0,
|
||||
(short) 0,
|
||||
(short) 0,
|
||||
(short) 0);
|
||||
(short) 0,
|
||||
(short) 0,
|
||||
(short) 0,
|
||||
(short) 0,
|
||||
new byte[0],
|
||||
new byte[0],
|
||||
new byte[0]);
|
||||
identityCertificate = null;
|
||||
}
|
||||
|
||||
@ -175,6 +261,30 @@ public class TPMInfo implements Serializable {
|
||||
return identityCertificate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the tpmQuote passed up by the client.
|
||||
* @return a byte blob of quote
|
||||
*/
|
||||
public final byte[] getTpmQuoteHash() {
|
||||
return tpmQuoteHash.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the quote signature.
|
||||
* @return a byte blob.
|
||||
*/
|
||||
public final byte[] getTpmQuoteSignature() {
|
||||
return tpmQuoteSignature.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the pcr values.
|
||||
* @return a byte blob for the pcrValues.
|
||||
*/
|
||||
public final byte[] getPcrValues() {
|
||||
return pcrValues.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
final int prime = 31;
|
||||
@ -285,4 +395,28 @@ public class TPMInfo implements Serializable {
|
||||
LOGGER.debug("setting identity certificate");
|
||||
this.identityCertificate = identityCertificate;
|
||||
}
|
||||
|
||||
private void setPcrValues(final byte[] pcrValues) {
|
||||
if (pcrValues == null) {
|
||||
this.pcrValues = new byte[0];
|
||||
} else {
|
||||
this.pcrValues = pcrValues.clone();
|
||||
}
|
||||
}
|
||||
|
||||
private void setTpmQuoteHash(final byte[] tpmQuoteHash) {
|
||||
if (tpmQuoteHash == null) {
|
||||
this.tpmQuoteHash = new byte[0];
|
||||
} else {
|
||||
this.tpmQuoteHash = tpmQuoteHash.clone();
|
||||
}
|
||||
}
|
||||
|
||||
private void setTpmQuoteSignature(final byte[] tpmQuoteSignature) {
|
||||
if (tpmQuoteSignature == null) {
|
||||
this.tpmQuoteSignature = new byte[0];
|
||||
} else {
|
||||
this.tpmQuoteSignature = tpmQuoteSignature.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ public class PcrComposite {
|
||||
@XmlElement(name = "ValueSize", required = true)
|
||||
public final int getValueSize() {
|
||||
int valueSize = 0;
|
||||
for (TPMMeasurementRecord record: this.pcrValueList) {
|
||||
for (TPMMeasurementRecord record : this.pcrValueList) {
|
||||
valueSize += record.getHash().getDigest().length;
|
||||
}
|
||||
return valueSize;
|
||||
|
Loading…
x
Reference in New Issue
Block a user