From e91517c77cd8be8851c25dbf7acea8d5dd1023bd Mon Sep 17 00:00:00 2001 From: iadgovuser58 <124906646+iadgovuser58@users.noreply.github.com> Date: Fri, 2 Aug 2024 18:35:08 -0400 Subject: [PATCH] parsing SPDM cert chain --- .../events/DeviceSecurityEventData2.java | 4 +- ...ceSecurityEventDataSubHeaderCertChain.java | 56 ++++---- ...ventDataSubHeaderSpdmMeasurementBlock.java | 12 +- .../eventlog/spdm/SpdmCertificateChain.java | 135 ++++++++++++------ .../hirs/utils/tpm/eventlog/spdm/SpdmHa.java | 38 +++++ .../tpm/eventlog/uefi/UefiSignatureData.java | 12 +- .../tpm/eventlog/uefi/UefiSignatureList.java | 42 +++++- 7 files changed, 214 insertions(+), 85 deletions(-) diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventData2.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventData2.java index b2f63ba4..7a2c2479 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventData2.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventData2.java @@ -76,14 +76,14 @@ public class DeviceSecurityEventData2 extends DeviceSecurityEvent { } } else if (subHeaderType == DeviceSecurityEventDataSubHeader.SUBHEADERTYPE_CERT_CHAIN) { - subHeaderInfo += "\n Cert chain to be implemented "; +// subHeaderInfo += "\n Cert chain to be implemented "; try { dsedSubHeader = new DeviceSecurityEventDataSubHeaderCertChain(dsedSubHeaderBytes); subHeaderInfo += dsedSubHeader.toString(); } 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 { diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderCertChain.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderCertChain.java index eac5bc8a..dc7c22c3 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderCertChain.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderCertChain.java @@ -1,8 +1,8 @@ package hirs.utils.tpm.eventlog.events; import hirs.utils.HexUtils; +import hirs.utils.tpm.eventlog.spdm.SpdmCertificateChain; import hirs.utils.tpm.eventlog.spdm.SpdmHa; -import hirs.utils.tpm.eventlog.spdm.SpdmMeasurementBlock; import lombok.Getter; import java.io.ByteArrayInputStream; @@ -20,24 +20,33 @@ import java.util.ArrayList; * SPDM_CERT_CHAIN SpdmCertChain; * } DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN; *

+ * 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{ /** * SPDM version. */ - @Getter private int spdmVersion = 0; /** * SPDM slot ID. */ - @Getter - private int spdmLotId = 0; + private int spdmSlotId = 0; /** * SPDM base hash algorithm. */ - @Getter 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. @@ -52,7 +61,7 @@ public class DeviceSecurityEventDataSubHeaderCertChain extends DeviceSecurityEve byte[] spdmLotIdBytes = new byte[1]; System.arraycopy(dsedSubHBytes, 2, spdmLotIdBytes, 0, 1); - spdmLotId = HexUtils.leReverseInt(spdmLotIdBytes); + spdmSlotId = HexUtils.leReverseInt(spdmLotIdBytes); // byte[] reserved[Bytes]: 1 byte @@ -68,13 +77,15 @@ public class DeviceSecurityEventDataSubHeaderCertChain extends DeviceSecurityEve System.arraycopy(dsedSubHBytes, 8, spdmCertChainBytes, 0, spdmCertChainSize); -// ByteArrayInputStream spdmMeasurementBlockListData = -// new ByteArrayInputStream(spdmMeasurementBlockListBytes); -// while (spdmMeasurementBlockListData.available() > 0) { -// SpdmMeasurementBlock spdmMeasurementBlock; -// spdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasurementBlockListData); -// spdmMeasurementBlockList.add(spdmMeasurementBlock); -// } + int spdmBaseHashAlgoSize = SpdmHa.tcgAlgIdToByteSize(spdmBaseHashAlgo); + + if(spdmBaseHashAlgoSize > 0) { + spdmCertChain = new SpdmCertificateChain(spdmCertChainBytes, spdmBaseHashAlgoSize); + } + else { + spdmBaseHashAlgoError += "SPDM base hash algorithm size is not >0"; + } + } @@ -85,18 +96,13 @@ public class DeviceSecurityEventDataSubHeaderCertChain extends DeviceSecurityEve */ public String toString() { String dsedSubHeaderInfo = ""; -// dsedSubHeaderInfo += "\n SPDM Version: " + spdmVersion; -// String spdmHashAlgoStr = SpdmHa.tcgAlgIdToString(spdmMeasurementHashAlgo); -// dsedSubHeaderInfo += "\n SPDM Hash Algorithm = " + spdmHashAlgoStr; -// -// // SPDM Measurement Block List output -// dsedSubHeaderInfo += "\n Number of SPDM Measurement Blocks = " + spdmMeasurementBlockList.size(); -// int spdmMeasBlockCnt = 1; -// for (SpdmMeasurementBlock spdmMeasBlock : spdmMeasurementBlockList) { -// dsedSubHeaderInfo += "\n SPDM Measurement Block # " + spdmMeasBlockCnt++ + " of " + -// spdmMeasurementBlockList.size(); -// dsedSubHeaderInfo += spdmMeasBlock.toString(); -// } + dsedSubHeaderInfo += "\n SPDM Version = " + spdmVersion; + dsedSubHeaderInfo += "\n SPDM Slot ID = " + spdmSlotId; + String spdmBaseHashAlgoStr = SpdmHa.tcgAlgIdToString(spdmBaseHashAlgo); + dsedSubHeaderInfo += "\n SPDM Base Hash Algorithm = " + spdmBaseHashAlgoStr; + + // SPDM Certificate Chain output + dsedSubHeaderInfo += spdmCertChain.toString(); return dsedSubHeaderInfo; } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock.java index 9df680ac..19c5d42a 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock.java @@ -21,6 +21,14 @@ import java.util.List; * SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock[SpdmMeasurementBlockCount]; * } DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK; *

+ * + * 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 { @@ -68,7 +76,7 @@ public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends Device System.arraycopy(dsedSubHBytes, 4, spdmMeasurementHashAlgoBytes, 0, 4); 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; // extract the bytes that comprise the SPDM Measurement Block List @@ -92,7 +100,7 @@ public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends Device */ public String toString() { String dsedSubHeaderInfo = ""; - dsedSubHeaderInfo += "\n SPDM Version: " + spdmVersion; + dsedSubHeaderInfo += "\n SPDM Version = " + spdmVersion; String spdmHashAlgoStr = SpdmHa.tcgAlgIdToString(spdmMeasurementHashAlgo); dsedSubHeaderInfo += "\n SPDM Hash Algorithm = " + spdmHashAlgoStr; diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmCertificateChain.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmCertificateChain.java index ad6fb351..7aaf1cb2 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmCertificateChain.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmCertificateChain.java @@ -1,8 +1,10 @@ package hirs.utils.tpm.eventlog.spdm; import hirs.utils.HexUtils; +import hirs.utils.tpm.eventlog.events.DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock; import hirs.utils.tpm.eventlog.uefi.UefiConstants; import hirs.utils.tpm.eventlog.uefi.UefiSignatureData; +import hirs.utils.tpm.eventlog.uefi.UefiSignatureList; import hirs.utils.tpm.eventlog.uefi.UefiX509Cert; 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 * structure as the member "SpdmBaseHashAlg" * 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 * this field shall be in Encoded ASN.1 byte order */ @@ -44,75 +48,99 @@ public class SpdmCertificateChain { * Root hash. */ private byte[] rootHash = null; - /** * Number of certs in the SPDM cert chain. */ - @Getter private int numberOfCerts = 0; /** * Array List of certs found in the chain. */ // private ArrayList certList = new ArrayList(); private ArrayList certList = new ArrayList(); + /** + * 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. * * @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) { - byte[] lengthBytes = new byte[2]; - System.arraycopy(spdmCertChainBytes, 0, lengthBytes, 0, 2); - length = HexUtils.leReverseInt(lengthBytes); + if(rootHashLength <= 0) { + spdmBaseHashAlgoError = "SPDM base hash algorithm size is not >0"; + } + else { + byte[] lengthBytes = new byte[2]; + System.arraycopy(spdmCertChainBytes, 0, lengthBytes, 0, 2); + length = HexUtils.leReverseInt(lengthBytes); - // Reserved: 2 bytes + // Reserved: 2 bytes - rootHash = new byte[rootHashLength]; - System.arraycopy(spdmCertChainBytes, 4, rootHash, 0, rootHashLength); + rootHash = new byte[rootHashLength]; + System.arraycopy(spdmCertChainBytes, 4, rootHash, 0, rootHashLength); - int certChainStartPos = 4 + rootHashLength; - int certChainLength = spdmCertChainBytes.length - certChainStartPos; - byte[] certChainBytes = new byte[certChainLength]; - System.arraycopy(spdmCertChainBytes, certChainStartPos, certChainBytes, 0, certChainLength); + int certChainStartPos = 4 + rootHashLength; + int certChainLength = spdmCertChainBytes.length - certChainStartPos; + byte[] certChainBytes = new byte[certChainLength]; + System.arraycopy(spdmCertChainBytes, certChainStartPos, certChainBytes, 0, certChainLength); - 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) * * @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) - throws CertificateException, NoSuchAlgorithmException, IOException { + private void processCertChain(final byte[] certChainData) { UefiX509Cert cert = null; ByteArrayInputStream certChainDataIS = new ByteArrayInputStream(certChainData); while (certChainDataIS.available() > 0) { - byte[] certType = new byte[UefiConstants.SIZE_2]; - certChainDataIS.read(certType); - byte[] certLength = new byte[UefiConstants.SIZE_2]; - certChainDataIS.read(certLength); - int cLength = new BigInteger(certLength).intValue() + UefiConstants.SIZE_4; - byte[] certData = new byte[cLength]; - certChainDataIS.read(certData); - // put the cert back together - byte[] certBlob = new byte[cLength + UefiConstants.SIZE_4]; - System.arraycopy(certType, 0, certBlob, 0, 2); - System.arraycopy(certLength, 0, certBlob, 2, 2); - System.arraycopy(certData, 0, certBlob, UefiConstants.OFFSET_4, cLength); - cert = new UefiX509Cert(certBlob); + // 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]; + certChainDataIS.read(certType); + byte[] certLength = new byte[UefiConstants.SIZE_2]; + certChainDataIS.read(certLength); + int cLength = new BigInteger(certLength).intValue() + UefiConstants.SIZE_4; + byte[] certData = new byte[cLength]; + certChainDataIS.read(certData); + // put the cert back together + byte[] certBlob = new byte[cLength + UefiConstants.SIZE_4]; + System.arraycopy(certType, 0, certBlob, 0, 2); + System.arraycopy(certLength, 0, certBlob, 2, 2); + System.arraycopy(certData, 0, certBlob, UefiConstants.OFFSET_4, cLength); + + cert = new UefiX509Cert(certBlob); // cert = new X509Certificate(certBlob); - certList.add(cert); - numberOfCerts++; + certList.add(cert); + 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() { - String spdmMeasBlockInfo = ""; -// -// if(spdmMeasurementBlockReadError) { -// spdmMeasBlockInfo += "\n Error reading SPDM Measurement Block"; -// } -// else { -// spdmMeasBlockInfo += "\n Index = " + index; -// spdmMeasBlockInfo += "\n MeasurementSpec = " + measurementSpec; -// spdmMeasBlockInfo += spdmMeasurement.toString(); -// } -// - return spdmMeasBlockInfo; + String spdmCertChainInfo = ""; + + if(spdmBaseHashAlgoError != "") { + spdmCertChainInfo += "\n *** ERROR with SPDM base hash algorithm size ***"; + spdmCertChainInfo += "\n " + spdmBaseHashAlgoError; + spdmCertChainInfo += "\n Stopping processing of this cert chain"; + } + else { + spdmCertChainInfo += "\n Root hash = " + rootHash.toString(); + spdmCertChainInfo += "\n Number of certs in chain = " + numberOfCerts + "\n"; + + 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; } } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmHa.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmHa.java index c619ba92..0a937031 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmHa.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmHa.java @@ -75,4 +75,42 @@ public class SpdmHa { } 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; + } } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiSignatureData.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiSignatureData.java index d4d6b324..d38a3e98 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiSignatureData.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiSignatureData.java @@ -10,9 +10,15 @@ import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; /** - * Class for processing 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 + * Class for processing either + * 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 + * 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 *

* typedef struct _EFI_SIGNATURE_DATA { * EFI_GUID SignatureOwner; diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiSignatureList.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiSignatureList.java index b2a682d1..ec780cdb 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiSignatureList.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiSignatureList.java @@ -12,12 +12,18 @@ import java.util.ArrayList; import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIBLE; /** - * Class for processing the contents of a Secure Boot 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. + * Class for processing either + * 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 + * 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 *

- * An EFI Signature List is actual 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. + * 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 either the + * Secure Boot PK, KEK, Db and DBx variables + * or the SPDM devdb variable (under EV_EFI_SPDM_DEVICE_POLICY). *

* typedef struct _EFI_SIGNATURE_LIST { * EFI_GUID SignatureType; @@ -27,6 +33,27 @@ import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIB * // UINT8 SignatureHeader[SignatureHeaderSize]; * // EFI_SIGNATURE_DATA Signatures[...][SignatureSize]; * } 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 { /** @@ -125,7 +152,7 @@ public class UefiSignatureList { vendorTableFileStatus = signatureType.getVendorTableFileStatus(); // 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 if (!isValidSigListGUID(signatureType)) { //processSignatureData(lists); @@ -230,7 +257,10 @@ public class UefiSignatureList { sigInfo.append(" UEFI Signature List Type = " + signatureType.toString() + "\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++) { + sigInfo.append(" Cert or Hash # " + certOrHashCnt++ + " of " + + numberOfCerts + ": ------------------\n"); UefiSignatureData certData = sigList.get(i); sigInfo.append(certData.toString()); }