parsing SPDM cert chain

This commit is contained in:
iadgovuser58 2024-08-02 18:35:08 -04:00
parent f2f5c52053
commit e91517c77c
7 changed files with 214 additions and 85 deletions

View File

@ -76,14 +76,14 @@ public class DeviceSecurityEventData2 extends DeviceSecurityEvent {
} }
} }
else if (subHeaderType == DeviceSecurityEventDataSubHeader.SUBHEADERTYPE_CERT_CHAIN) { else if (subHeaderType == DeviceSecurityEventDataSubHeader.SUBHEADERTYPE_CERT_CHAIN) {
subHeaderInfo += "\n Cert chain to be implemented "; // subHeaderInfo += "\n Cert chain to be implemented ";
try { try {
dsedSubHeader = dsedSubHeader =
new DeviceSecurityEventDataSubHeaderCertChain(dsedSubHeaderBytes); new DeviceSecurityEventDataSubHeaderCertChain(dsedSubHeaderBytes);
subHeaderInfo += dsedSubHeader.toString(); subHeaderInfo += dsedSubHeader.toString();
} }
catch(NullPointerException e) { catch(NullPointerException e) {
subHeaderInfo = "\n Could not interpret Sub header info for SPDM measurement block"; subHeaderInfo = "\n Could not interpret Sub header info for SPDM cert chain";
} }
} }
else { else {

View File

@ -1,8 +1,8 @@
package hirs.utils.tpm.eventlog.events; package hirs.utils.tpm.eventlog.events;
import hirs.utils.HexUtils; import hirs.utils.HexUtils;
import hirs.utils.tpm.eventlog.spdm.SpdmCertificateChain;
import hirs.utils.tpm.eventlog.spdm.SpdmHa; import hirs.utils.tpm.eventlog.spdm.SpdmHa;
import hirs.utils.tpm.eventlog.spdm.SpdmMeasurementBlock;
import lombok.Getter; import lombok.Getter;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -20,24 +20,33 @@ import java.util.ArrayList;
* SPDM_CERT_CHAIN SpdmCertChain; * SPDM_CERT_CHAIN SpdmCertChain;
* } DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN; * } DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN;
* <p> * <p>
* SpdmVersion: SpdmBaseHashAlgo
* SpdmSlotId: SlotId associated with this SPDM Certificate Chain
* SpdmBaseHashAlgo: SPDM Base Hash Algorithm for the root certificate in the SPDM Certificate chain
* SpdmCertChain: SPDM Certificate Chain
*/ */
public class DeviceSecurityEventDataSubHeaderCertChain extends DeviceSecurityEventDataSubHeader{ public class DeviceSecurityEventDataSubHeaderCertChain extends DeviceSecurityEventDataSubHeader{
/** /**
* SPDM version. * SPDM version.
*/ */
@Getter
private int spdmVersion = 0; private int spdmVersion = 0;
/** /**
* SPDM slot ID. * SPDM slot ID.
*/ */
@Getter private int spdmSlotId = 0;
private int spdmLotId = 0;
/** /**
* SPDM base hash algorithm. * SPDM base hash algorithm.
*/ */
@Getter
private int spdmBaseHashAlgo = -1; private int spdmBaseHashAlgo = -1;
/**
* SPDM cert chain.
*/
private SpdmCertificateChain spdmCertChain = null;
/**
* Human-readable description of any error associated with SPDM base hash alg.
*/
String spdmBaseHashAlgoError = "";
/** /**
* DeviceSecurityEventDataSubHeaderCertChain Constructor. * DeviceSecurityEventDataSubHeaderCertChain Constructor.
@ -52,7 +61,7 @@ public class DeviceSecurityEventDataSubHeaderCertChain extends DeviceSecurityEve
byte[] spdmLotIdBytes = new byte[1]; byte[] spdmLotIdBytes = new byte[1];
System.arraycopy(dsedSubHBytes, 2, spdmLotIdBytes, 0, 1); System.arraycopy(dsedSubHBytes, 2, spdmLotIdBytes, 0, 1);
spdmLotId = HexUtils.leReverseInt(spdmLotIdBytes); spdmSlotId = HexUtils.leReverseInt(spdmLotIdBytes);
// byte[] reserved[Bytes]: 1 byte // byte[] reserved[Bytes]: 1 byte
@ -68,13 +77,15 @@ public class DeviceSecurityEventDataSubHeaderCertChain extends DeviceSecurityEve
System.arraycopy(dsedSubHBytes, 8, spdmCertChainBytes, 0, System.arraycopy(dsedSubHBytes, 8, spdmCertChainBytes, 0,
spdmCertChainSize); spdmCertChainSize);
// ByteArrayInputStream spdmMeasurementBlockListData = int spdmBaseHashAlgoSize = SpdmHa.tcgAlgIdToByteSize(spdmBaseHashAlgo);
// new ByteArrayInputStream(spdmMeasurementBlockListBytes);
// while (spdmMeasurementBlockListData.available() > 0) { if(spdmBaseHashAlgoSize > 0) {
// SpdmMeasurementBlock spdmMeasurementBlock; spdmCertChain = new SpdmCertificateChain(spdmCertChainBytes, spdmBaseHashAlgoSize);
// spdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasurementBlockListData); }
// spdmMeasurementBlockList.add(spdmMeasurementBlock); else {
// } spdmBaseHashAlgoError += "SPDM base hash algorithm size is not >0";
}
} }
@ -85,18 +96,13 @@ public class DeviceSecurityEventDataSubHeaderCertChain extends DeviceSecurityEve
*/ */
public String toString() { public String toString() {
String dsedSubHeaderInfo = ""; String dsedSubHeaderInfo = "";
// dsedSubHeaderInfo += "\n SPDM Version: " + spdmVersion; dsedSubHeaderInfo += "\n SPDM Version = " + spdmVersion;
// String spdmHashAlgoStr = SpdmHa.tcgAlgIdToString(spdmMeasurementHashAlgo); dsedSubHeaderInfo += "\n SPDM Slot ID = " + spdmSlotId;
// dsedSubHeaderInfo += "\n SPDM Hash Algorithm = " + spdmHashAlgoStr; String spdmBaseHashAlgoStr = SpdmHa.tcgAlgIdToString(spdmBaseHashAlgo);
// dsedSubHeaderInfo += "\n SPDM Base Hash Algorithm = " + spdmBaseHashAlgoStr;
// // SPDM Measurement Block List output
// dsedSubHeaderInfo += "\n Number of SPDM Measurement Blocks = " + spdmMeasurementBlockList.size(); // SPDM Certificate Chain output
// int spdmMeasBlockCnt = 1; dsedSubHeaderInfo += spdmCertChain.toString();
// for (SpdmMeasurementBlock spdmMeasBlock : spdmMeasurementBlockList) {
// dsedSubHeaderInfo += "\n SPDM Measurement Block # " + spdmMeasBlockCnt++ + " of " +
// spdmMeasurementBlockList.size();
// dsedSubHeaderInfo += spdmMeasBlock.toString();
// }
return dsedSubHeaderInfo; return dsedSubHeaderInfo;
} }

View File

@ -21,6 +21,14 @@ import java.util.List;
* SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock[SpdmMeasurementBlockCount]; * SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock[SpdmMeasurementBlockCount];
* } DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK; * } DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK;
* <p> * <p>
*
* SpdmMeasurementBlock is an array of SPDM_MEASUREMENT_BLOCKs
* The size of each block is the same and can be found by either:
* 1) 4 + SpdmMeasurementBlock MeasurementSize
* OR
* 2) 4 + hash length of the hash algorithm found in
* DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK SpdmMeasurementHashAlgo
* where 4 is the size of the SpdmMeasurementBlock header
*/ */
public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends DeviceSecurityEventDataSubHeader { public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends DeviceSecurityEventDataSubHeader {
@ -68,7 +76,7 @@ public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends Device
System.arraycopy(dsedSubHBytes, 4, spdmMeasurementHashAlgoBytes, 0, 4); System.arraycopy(dsedSubHBytes, 4, spdmMeasurementHashAlgoBytes, 0, 4);
spdmMeasurementHashAlgo = HexUtils.leReverseInt(spdmMeasurementHashAlgoBytes); spdmMeasurementHashAlgo = HexUtils.leReverseInt(spdmMeasurementHashAlgoBytes);
// get the size of the SPDM Measurement Block List // get the total size of the SPDM Measurement Block List
int spdmMeasurementBlockListSize = dsedSubHBytes.length - 8; int spdmMeasurementBlockListSize = dsedSubHBytes.length - 8;
// extract the bytes that comprise the SPDM Measurement Block List // extract the bytes that comprise the SPDM Measurement Block List
@ -92,7 +100,7 @@ public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends Device
*/ */
public String toString() { public String toString() {
String dsedSubHeaderInfo = ""; String dsedSubHeaderInfo = "";
dsedSubHeaderInfo += "\n SPDM Version: " + spdmVersion; dsedSubHeaderInfo += "\n SPDM Version = " + spdmVersion;
String spdmHashAlgoStr = SpdmHa.tcgAlgIdToString(spdmMeasurementHashAlgo); String spdmHashAlgoStr = SpdmHa.tcgAlgIdToString(spdmMeasurementHashAlgo);
dsedSubHeaderInfo += "\n SPDM Hash Algorithm = " + spdmHashAlgoStr; dsedSubHeaderInfo += "\n SPDM Hash Algorithm = " + spdmHashAlgoStr;

View File

@ -1,8 +1,10 @@
package hirs.utils.tpm.eventlog.spdm; package hirs.utils.tpm.eventlog.spdm;
import hirs.utils.HexUtils; import hirs.utils.HexUtils;
import hirs.utils.tpm.eventlog.events.DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock;
import hirs.utils.tpm.eventlog.uefi.UefiConstants; import hirs.utils.tpm.eventlog.uefi.UefiConstants;
import hirs.utils.tpm.eventlog.uefi.UefiSignatureData; import hirs.utils.tpm.eventlog.uefi.UefiSignatureData;
import hirs.utils.tpm.eventlog.uefi.UefiSignatureList;
import hirs.utils.tpm.eventlog.uefi.UefiX509Cert; import hirs.utils.tpm.eventlog.uefi.UefiX509Cert;
import lombok.Getter; import lombok.Getter;
@ -31,6 +33,8 @@ import java.util.ArrayList;
* hash algorithm is included in the DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN * hash algorithm is included in the DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN
* structure as the member "SpdmBaseHashAlg" * structure as the member "SpdmBaseHashAlg"
* RootHash: the digest of the Root Certificate. * RootHash: the digest of the Root Certificate.
* size is determined by hash algorithm selected by the most recent SPDM ALGORITHMS response;
* the hash algorithm is the DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN SpdmBaseHashAlgo
* Certificates: Complete cert chain consisting of 1 or more ASN.1 DER-encoded X.509 v3 certs * Certificates: Complete cert chain consisting of 1 or more ASN.1 DER-encoded X.509 v3 certs
* this field shall be in Encoded ASN.1 byte order * this field shall be in Encoded ASN.1 byte order
*/ */
@ -44,25 +48,35 @@ public class SpdmCertificateChain {
* Root hash. * Root hash.
*/ */
private byte[] rootHash = null; private byte[] rootHash = null;
/** /**
* Number of certs in the SPDM cert chain. * Number of certs in the SPDM cert chain.
*/ */
@Getter
private int numberOfCerts = 0; private int numberOfCerts = 0;
/** /**
* Array List of certs found in the chain. * Array List of certs found in the chain.
*/ */
// private ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>(); // private ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>();
private ArrayList<UefiX509Cert> certList = new ArrayList<UefiX509Cert>(); private ArrayList<UefiX509Cert> certList = new ArrayList<UefiX509Cert>();
/**
* Human-readable description of any error associated with SPDM base hash alg.
*/
String spdmBaseHashAlgoError = "";
/**
* Human-readable description of any error associated with parsing the X509 certs.
*/
String certProcessingError = "";
/** /**
* SpdmCertificateChain Constructor. * SpdmCertificateChain Constructor.
* *
* @param spdmCertChainBytes byte array holding the SPDM Cert Chain bytes. * @param spdmCertChainBytes byte array holding the SPDM Cert Chain bytes.
*/ */
public SpdmCertificateChain(final byte[] spdmCertChainBytes, final int rootHashLength) throws CertificateException, NoSuchAlgorithmException, IOException { public SpdmCertificateChain(final byte[] spdmCertChainBytes, final int rootHashLength) {
if(rootHashLength <= 0) {
spdmBaseHashAlgoError = "SPDM base hash algorithm size is not >0";
}
else {
byte[] lengthBytes = new byte[2]; byte[] lengthBytes = new byte[2];
System.arraycopy(spdmCertChainBytes, 0, lengthBytes, 0, 2); System.arraycopy(spdmCertChainBytes, 0, lengthBytes, 0, 2);
length = HexUtils.leReverseInt(lengthBytes); length = HexUtils.leReverseInt(lengthBytes);
@ -79,24 +93,24 @@ public class SpdmCertificateChain {
processCertChain(certChainBytes); processCertChain(certChainBytes);
} }
}
//TODO possily get rid of exceptions
/** /**
* Method for processing the data in an EFI SignatureList (ex. can be one or more X509 certs) * Method for processing the data in an EFI SignatureList (ex. can be one or more X509 certs)
* *
* @param certChainData Byte array holding the cert chain data * @param certChainData Byte array holding the cert chain data
* @throws java.security.cert.CertificateException If there's a problem parsing the X509 certificate.
* @throws java.security.NoSuchAlgorithmException if there's a problem hashing the certificate.
* @throws java.io.IOException If there's a problem parsing the signature data.
*/ */
private void processCertChain(final byte[] certChainData) private void processCertChain(final byte[] certChainData) {
throws CertificateException, NoSuchAlgorithmException, IOException {
UefiX509Cert cert = null; UefiX509Cert cert = null;
ByteArrayInputStream certChainDataIS = new ByteArrayInputStream(certChainData); ByteArrayInputStream certChainDataIS = new ByteArrayInputStream(certChainData);
while (certChainDataIS.available() > 0) { while (certChainDataIS.available() > 0) {
// java.io.IOException If there's a problem parsing the cert chain data.
// java.security.cert.CertificateException if there's a problem parsing the X509 certificate.
// java.security.NoSuchAlgorithmException if there's a problem hashing the certificate.
try {
byte[] certType = new byte[UefiConstants.SIZE_2]; byte[] certType = new byte[UefiConstants.SIZE_2];
certChainDataIS.read(certType); certChainDataIS.read(certType);
byte[] certLength = new byte[UefiConstants.SIZE_2]; byte[] certLength = new byte[UefiConstants.SIZE_2];
@ -109,10 +123,24 @@ public class SpdmCertificateChain {
System.arraycopy(certType, 0, certBlob, 0, 2); System.arraycopy(certType, 0, certBlob, 0, 2);
System.arraycopy(certLength, 0, certBlob, 2, 2); System.arraycopy(certLength, 0, certBlob, 2, 2);
System.arraycopy(certData, 0, certBlob, UefiConstants.OFFSET_4, cLength); System.arraycopy(certData, 0, certBlob, UefiConstants.OFFSET_4, cLength);
cert = new UefiX509Cert(certBlob); cert = new UefiX509Cert(certBlob);
// cert = new X509Certificate(certBlob); // cert = new X509Certificate(certBlob);
certList.add(cert); certList.add(cert);
numberOfCerts++; numberOfCerts++;
} catch (IOException e) {
certProcessingError += "Error with Cert # " + (numberOfCerts+1)
+ ": IOException (error reading cert data)";
break;
} catch (CertificateException e) {
certProcessingError += "Error with Cert # " + (numberOfCerts+1)
+ ": CertificateException";
break;
} catch (NoSuchAlgorithmException e) {
certProcessingError += "Error with Cert # " + numberOfCerts+1
+ ": CNoSuchAlgorithmException";
break;
}
} }
} }
@ -123,17 +151,30 @@ public class SpdmCertificateChain {
*/ */
public String toString() { public String toString() {
String spdmMeasBlockInfo = ""; String spdmCertChainInfo = "";
//
// if(spdmMeasurementBlockReadError) { if(spdmBaseHashAlgoError != "") {
// spdmMeasBlockInfo += "\n Error reading SPDM Measurement Block"; spdmCertChainInfo += "\n *** ERROR with SPDM base hash algorithm size ***";
// } spdmCertChainInfo += "\n " + spdmBaseHashAlgoError;
// else { spdmCertChainInfo += "\n Stopping processing of this cert chain";
// spdmMeasBlockInfo += "\n Index = " + index; }
// spdmMeasBlockInfo += "\n MeasurementSpec = " + measurementSpec; else {
// spdmMeasBlockInfo += spdmMeasurement.toString(); spdmCertChainInfo += "\n Root hash = " + rootHash.toString();
// } spdmCertChainInfo += "\n Number of certs in chain = " + numberOfCerts + "\n";
//
return spdmMeasBlockInfo; int certCnt = 1;
for (UefiX509Cert cert : certList) {
spdmCertChainInfo += " Cert # " + certCnt++ + " of " +
numberOfCerts + ": ------------------\n";
spdmCertChainInfo += cert.toString();
}
if (certProcessingError != "") {
spdmCertChainInfo += " *** ERROR processing cert ***";
spdmCertChainInfo += "\n " + certProcessingError;
spdmCertChainInfo += "\n Stopping processing of this cert chain";
}
}
return spdmCertChainInfo;
} }
} }

View File

@ -75,4 +75,42 @@ public class SpdmHa {
} }
return alg; return alg;
} }
/**
* Returns the hash name via a lookup.
* Lookup based upon SPDM Spec v1.03 section 10.4.
*
* @param algId int to convert to string
* @return name of the algorithm
*/
public static int tcgAlgIdToByteSize(final int algId) {
int byteSize;
switch (algId) {
//case TPM_ALG_RAW: // add this when have more test data
// byteSize = ;
// break;
case TPM_ALG_SHA_256:
byteSize = 32;
break;
case TPM_ALG_SHA_384:
byteSize = 48;
break;
case TPM_ALG_SHA_512:
byteSize = 64;
break;
case TPM_ALG_SHA3_256:
byteSize = 32;
break;
case TPM_ALG_SHA3_384:
byteSize = 48;
break;
case TPM_ALG_SHA3_512:
byteSize = 64;
break;
default:
byteSize = -1;
}
return byteSize;
}
} }

View File

@ -10,9 +10,15 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
/** /**
* Class for processing the contents of a Secure Boot PK, KEK, DB or DBX contents. * Class for processing either
* used for EFIVariables associated with Secure Boot * 1) the contents of a Secure Boot PK, KEK, DB or DBX contents,
* used for EFIVariables associated with Secure Boot,
* as defined by Section 32.4.1 Signature Database from the UEFI 2.8 specification * as defined by Section 32.4.1 Signature Database from the UEFI 2.8 specification
* 2) the contents of an SPDM devdb,
* used for SPDM Device Policy or Device Authority, whose data is an EFIVariable
* EFIVariable data for SPDM Device Policy: UefiSignatureList
* EFIVariable data for SPDM Device: UefiSignatureData only
* as defined by PFP v1.06 Rev52, Section 10.4
* <p> * <p>
* typedef struct _EFI_SIGNATURE_DATA { * typedef struct _EFI_SIGNATURE_DATA {
* EFI_GUID SignatureOwner; * EFI_GUID SignatureOwner;

View File

@ -12,12 +12,18 @@ import java.util.ArrayList;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIBLE; import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
/** /**
* Class for processing the contents of a Secure Boot DB or DBX contents. * Class for processing either
* used for EFIVariables associated with Secure Boot * 1) the contents of a Secure Boot PK, KEK, DB or DBX contents,
* as defined by Section 32.4.1 Signature Database from the UEFI 2.8 specification. * used for EFIVariables associated with Secure Boot,
* as defined by Section 32.4.1 Signature Database from the UEFI 2.8 specification
* 2) the contents of an SPDM devdb,
* used for SPDM Device Policy, whose data is an EFIVariable
* as defined by PFP v1.06 Rev52, Section 10.4
* <p> * <p>
* An EFI Signature List is actual a list of Certificates used to verify a Signature. * An EFI Signature List is actually a list of Certificates used to verify a Signature.
* This is mainly found in PCR[7] UEFI variables for the Secure Boot PK, KEK, Db and DBx variables. * This is mainly found in PCR[7] UEFI variables for either the
* Secure Boot PK, KEK, Db and DBx variables
* or the SPDM devdb variable (under EV_EFI_SPDM_DEVICE_POLICY).
* <p> * <p>
* typedef struct _EFI_SIGNATURE_LIST { * typedef struct _EFI_SIGNATURE_LIST {
* EFI_GUID SignatureType; * EFI_GUID SignatureType;
@ -27,6 +33,27 @@ import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIB
* // UINT8 SignatureHeader[SignatureHeaderSize]; * // UINT8 SignatureHeader[SignatureHeaderSize];
* // EFI_SIGNATURE_DATA Signatures[...][SignatureSize]; * // EFI_SIGNATURE_DATA Signatures[...][SignatureSize];
* } EFI_SIGNATURE_LIST; * } EFI_SIGNATURE_LIST;
*
* Signatures[][] is an array of signatures.
* - Each signature is SignatureSize bytes in length.
* - The format of the signature is defined by SignatureType (SHA256, X509)
*
* / |-------------------------| ------- SignatureType
* / | Signature List Header | SignatureListSize
* |---------------------| / |-------------------------|\ SignatureHeaderSize
* | Signature List #0 | / | Signature Header | \ _____ SignatureSize
* | | / |-------------------------|
* |---------------------| / | Signature #0 |
* | Signature List #1 | / |-------------------------|
* |---------------------|/ | Signature #1 | --> each Signature is
* | Signature List #2 | |-------------------------| 1 UefiSignatureData
* | | | Signature #2 | (1 cert or hash)
* | | |-------------------------|
* |---------------------| | ... |
* \ | |
* \ |-------------------------|
* \ | Signature #n |
* \ |-------------------------|
*/ */
public class UefiSignatureList { public class UefiSignatureList {
/** /**
@ -125,7 +152,7 @@ public class UefiSignatureList {
vendorTableFileStatus = signatureType.getVendorTableFileStatus(); vendorTableFileStatus = signatureType.getVendorTableFileStatus();
// if signatureType is invalid, don't even process any of the data // if signatureType is invalid, don't even process any of the data
// however, if signatureTYpe is valid, but some of the data later on is invalid, that will // however, if signatureType is valid, but some of the data later on is invalid, that will
// be caught when UefiSignatureData is processed // be caught when UefiSignatureData is processed
if (!isValidSigListGUID(signatureType)) { if (!isValidSigListGUID(signatureType)) {
//processSignatureData(lists); //processSignatureData(lists);
@ -230,7 +257,10 @@ public class UefiSignatureList {
sigInfo.append(" UEFI Signature List Type = " + signatureType.toString() + "\n"); sigInfo.append(" UEFI Signature List Type = " + signatureType.toString() + "\n");
sigInfo.append(" Number of Certs or Hashes in UEFI Signature List = " + numberOfCerts + "\n"); sigInfo.append(" Number of Certs or Hashes in UEFI Signature List = " + numberOfCerts + "\n");
int certOrHashCnt = 1;
for (int i = 0; i < sigList.size(); i++) { for (int i = 0; i < sigList.size(); i++) {
sigInfo.append(" Cert or Hash # " + certOrHashCnt++ + " of " +
numberOfCerts + ": ------------------\n");
UefiSignatureData certData = sigList.get(i); UefiSignatureData certData = sigList.get(i);
sigInfo.append(certData.toString()); sigInfo.append(certData.toString());
} }