mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-24 07:06:46 +00:00
parsing SPDM cert chain
This commit is contained in:
parent
602fd88e53
commit
0266b5293e
@ -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);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
* <p>
|
||||
* 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 <H> bytes;
|
||||
* Certificates <Length> - (4 + <H>) 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<X509Certificate> certList = new ArrayList<X509Certificate>();
|
||||
private ArrayList<UefiX509Cert> certList = new ArrayList<UefiX509Cert>();
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user