From 0266b5293ed82ef6bf7eceb7cb1fbd8fce7a8d7d Mon Sep 17 00:00:00 2001 From: iadgovuser58 <124906646+iadgovuser58@users.noreply.github.com> Date: Fri, 19 Jul 2024 18:18:06 -0400 Subject: [PATCH] parsing SPDM cert chain --- ...ceSecurityEventDataSubHeaderCertChain.java | 16 ++- .../eventlog/spdm/SpdmCertificateChain.java | 105 ++++++++++++------ 2 files changed, 80 insertions(+), 41 deletions(-) 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 2c77e2bf..45c9e722 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 @@ -45,8 +45,6 @@ public class DeviceSecurityEventDataSubHeaderCertChain extends DeviceSecurityEve */ public DeviceSecurityEventDataSubHeaderCertChain(final byte[] dsedSubHBytes) { - spdmMeasurementBlockList = new ArrayList<>(); - byte[] spdmVersionBytes = new byte[2]; System.arraycopy(dsedSubHBytes, 0, spdmVersionBytes, 0, 2); spdmVersion = HexUtils.leReverseInt(spdmVersionBytes); @@ -69,12 +67,12 @@ 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); - } +// ByteArrayInputStream spdmMeasurementBlockListData = +// new ByteArrayInputStream(spdmMeasurementBlockListBytes); +// while (spdmMeasurementBlockListData.available() > 0) { +// SpdmMeasurementBlock spdmMeasurementBlock; +// spdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasurementBlockListData); +// spdmMeasurementBlockList.add(spdmMeasurementBlock); +// } } } 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 5a876a0a..ad6fb351 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,17 +1,25 @@ package hirs.utils.tpm.eventlog.spdm; import hirs.utils.HexUtils; +import hirs.utils.tpm.eventlog.uefi.UefiConstants; +import hirs.utils.tpm.eventlog.uefi.UefiSignatureData; +import hirs.utils.tpm.eventlog.uefi.UefiX509Cert; import lombok.Getter; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.math.BigInteger; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; /** * Class to process the SpdmCertificateChain. *

* Certificate chain format, defined by SPDM v1.03, Sect 10.6.1, Table 33: * Certificate chain format { - * Length 1 byte; + * Length 2 bytes; * Reserved 2 bytes; * RootHash bytes; * Certificates - (4 + ) bytes; @@ -31,47 +39,80 @@ public class SpdmCertificateChain { /** * Length of the certificate chain to include all fields in this structure. */ - @Getter private int length = 0; /** * Root hash. */ private byte[] rootHash = null; - /** - * Certificates. - */ -// private SpdmMeasurement spdmMeasurement; - /** - * Error reading SPDM Cert Chain. - */ - private boolean spdmCertificateChainReadError = false; /** - * SpdmMeasurementBlock Constructor. + * 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(); + + /** + * SpdmCertificateChain Constructor. * - * @param spdmMeasBlocks byte array holding the SPDM Measurement Block bytes. + * @param spdmCertChainBytes byte array holding the SPDM Cert Chain bytes. */ - public SpdmCertificateChain(final ByteArrayInputStream spdmMeasBlocks) { + public SpdmCertificateChain(final byte[] spdmCertChainBytes, final int rootHashLength) throws CertificateException, NoSuchAlgorithmException, IOException { - try { - byte[] indexBytes = new byte[1]; - spdmMeasBlocks.read(indexBytes); - index = HexUtils.leReverseInt(indexBytes); + byte[] lengthBytes = new byte[2]; + System.arraycopy(spdmCertChainBytes, 0, lengthBytes, 0, 2); + length = HexUtils.leReverseInt(lengthBytes); - byte[] measurementSpecBytes = new byte[1]; - spdmMeasBlocks.read(measurementSpecBytes); - measurementSpec = HexUtils.leReverseInt(measurementSpecBytes); + // Reserved: 2 bytes - // in future, can crosscheck this measurement size with the MeasurementSpec hash alg size - byte[] measurementSizeBytes = new byte[2]; - spdmMeasBlocks.read(measurementSizeBytes); - int measurementSize = HexUtils.leReverseInt(measurementSizeBytes); + rootHash = new byte[rootHashLength]; + System.arraycopy(spdmCertChainBytes, 4, rootHash, 0, rootHashLength); - byte[] measurementBytes = new byte[measurementSize]; - spdmMeasBlocks.read(measurementBytes); - spdmMeasurement = new SpdmMeasurement(measurementBytes); - } catch (IOException ioEx) { - spdmMeasurementBlockReadError = true; + int certChainStartPos = 4 + rootHashLength; + int certChainLength = spdmCertChainBytes.length - certChainStartPos; + byte[] certChainBytes = new byte[certChainLength]; + System.arraycopy(spdmCertChainBytes, certChainStartPos, certChainBytes, 0, certChainLength); + + 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 { + + 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); +// cert = new X509Certificate(certBlob); + certList.add(cert); + numberOfCerts++; } } @@ -82,7 +123,7 @@ public class SpdmCertificateChain { */ public String toString() { -// String spdmMeasBlockInfo = ""; + String spdmMeasBlockInfo = ""; // // if(spdmMeasurementBlockReadError) { // spdmMeasBlockInfo += "\n Error reading SPDM Measurement Block"; @@ -93,6 +134,6 @@ public class SpdmCertificateChain { // spdmMeasBlockInfo += spdmMeasurement.toString(); // } // -// return spdmMeasBlockInfo; -// } + return spdmMeasBlockInfo; + } }