mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-04-08 11:54:27 +00:00
Merge branch 'master' into rimel-delete-details
This commit is contained in:
commit
89dd2084c2
@ -62,14 +62,11 @@ import javax.crypto.spec.OAEPParameterSpec;
|
||||
import javax.crypto.spec.PSource;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyFactory;
|
||||
@ -166,8 +163,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 tpmQuoteSignature = "";
|
||||
private String pcrValues;
|
||||
|
||||
/**
|
||||
@ -305,7 +302,7 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
// update the validation result in the device
|
||||
device.setSupplyChainStatus(summary.getOverallValidationResult());
|
||||
deviceManager.updateDevice(device);
|
||||
|
||||
LOG.error("This is the device id? {} ", device.getId());
|
||||
// check if supply chain validation succeeded.
|
||||
// If it did not, do not provide the IdentityResponseEnvelope
|
||||
if (summary.getOverallValidationResult() == AppraisalStatus.Status.PASS) {
|
||||
@ -455,7 +452,7 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
// perform supply chain validation
|
||||
SupplyChainValidationSummary summary = supplyChainValidationService.validateSupplyChain(
|
||||
endorsementCredential, platformCredentials, device);
|
||||
|
||||
device.setSummaryId(summary.getId().toString());
|
||||
// update the validation result in the device
|
||||
AppraisalStatus.Status validationResult = summary.getOverallValidationResult();
|
||||
device.setSupplyChainStatus(validationResult);
|
||||
@ -463,6 +460,34 @@ 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 {
|
||||
device.setSummaryId(scvs.getId().toString());
|
||||
// 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,
|
||||
@ -510,37 +535,63 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
Set<PlatformCredential> platformCredentials = parsePcsFromIdentityClaim(claim,
|
||||
endorsementCredential);
|
||||
|
||||
// Parse through the Provisioner supplied TPM Quote and pcr values
|
||||
// these fields are optional
|
||||
if (request.getQuote() != null && !request.getQuote().isEmpty()) {
|
||||
parseTPMQuote(request.getQuote().toStringUtf8());
|
||||
}
|
||||
if (request.getPcrslist() != null && !request.getPcrslist().isEmpty()) {
|
||||
this.pcrValues = request.getPcrslist().toStringUtf8();
|
||||
}
|
||||
|
||||
// Get device name and device
|
||||
String deviceName = claim.getDv().getNw().getHostname();
|
||||
Device device = deviceManager.getDevice(deviceName);
|
||||
|
||||
// Create signed, attestation certificate
|
||||
X509Certificate attestationCertificate = generateCredential(akPub,
|
||||
endorsementCredential, platformCredentials, deviceName);
|
||||
byte[] derEncodedAttestationCertificate = getDerEncodedCertificate(
|
||||
attestationCertificate);
|
||||
// Parse through the Provisioner supplied TPM Quote and pcr values
|
||||
// these fields are optional
|
||||
if (request.getQuote() != null && !request.getQuote().isEmpty()) {
|
||||
parseTPMQuote(request.getQuote().toStringUtf8());
|
||||
TPMInfo savedInfo = device.getDeviceInfo().getTPMInfo();
|
||||
TPMInfo tpmInfo = null;
|
||||
try {
|
||||
tpmInfo = new TPMInfo(savedInfo.getTPMMake(),
|
||||
savedInfo.getTPMVersionMajor(),
|
||||
savedInfo.getTPMVersionMinor(),
|
||||
savedInfo.getTPMVersionRevMajor(),
|
||||
savedInfo.getTPMVersionRevMinor(),
|
||||
savedInfo.getPcrValues(),
|
||||
this.tpmQuoteHash.getBytes("UTF-8"),
|
||||
this.tpmQuoteSignature.getBytes("UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
DeviceInfoReport dvReport = new DeviceInfoReport(
|
||||
device.getDeviceInfo().getNetworkInfo(),
|
||||
device.getDeviceInfo().getOSInfo(),
|
||||
device.getDeviceInfo().getFirmwareInfo(),
|
||||
device.getDeviceInfo().getHardwareInfo(), tpmInfo,
|
||||
claim.getClientVersion());
|
||||
device = this.deviceRegister.saveOrUpdateDevice(dvReport);
|
||||
}
|
||||
|
||||
// We validated the nonce and made use of the identity claim so state can be deleted
|
||||
tpm2ProvisionerStateDBManager.delete(tpm2ProvisionerState);
|
||||
AppraisalStatus.Status validationResult = doQuoteValidation(device);
|
||||
if (validationResult == AppraisalStatus.Status.PASS) {
|
||||
// Create signed, attestation certificate
|
||||
X509Certificate attestationCertificate = generateCredential(akPub,
|
||||
endorsementCredential, platformCredentials, deviceName);
|
||||
byte[] derEncodedAttestationCertificate = getDerEncodedCertificate(
|
||||
attestationCertificate);
|
||||
|
||||
// Package the signed certificate into a response
|
||||
ByteString certificateBytes = ByteString.copyFrom(derEncodedAttestationCertificate);
|
||||
ProvisionerTpm2.CertificateResponse response = ProvisionerTpm2.CertificateResponse
|
||||
.newBuilder().setCertificate(certificateBytes).build();
|
||||
// We validated the nonce and made use of the identity claim so state can be deleted
|
||||
tpm2ProvisionerStateDBManager.delete(tpm2ProvisionerState);
|
||||
|
||||
saveAttestationCertificate(derEncodedAttestationCertificate, endorsementCredential,
|
||||
platformCredentials, device);
|
||||
// Package the signed certificate into a response
|
||||
ByteString certificateBytes = ByteString.copyFrom(derEncodedAttestationCertificate);
|
||||
ProvisionerTpm2.CertificateResponse response = ProvisionerTpm2.CertificateResponse
|
||||
.newBuilder().setCertificate(certificateBytes).build();
|
||||
|
||||
return response.toByteArray();
|
||||
saveAttestationCertificate(derEncodedAttestationCertificate, endorsementCredential,
|
||||
platformCredentials, device);
|
||||
|
||||
return response.toByteArray();
|
||||
} else {
|
||||
LOG.error("Supply chain validation did not succeed. "
|
||||
+ "Firmware Quote Validation failed. Result is: "
|
||||
+ validationResult);
|
||||
return new byte[]{};
|
||||
}
|
||||
} else {
|
||||
LOG.error("Could not process credential request. Invalid nonce provided: "
|
||||
+ request.getNonce().toString());
|
||||
@ -553,7 +604,8 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
* quote and the signature hash.
|
||||
* @param tpmQuote contains hash values for the quote and the signature
|
||||
*/
|
||||
private void parseTPMQuote(final String tpmQuote) {
|
||||
private boolean parseTPMQuote(final String tpmQuote) {
|
||||
boolean success = false;
|
||||
if (tpmQuote != null) {
|
||||
String[] lines = tpmQuote.split(":");
|
||||
if (lines[1].contains("signature")) {
|
||||
@ -561,8 +613,11 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
} else {
|
||||
this.tpmQuoteHash = lines[1].trim();
|
||||
}
|
||||
this.tpmSignatureHash = lines[2].trim();
|
||||
this.tpmQuoteSignature = lines[2].trim();
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -663,9 +718,24 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
hwProto.getProductVersion(), hwProto.getSystemSerialNumber(),
|
||||
firstChassisSerialNumber, firstBaseboardSerialNumber);
|
||||
|
||||
if (dv.getPcrslist() != null && !dv.getPcrslist().isEmpty()) {
|
||||
this.pcrValues = dv.getPcrslist().toStringUtf8();
|
||||
}
|
||||
|
||||
// Get TPM info, currently unimplemented
|
||||
TPMInfo tpm = new TPMInfo();
|
||||
try {
|
||||
tpm = new TPMInfo(DeviceInfoReport.NOT_SPECIFIED,
|
||||
(short) 0,
|
||||
(short) 0,
|
||||
(short) 0,
|
||||
(short) 0,
|
||||
this.pcrValues.getBytes("UTF-8"),
|
||||
this.tpmQuoteHash.getBytes("UTF-8"),
|
||||
this.tpmQuoteSignature.getBytes("UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
tpm = new TPMInfo();
|
||||
}
|
||||
|
||||
// Create final report
|
||||
DeviceInfoReport dvReport = new DeviceInfoReport(nw, os, fw, hw, tpm,
|
||||
@ -1477,7 +1547,6 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
IssuedAttestationCertificate attCert = new IssuedAttestationCertificate(
|
||||
derEncodedAttestationCertificate, endorsementCredential, platformCredentials);
|
||||
attCert.setDevice(device);
|
||||
attCert.setPcrValues(savePcrValues(pcrValues, device.getName()));
|
||||
certificateManager.save(attCert);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error saving generated Attestation Certificate to database.", e);
|
||||
@ -1486,29 +1555,4 @@ public abstract class AbstractAttestationCertificateAuthority
|
||||
+ e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private String savePcrValues(final String pcrValues, final String deviceName) {
|
||||
if (pcrValues != null && !pcrValues.isEmpty()) {
|
||||
try {
|
||||
if (Files.notExists(Paths.get(PCR_UPLOAD_FOLDER))) {
|
||||
Files.createDirectory(Paths.get(PCR_UPLOAD_FOLDER));
|
||||
}
|
||||
Path pcrPath = Paths.get(String.format("%s/%s",
|
||||
PCR_UPLOAD_FOLDER, deviceName));
|
||||
if (Files.notExists(pcrPath)) {
|
||||
Files.createFile(pcrPath);
|
||||
}
|
||||
Files.write(pcrPath, pcrValues.getBytes("UTF8"));
|
||||
return pcrPath.toString();
|
||||
} catch (NoSuchFileException nsfEx) {
|
||||
LOG.error(String.format("File Not found!: %s",
|
||||
deviceName));
|
||||
LOG.error(nsfEx);
|
||||
} catch (IOException ioEx) {
|
||||
LOG.error(ioEx);
|
||||
}
|
||||
}
|
||||
|
||||
return "empty";
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package hirs.attestationca.service;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import hirs.data.persist.Device;
|
||||
import hirs.data.persist.SupplyChainValidationSummary;
|
||||
import hirs.data.persist.certificate.EndorsementCredential;
|
||||
@ -25,4 +26,12 @@ public interface SupplyChainValidationService {
|
||||
SupplyChainValidationSummary validateSupplyChain(EndorsementCredential ec,
|
||||
Set<PlatformCredential> pc,
|
||||
Device device);
|
||||
|
||||
/**
|
||||
* A supplemental method that handles validating just the quote post main validation.
|
||||
*
|
||||
* @param device the associated device.
|
||||
* @return True if validation is successful, false otherwise.
|
||||
*/
|
||||
SupplyChainValidationSummary validateQuote(Device device);
|
||||
}
|
||||
|
@ -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;
|
||||
@ -27,6 +24,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.LinkedList;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import hirs.appraiser.Appraiser;
|
||||
@ -41,7 +39,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;
|
||||
@ -52,6 +49,7 @@ import hirs.persist.DBManagerException;
|
||||
import hirs.persist.PersistenceConfiguration;
|
||||
import hirs.persist.PolicyManager;
|
||||
import hirs.validation.CredentialValidator;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -128,6 +126,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
List<SupplyChainValidation> validations = new LinkedList<>();
|
||||
Map<PlatformCredential, SupplyChainValidation> deltaMapping = new HashMap<>();
|
||||
SupplyChainValidation platformScv = null;
|
||||
LOGGER.info("Validating supply chain.");
|
||||
|
||||
// Validate the Endorsement Credential
|
||||
if (policy.isEcValidationEnabled()) {
|
||||
@ -258,6 +257,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
} catch (DBManagerException ex) {
|
||||
LOGGER.error("Failed to save Supply Chain summary", ex);
|
||||
}
|
||||
|
||||
return summary;
|
||||
}
|
||||
|
||||
@ -326,9 +326,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)
|
||||
@ -345,19 +342,13 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
}
|
||||
pcrPolicy.setBaselinePcrs(baseline);
|
||||
|
||||
if (attCert != null) {
|
||||
Path pcrPath = Paths.get(attCert.getPcrValues());
|
||||
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;
|
||||
int algorithmLength = baseline[0].length();
|
||||
|
||||
if (pcrContent.isEmpty()) {
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
@ -365,31 +356,13 @@ 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];
|
||||
int algorithmLength = baseline[0].length();
|
||||
String[] storedPcrs = buildStoredPcrs(pcrContent, algorithmLength);
|
||||
|
||||
// we need to scroll through the entire list until we find
|
||||
// a matching hash length
|
||||
int offset = 1;
|
||||
|
||||
for (int i = 0; i < pcrSet.length; i++) {
|
||||
if (pcrSet[i].contains("sha")) {
|
||||
// entered a new set, check size
|
||||
if (pcrSet[i + offset].split(":")[1].trim().length()
|
||||
== algorithmLength) {
|
||||
// found the matching set
|
||||
for (int j = 0; j <= TPMMeasurementRecord.MAX_PCR_ID; j++) {
|
||||
quote[j] = pcrSet[++i].split(":")[1].trim();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (quote[0].isEmpty()) {
|
||||
if (storedPcrs[0].isEmpty()) {
|
||||
// validation fail
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
"Firmware validation failed: "
|
||||
@ -397,7 +370,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());
|
||||
@ -421,6 +394,96 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
fwStatus.getAppStatus(), fwStatus.getMessage(), rim, level);
|
||||
}
|
||||
|
||||
/**
|
||||
* A supplemental method that handles validating just the quote post main validation.
|
||||
*
|
||||
* @param device the associated device.
|
||||
* @return True if validation is successful, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public SupplyChainValidationSummary validateQuote(final Device device) {
|
||||
final Appraiser supplyChainAppraiser = appraiserManager.getAppraiser(
|
||||
SupplyChainAppraiser.NAME);
|
||||
SupplyChainPolicy policy = (SupplyChainPolicy) policyManager.getDefaultPolicy(
|
||||
supplyChainAppraiser);
|
||||
SupplyChainValidation quoteScv = null;
|
||||
SupplyChainValidationSummary summary = null;
|
||||
Level level = Level.ERROR;
|
||||
AppraisalStatus fwStatus = new AppraisalStatus(FAIL,
|
||||
SupplyChainCredentialValidator.FIRMWARE_VALID);
|
||||
|
||||
// check if the policy is enabled
|
||||
if (policy.isFirmwareValidationEnabled()) {
|
||||
String[] baseline = new String[Integer.SIZE];
|
||||
String manufacturer = device.getDeviceInfo()
|
||||
.getHardwareInfo().getManufacturer();
|
||||
|
||||
// need to get pcrs
|
||||
ReferenceManifest rim = ReferenceManifest.select(
|
||||
this.referenceManifestManager)
|
||||
.byManufacturer(manufacturer)
|
||||
.getRIM();
|
||||
if (rim == null) {
|
||||
fwStatus = new AppraisalStatus(FAIL,
|
||||
String.format("Firmware Quote validation failed: "
|
||||
+ "No associated RIM file could be found for %s",
|
||||
manufacturer));
|
||||
} else {
|
||||
List<SwidResource> swids = rim.parseResource();
|
||||
for (SwidResource swid : swids) {
|
||||
baseline = swid.getPcrValues()
|
||||
.toArray(new String[swid.getPcrValues().size()]);
|
||||
}
|
||||
|
||||
String pcrContent = new String(device.getDeviceInfo().getTPMInfo().getPcrValues());
|
||||
String[] storedPcrs = buildStoredPcrs(pcrContent, baseline[0].length());
|
||||
PCRPolicy pcrPolicy = policy.getPcrPolicy();
|
||||
pcrPolicy.setBaselinePcrs(baseline);
|
||||
// grab the quote
|
||||
byte[] hash = device.getDeviceInfo().getTPMInfo().getTpmQuoteHash();
|
||||
if (pcrPolicy.validateQuote(hash, storedPcrs)) {
|
||||
level = Level.INFO;
|
||||
fwStatus = new AppraisalStatus(PASS,
|
||||
SupplyChainCredentialValidator.FIRMWARE_VALID);
|
||||
fwStatus.setMessage("Firmware validation of TPM Quote successful.");
|
||||
|
||||
} else {
|
||||
fwStatus.setMessage("Firmware validation of TPM Quote failed.");
|
||||
}
|
||||
}
|
||||
|
||||
quoteScv = buildValidationRecord(SupplyChainValidation
|
||||
.ValidationType.FIRMWARE,
|
||||
fwStatus.getAppStatus(), fwStatus.getMessage(), rim, level);
|
||||
|
||||
// Generate validation summary, save it, and return it.
|
||||
List<SupplyChainValidation> validations = new ArrayList<>();
|
||||
SupplyChainValidationSummary previous
|
||||
= this.supplyChainValidatorSummaryManager.get(
|
||||
UUID.fromString(device.getSummaryId()));
|
||||
for (SupplyChainValidation scv : previous.getValidations()) {
|
||||
if (scv.getValidationType() != SupplyChainValidation.ValidationType.FIRMWARE) {
|
||||
validations.add(buildValidationRecord(scv.getValidationType(),
|
||||
scv.getResult(), scv.getMessage(),
|
||||
scv.getCertificatesUsed().get(0), Level.INFO));
|
||||
}
|
||||
}
|
||||
validations.add(quoteScv);
|
||||
previous.archive();
|
||||
supplyChainValidatorSummaryManager.update(previous);
|
||||
summary = new SupplyChainValidationSummary(device, validations);
|
||||
|
||||
// try removing the supply chain validation as well and resaving that
|
||||
try {
|
||||
supplyChainValidatorSummaryManager.save(summary);
|
||||
} catch (DBManagerException ex) {
|
||||
LOGGER.error("Failed to save Supply Chain Summary", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return summary;
|
||||
}
|
||||
|
||||
private SupplyChainValidation validateEndorsementCredential(final EndorsementCredential ec,
|
||||
final boolean acceptExpiredCerts) {
|
||||
final SupplyChainValidation.ValidationType validationType
|
||||
@ -555,7 +618,6 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
final SupplyChainValidation.ValidationType validationType,
|
||||
final AppraisalStatus.Status result, final String message,
|
||||
final ArchivableEntity archivableEntity, final Level logLevel) {
|
||||
|
||||
List<ArchivableEntity> aeList = new ArrayList<>();
|
||||
if (archivableEntity != null) {
|
||||
aeList.add(archivableEntity);
|
||||
@ -673,4 +735,30 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe
|
||||
|
||||
return multiple;
|
||||
}
|
||||
|
||||
private String[] buildStoredPcrs(final String pcrContent, final int algorithmLength) {
|
||||
// we have a full set of PCR values
|
||||
String[] pcrSet = pcrContent.split("\\n");
|
||||
String[] storedPcrs = new String[TPMMeasurementRecord.MAX_PCR_ID + 1];
|
||||
|
||||
// we need to scroll through the entire list until we find
|
||||
// a matching hash length
|
||||
int offset = 1;
|
||||
|
||||
for (int i = 0; i < pcrSet.length; i++) {
|
||||
if (pcrSet[i].contains("sha")) {
|
||||
// entered a new set, check size
|
||||
if (pcrSet[i + offset].split(":")[1].trim().length()
|
||||
== algorithmLength) {
|
||||
// found the matching set
|
||||
for (int j = 0; j <= TPMMeasurementRecord.MAX_PCR_ID; j++) {
|
||||
storedPcrs[j] = pcrSet[++i].split(":")[1].trim();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return storedPcrs;
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,11 @@ import hirs.attestationca.portal.datatables.DataTableResponse;
|
||||
import hirs.attestationca.portal.datatables.OrderedListQueryDataTableAdapter;
|
||||
import hirs.attestationca.portal.page.PageController;
|
||||
import hirs.attestationca.portal.page.params.NoPageParams;
|
||||
import hirs.data.persist.certificate.Certificate;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import static org.apache.logging.log4j.LogManager.getLogger;
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
@ -79,16 +81,19 @@ public class ValidationReportsPageController extends PageController<NoPageParams
|
||||
// define an alias so the composite object, device, can be used by the
|
||||
// datatables / query. This is necessary so the device.name property can
|
||||
// be used.
|
||||
CriteriaModifier modifier = new CriteriaModifier() {
|
||||
CriteriaModifier criteriaModifier = new CriteriaModifier() {
|
||||
@Override
|
||||
public void modify(final Criteria criteria) {
|
||||
criteria.add(Restrictions.isNull(Certificate.ARCHIVE_FIELD));
|
||||
criteria.createAlias("device", "device");
|
||||
}
|
||||
};
|
||||
|
||||
FilteredRecordsList<SupplyChainValidationSummary> records =
|
||||
OrderedListQueryDataTableAdapter.getOrderedList(SupplyChainValidationSummary.class,
|
||||
supplyChainValidatorSummaryManager, input, orderColumnName, modifier);
|
||||
OrderedListQueryDataTableAdapter.getOrderedList(
|
||||
SupplyChainValidationSummary.class,
|
||||
supplyChainValidatorSummaryManager, input, orderColumnName,
|
||||
criteriaModifier);
|
||||
|
||||
return new DataTableResponse<>(records, input);
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ class CommandTpm2 {
|
||||
std::string getQuote(const std::string& pcr_selection,
|
||||
const std::string& nonce);
|
||||
|
||||
std::string getPcrsList();
|
||||
std::string getPcrList();
|
||||
};
|
||||
|
||||
} // namespace tpm2
|
||||
|
@ -558,7 +558,7 @@ string CommandTpm2::getQuote(const string& pcr_selection,
|
||||
* Method to get the full list of pcrs from the TPM.
|
||||
*
|
||||
*/
|
||||
string CommandTpm2::getPcrsList() {
|
||||
string CommandTpm2::getPcrList() {
|
||||
string pcrslist;
|
||||
stringstream argsStream;
|
||||
|
||||
|
@ -57,6 +57,7 @@ message DeviceInfo {
|
||||
required HardwareInfo hw = 2;
|
||||
required NetworkInfo nw = 3;
|
||||
required OsInfo os = 4;
|
||||
optional bytes pcrslist = 5;
|
||||
}
|
||||
|
||||
message IdentityClaim {
|
||||
@ -80,7 +81,6 @@ message IdentityClaimResponse {
|
||||
message CertificateRequest {
|
||||
required bytes nonce = 1;
|
||||
optional bytes quote = 2;
|
||||
optional bytes pcrslist = 3;
|
||||
}
|
||||
|
||||
message CertificateResponse {
|
||||
|
@ -98,7 +98,7 @@ string RestfulClientProvisioner::sendIdentityClaim(
|
||||
stringstream errormsg;
|
||||
errormsg << "Error communicating with ACA server. "
|
||||
<< "Received response code: " << to_string(r.status_code)
|
||||
<< "\n\nError message fom ACA was: "
|
||||
<< "\n\nError message from ACA was: "
|
||||
<< JSONFieldParser::parseJsonStringField(r.text,
|
||||
ACA_ERROR_FIELDNAME);
|
||||
throw HirsRuntimeException(errormsg.str(),
|
||||
|
@ -64,6 +64,7 @@ int provision() {
|
||||
// collect device info
|
||||
cout << "----> Collecting device information" << endl;
|
||||
hirs::pb::DeviceInfo dv = DeviceInfoCollector::collectDeviceInfo();
|
||||
dv.set_pcrslist(tpm2.getPcrList());
|
||||
|
||||
// send identity claim
|
||||
cout << "----> Sending identity claim to Attestation CA" << endl;
|
||||
@ -106,10 +107,14 @@ int provision() {
|
||||
"14,15,16,17,18,19,20,21,22,23",
|
||||
decryptedNonce));
|
||||
|
||||
certificateRequest.set_pcrslist(tpm2.getPcrsList());
|
||||
const string& akCertificateByteString
|
||||
= provisioner.sendAttestationCertificateRequest(certificateRequest);
|
||||
|
||||
if (akCertificateByteString == "") {
|
||||
cout << "----> Provisioning failed.";
|
||||
cout << "Please refer to the Attestation CA for details." << endl;
|
||||
return 0;
|
||||
}
|
||||
cout << "----> Storing attestation key certificate" << endl;
|
||||
tpm2.storeAKCertificate(akCertificateByteString);
|
||||
return 1;
|
||||
|
@ -95,6 +95,9 @@ public class Device extends AbstractEntity {
|
||||
@Column(name = "state_override_reason")
|
||||
private String overrideReason;
|
||||
|
||||
@Column(name = "summary_id")
|
||||
private String summaryId;
|
||||
|
||||
/**
|
||||
* Default constructor required by Hibernate.
|
||||
*/
|
||||
@ -358,6 +361,22 @@ public class Device extends AbstractEntity {
|
||||
this.supplyChainValidationStatus = supplyChainValidationStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the last summary id.
|
||||
* @return UUID for the summary
|
||||
*/
|
||||
public String getSummaryId() {
|
||||
return summaryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the last summary id.
|
||||
* @param summaryId UUID
|
||||
*/
|
||||
public void setSummaryId(final String summaryId) {
|
||||
this.summaryId = summaryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this <code>Device</code>. The hash code is
|
||||
* determined from the name of the <code>Device</code>.
|
||||
|
@ -2,9 +2,20 @@ 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 hirs.data.persist.tpm.PcrSelection;
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* The class handles the flags that ignore certain PCRs for validation.
|
||||
*/
|
||||
@ -52,10 +63,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 +81,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 +89,47 @@ public final class PCRPolicy extends Policy {
|
||||
return sb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares hashs to validate the quote from the client.
|
||||
*
|
||||
* @param tpmQuote the provided quote
|
||||
* @param storedPcrs values from the RIM file
|
||||
* @return true if validated, false if not
|
||||
*/
|
||||
public boolean validateQuote(final byte[] tpmQuote, final String[] storedPcrs) {
|
||||
LOGGER.info("Validating quote from associated device.");
|
||||
boolean validated = false;
|
||||
short localityAtRelease = 0;
|
||||
Charset charset = Charset.forName("UTF-8");
|
||||
String quoteString = new String(tpmQuote, charset);
|
||||
|
||||
TPMMeasurementRecord[] measurements = new TPMMeasurementRecord[baselinePcrs.length];
|
||||
try {
|
||||
for (int i = 0; i <= TPMMeasurementRecord.MAX_PCR_ID; i++) {
|
||||
measurements[i] = new TPMMeasurementRecord(i, storedPcrs[i]);
|
||||
}
|
||||
} catch (DecoderException deEx) {
|
||||
LOGGER.error(deEx);
|
||||
}
|
||||
PcrSelection pcrSelection = new PcrSelection(PcrSelection.ALL_PCRS_ON);
|
||||
PcrComposite pcrComposite = new PcrComposite(
|
||||
pcrSelection,
|
||||
Arrays.asList(measurements));
|
||||
PcrInfoShort pcrInfoShort = new PcrInfoShort(pcrSelection,
|
||||
localityAtRelease,
|
||||
tpmQuote, pcrComposite);
|
||||
|
||||
try {
|
||||
String calculatedString = Hex.encodeHexString(
|
||||
pcrInfoShort.getCalculatedDigest());
|
||||
validated = quoteString.contains(calculatedString);
|
||||
} catch (NoSuchAlgorithmException naEx) {
|
||||
LOGGER.error(naEx);
|
||||
}
|
||||
|
||||
return validated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the array of baseline PCRs.
|
||||
* @return instance of the PCRs.
|
||||
|
@ -48,6 +48,7 @@ public class SwidResource {
|
||||
private List<String> pcrValues;
|
||||
private TpmWhiteListBaseline tpmWhiteList;
|
||||
private DigestAlgorithm digest = DigestAlgorithm.SHA1;
|
||||
private boolean validFileSize = false;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
@ -192,6 +193,14 @@ public class SwidResource {
|
||||
this.pcrValues = pcrValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* flag for if the file sizes match with the swidtag.
|
||||
* @return true if they match
|
||||
*/
|
||||
public boolean isValidFileSize() {
|
||||
return validFileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for a generated map of the PCR values.
|
||||
*
|
||||
|
@ -10,7 +10,6 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
@ -21,8 +20,6 @@ import javax.persistence.ManyToOne;
|
||||
@Entity
|
||||
public class IssuedAttestationCertificate extends DeviceAssociatedCertificate {
|
||||
|
||||
private static final int MAX_CERT_LENGTH_BYTES = 1024;
|
||||
|
||||
/**
|
||||
* AIC label that must be used.
|
||||
*/
|
||||
@ -36,9 +33,6 @@ public class IssuedAttestationCertificate extends DeviceAssociatedCertificate {
|
||||
@JoinColumn(name = "pc_id")
|
||||
private Set<PlatformCredential> platformCredentials;
|
||||
|
||||
@Column(nullable = true, length = MAX_CERT_LENGTH_BYTES)
|
||||
private String pcrValues;
|
||||
|
||||
/**
|
||||
* This class enables the retrieval of IssuedAttestationCertificate by their attributes.
|
||||
*/
|
||||
@ -129,20 +123,4 @@ public class IssuedAttestationCertificate extends DeviceAssociatedCertificate {
|
||||
public Set<PlatformCredential> getPlatformCredentials() {
|
||||
return Collections.unmodifiableSet(platformCredentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the pcrValues passed up by the client.
|
||||
* @return a string blob of pcrs
|
||||
*/
|
||||
public String getPcrValues() {
|
||||
return pcrValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the pcrValues passed up by the client.
|
||||
* @param pcrValues to be stored.
|
||||
*/
|
||||
public void setPcrValues(final String pcrValues) {
|
||||
this.pcrValues = pcrValues;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -287,7 +287,6 @@ public class PcrInfoShort {
|
||||
* @return byte array representing the PcrInfoShort object
|
||||
*/
|
||||
public final byte[] getValue() {
|
||||
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate(getLength());
|
||||
byteBuffer.put(pcrSelection.getValue());
|
||||
byteBuffer.put((byte) localityAtRelease);
|
||||
|
@ -30,6 +30,10 @@ public class PcrSelection {
|
||||
private static final Logger LOGGER = LogManager
|
||||
.getLogger(PcrSelection.class);
|
||||
private static final int MAX_SIZE_PCR_ARRAY = 3;
|
||||
/**
|
||||
* All PCRs are on.
|
||||
*/
|
||||
public static final int ALL_PCRS_ON = 0xffffff;
|
||||
|
||||
@XmlAttribute(name = "PcrSelect", required = true)
|
||||
private final byte[] pcrSelect;
|
||||
@ -76,8 +80,7 @@ public class PcrSelection {
|
||||
* long value representing the bits to be selected
|
||||
*/
|
||||
public PcrSelection(final long pcrSelectLong) {
|
||||
final int allPCRsOn = 0xffffff;
|
||||
if (pcrSelectLong > allPCRsOn) {
|
||||
if (pcrSelectLong > ALL_PCRS_ON) {
|
||||
LOGGER.error("pcrSelect long value must be less than 3 bytes");
|
||||
throw new InvalidParameterException("pcrSelect");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user