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;
+ }
}