mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-18 20:47:58 +00:00
Improve output for ACA-signed certificates (#859)
This commit is contained in:
parent
b163691d49
commit
9662c08e76
@ -116,7 +116,7 @@ public class AbstractProcessor {
|
|||||||
+ "Unable to issue certificates");
|
+ "Unable to issue certificates");
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentSigner signer = new JcaContentSignerBuilder("SHA1WithRSA")
|
ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA")
|
||||||
.setProvider("BC").build(getPrivateKey());
|
.setProvider("BC").build(getPrivateKey());
|
||||||
X509CertificateHolder holder = builder.build(signer);
|
X509CertificateHolder holder = builder.build(signer);
|
||||||
return new JcaX509CertificateConverter()
|
return new JcaX509CertificateConverter()
|
||||||
|
@ -160,16 +160,14 @@ public class CertificateRequestProcessor extends AbstractProcessor {
|
|||||||
attestationCertificate);
|
attestationCertificate);
|
||||||
byte[] derEncodedLdevidCertificate = ProvisionUtils.getDerEncodedCertificate(
|
byte[] derEncodedLdevidCertificate = ProvisionUtils.getDerEncodedCertificate(
|
||||||
ldevidCertificate);
|
ldevidCertificate);
|
||||||
|
String pemEncodedAttestationCertificate = ProvisionUtils.getPemEncodedCertificate(
|
||||||
|
attestationCertificate);
|
||||||
|
String pemEncodedLdevidCertificate = ProvisionUtils.getPemEncodedCertificate(
|
||||||
|
ldevidCertificate);
|
||||||
|
|
||||||
// We validated the nonce and made use of the identity claim so state can be deleted
|
// We validated the nonce and made use of the identity claim so state can be deleted
|
||||||
tpm2ProvisionerStateRepository.delete(tpm2ProvisionerState);
|
tpm2ProvisionerStateRepository.delete(tpm2ProvisionerState);
|
||||||
|
|
||||||
// Package the signed certificates into a response
|
|
||||||
ByteString certificateBytes = ByteString
|
|
||||||
.copyFrom(derEncodedAttestationCertificate);
|
|
||||||
ByteString ldevidCertificateBytes = ByteString
|
|
||||||
.copyFrom(derEncodedLdevidCertificate);
|
|
||||||
|
|
||||||
boolean generateAtt = saveAttestationCertificate(certificateRepository, derEncodedAttestationCertificate,
|
boolean generateAtt = saveAttestationCertificate(certificateRepository, derEncodedAttestationCertificate,
|
||||||
endorsementCredential, platformCredentials, device, false);
|
endorsementCredential, platformCredentials, device, false);
|
||||||
boolean generateLDevID = saveAttestationCertificate(certificateRepository, derEncodedLdevidCertificate,
|
boolean generateLDevID = saveAttestationCertificate(certificateRepository, derEncodedLdevidCertificate,
|
||||||
@ -178,10 +176,10 @@ public class CertificateRequestProcessor extends AbstractProcessor {
|
|||||||
ProvisionerTpm2.CertificateResponse.Builder builder = ProvisionerTpm2.CertificateResponse.
|
ProvisionerTpm2.CertificateResponse.Builder builder = ProvisionerTpm2.CertificateResponse.
|
||||||
newBuilder().setStatus(ProvisionerTpm2.ResponseStatus.PASS);
|
newBuilder().setStatus(ProvisionerTpm2.ResponseStatus.PASS);
|
||||||
if (generateAtt) {
|
if (generateAtt) {
|
||||||
builder = builder.setCertificate(certificateBytes);
|
builder = builder.setCertificate(pemEncodedAttestationCertificate);
|
||||||
}
|
}
|
||||||
if (generateLDevID) {
|
if (generateLDevID) {
|
||||||
builder = builder.setLdevidCertificate(ldevidCertificateBytes);
|
builder = builder.setLdevidCertificate(pemEncodedLdevidCertificate);
|
||||||
}
|
}
|
||||||
ProvisionerTpm2.CertificateResponse response = builder.build();
|
ProvisionerTpm2.CertificateResponse response = builder.build();
|
||||||
|
|
||||||
@ -190,20 +188,19 @@ public class CertificateRequestProcessor extends AbstractProcessor {
|
|||||||
else {
|
else {
|
||||||
byte[] derEncodedAttestationCertificate = ProvisionUtils.getDerEncodedCertificate(
|
byte[] derEncodedAttestationCertificate = ProvisionUtils.getDerEncodedCertificate(
|
||||||
attestationCertificate);
|
attestationCertificate);
|
||||||
|
String pemEncodedAttestationCertificate = ProvisionUtils.getPemEncodedCertificate(
|
||||||
|
attestationCertificate);
|
||||||
|
|
||||||
// We validated the nonce and made use of the identity claim so state can be deleted
|
// We validated the nonce and made use of the identity claim so state can be deleted
|
||||||
tpm2ProvisionerStateRepository.delete(tpm2ProvisionerState);
|
tpm2ProvisionerStateRepository.delete(tpm2ProvisionerState);
|
||||||
|
|
||||||
// Package the signed certificates into a response
|
|
||||||
ByteString certificateBytes = ByteString
|
|
||||||
.copyFrom(derEncodedAttestationCertificate);
|
|
||||||
ProvisionerTpm2.CertificateResponse.Builder builder = ProvisionerTpm2.CertificateResponse.
|
ProvisionerTpm2.CertificateResponse.Builder builder = ProvisionerTpm2.CertificateResponse.
|
||||||
newBuilder().setStatus(ProvisionerTpm2.ResponseStatus.PASS);
|
newBuilder().setStatus(ProvisionerTpm2.ResponseStatus.PASS);
|
||||||
|
|
||||||
boolean generateAtt = saveAttestationCertificate(certificateRepository, derEncodedAttestationCertificate,
|
boolean generateAtt = saveAttestationCertificate(certificateRepository, derEncodedAttestationCertificate,
|
||||||
endorsementCredential, platformCredentials, device, false);
|
endorsementCredential, platformCredentials, device, false);
|
||||||
if (generateAtt) {
|
if (generateAtt) {
|
||||||
builder = builder.setCertificate(certificateBytes);
|
builder = builder.setCertificate(pemEncodedAttestationCertificate);
|
||||||
}
|
}
|
||||||
ProvisionerTpm2.CertificateResponse response = builder.build();
|
ProvisionerTpm2.CertificateResponse response = builder.build();
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import hirs.utils.enums.DeviceInfoEnums;
|
|||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import org.apache.commons.codec.binary.Hex;
|
import org.apache.commons.codec.binary.Hex;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
import javax.crypto.BadPaddingException;
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
@ -28,6 +29,8 @@ import javax.crypto.spec.IvParameterSpec;
|
|||||||
import javax.crypto.spec.OAEPParameterSpec;
|
import javax.crypto.spec.OAEPParameterSpec;
|
||||||
import javax.crypto.spec.PSource;
|
import javax.crypto.spec.PSource;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@ -107,6 +110,29 @@ public final class ProvisionUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to extract a PEM encoded certificate from an X509 certificate.
|
||||||
|
*
|
||||||
|
* @param certificate the X509 certificate to be converted to PEM encoding
|
||||||
|
* @throws {@link UnexpectedServerException} if error occurs during encoding retrieval
|
||||||
|
* @return the string representing the PEM encoded certificate
|
||||||
|
*/
|
||||||
|
public static String getPemEncodedCertificate(final X509Certificate certificate) {
|
||||||
|
try {
|
||||||
|
final StringWriter stringWriter = new StringWriter();
|
||||||
|
final JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter);
|
||||||
|
pemWriter.writeObject(certificate);
|
||||||
|
pemWriter.flush();
|
||||||
|
pemWriter.close();
|
||||||
|
return stringWriter.toString();
|
||||||
|
} catch (IOException ioEx) {
|
||||||
|
log.error("Error converting certificate to PEM Encoding.", ioEx);
|
||||||
|
throw new UnexpectedServerException(
|
||||||
|
"Encountered error while converting X509 Certificate to PEM Encoding: "
|
||||||
|
+ ioEx.getMessage(), ioEx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse public key from public data segment generated by TPM 2.0.
|
* Parse public key from public data segment generated by TPM 2.0.
|
||||||
* @param publicArea the public area segment to parse
|
* @param publicArea the public area segment to parse
|
||||||
|
@ -95,8 +95,8 @@ message CertificateRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message CertificateResponse {
|
message CertificateResponse {
|
||||||
optional bytes certificate = 1;
|
optional string certificate = 1;
|
||||||
optional ResponseStatus status = 2 [default = FAIL];
|
optional ResponseStatus status = 2 [default = FAIL];
|
||||||
optional bytes ldevidCertificate = 3;
|
optional string ldevidCertificate = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +297,7 @@ namespace hirs {
|
|||||||
tpm.GetQuote(CommandTpm.DefaultAkHandle, Tpm2Lib.TpmAlgId.Sha256, recoveredSecret, out CommandTpmQuoteResponse ctqr, selectPcrs);
|
tpm.GetQuote(CommandTpm.DefaultAkHandle, Tpm2Lib.TpmAlgId.Sha256, recoveredSecret, out CommandTpmQuoteResponse ctqr, selectPcrs);
|
||||||
Log.Information("----> Nonce successfully decrypted. Sending attestation certificate request");
|
Log.Information("----> Nonce successfully decrypted. Sending attestation certificate request");
|
||||||
CertificateRequest akCertReq = acaClient.CreateAkCertificateRequest(recoveredSecret, ctqr);
|
CertificateRequest akCertReq = acaClient.CreateAkCertificateRequest(recoveredSecret, ctqr);
|
||||||
byte[] certificate;
|
string certificate;
|
||||||
Log.Debug("Communicate certificate request to the ACA.");
|
Log.Debug("Communicate certificate request to the ACA.");
|
||||||
CertificateResponse cr = await acaClient.PostCertificateRequest(akCertReq);
|
CertificateResponse cr = await acaClient.PostCertificateRequest(akCertReq);
|
||||||
Log.Debug("Response received from the ACA regarding the certificate request.");
|
Log.Debug("Response received from the ACA regarding the certificate request.");
|
||||||
@ -311,34 +311,34 @@ namespace hirs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cr.HasCertificate) {
|
if (cr.HasCertificate) {
|
||||||
certificate = cr.Certificate.ToByteArray(); // contains certificate
|
certificate = cr.Certificate.ToString(); // contains certificate
|
||||||
String certificateDirPath = settings.certificate_output_directory;
|
String certificateDirPath = settings.certificate_output_directory;
|
||||||
if (certificateDirPath != null) {
|
if (certificateDirPath != null) {
|
||||||
String certificateFilePath = FormatCertificatePath(dv, certificateDirPath, DefaultAKCertFileName);
|
String certificateFilePath = FormatCertificatePath(dv, certificateDirPath, DefaultAKCertFileName);
|
||||||
try {
|
try {
|
||||||
File.WriteAllBytes(certificateFilePath, certificate);
|
File.WriteAllText(certificateFilePath, certificate);
|
||||||
Log.Debug("Attestation key certificate written to local file system: {0}", certificateFilePath);
|
Log.Debug("Attestation key certificate written to local file system: {0}", certificateFilePath);
|
||||||
}
|
}
|
||||||
catch (Exception) {
|
catch (Exception) {
|
||||||
Log.Debug("Failed to write attestation key certificate to local file system.");
|
Log.Debug("Failed to write attestation key certificate to local file system.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.Debug("Printing attestation key certificate: " + BitConverter.ToString(certificate));
|
Log.Debug("Printing attestation key certificate: " + certificate);
|
||||||
}
|
}
|
||||||
if (cr.HasLdevidCertificate) {
|
if (cr.HasLdevidCertificate) {
|
||||||
certificate = cr.LdevidCertificate.ToByteArray(); // contains certificate
|
certificate = cr.LdevidCertificate.ToString(); // contains certificate
|
||||||
String certificateDirPath = settings.certificate_output_directory;
|
String certificateDirPath = settings.certificate_output_directory;
|
||||||
if (certificateDirPath != null) {
|
if (certificateDirPath != null) {
|
||||||
String certificateFilePath = FormatCertificatePath(dv, certificateDirPath, DefaultLDevIDCertFileName);
|
String certificateFilePath = FormatCertificatePath(dv, certificateDirPath, DefaultLDevIDCertFileName);
|
||||||
try {
|
try {
|
||||||
File.WriteAllBytes(certificateFilePath, certificate);
|
File.WriteAllText(certificateFilePath, certificate);
|
||||||
Log.Debug("LDevID certificate written to local file system: {0}", certificateFilePath);
|
Log.Debug("LDevID certificate written to local file system: {0}", certificateFilePath);
|
||||||
}
|
}
|
||||||
catch (Exception) {
|
catch (Exception) {
|
||||||
Log.Debug("Failed to write LDevID certificate to local file system.");
|
Log.Debug("Failed to write LDevID certificate to local file system.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.Debug("Printing LDevID certificate: " + BitConverter.ToString(certificate));
|
Log.Debug("Printing LDevID certificate: " + certificate);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = ClientExitCodes.MAKE_CREDENTIAL_BLOB_MALFORMED;
|
result = ClientExitCodes.MAKE_CREDENTIAL_BLOB_MALFORMED;
|
||||||
|
@ -14,7 +14,7 @@ namespace hirsTest {
|
|||||||
const string address = "https://127.0.0.1:8443/";
|
const string address = "https://127.0.0.1:8443/";
|
||||||
byte[] ekCert = Encoding.UTF8.GetBytes("EK CERTIFICATE");
|
byte[] ekCert = Encoding.UTF8.GetBytes("EK CERTIFICATE");
|
||||||
byte[] secret = Encoding.UTF8.GetBytes("AuthCredential Secret");
|
byte[] secret = Encoding.UTF8.GetBytes("AuthCredential Secret");
|
||||||
byte[] acaIssuedCert = Encoding.UTF8.GetBytes("ACA ISSUED CERTIFICATE");
|
string acaIssuedCert = "ACA ISSUED CERTIFICATE";
|
||||||
byte[] integrityHMAC = Convert.FromBase64String("VAtedc1RlNA1w0XfrtwmhE0ILBlILP6163Tur5HRIo0=");
|
byte[] integrityHMAC = Convert.FromBase64String("VAtedc1RlNA1w0XfrtwmhE0ILBlILP6163Tur5HRIo0=");
|
||||||
byte[] encIdentity = Convert.FromBase64String("6e2oGBsK3H9Vzbj667ZsjnVOtvpSpQ==");
|
byte[] encIdentity = Convert.FromBase64String("6e2oGBsK3H9Vzbj667ZsjnVOtvpSpQ==");
|
||||||
byte[] encryptedSecret = Convert.FromBase64String("NekvnOX8RPRdyd0/cxBI4FTCuNkiu0KAnS28yT7yYJUL5Lwfcv5ctEK6zQA0fq0IsX5TlAYSidGKxrAilOSwALJmJ+m7sMiXwMKrZn1cd4gzXObZEQimQoWgSEQbPO7rfpUn1UfI8K5SzmUFUTxc5X3D8zFonaEBp6QCjtdLegKGgioCDcQFdz20Y0PFAa1Itug7YbZdCFpfit570eQQinmqdVryiNyn6CLQdMgIejuBxoEpoTSWszB5eFKEdn5g/+8wcvhp6RpNBQ0hikF+6688TOVK/j8n3JDwKVltJ/WNHjVO+lxa2aLIMJRgs5ZRuzuz6OSMf10KqJjSWZE04w==");
|
byte[] encryptedSecret = Convert.FromBase64String("NekvnOX8RPRdyd0/cxBI4FTCuNkiu0KAnS28yT7yYJUL5Lwfcv5ctEK6zQA0fq0IsX5TlAYSidGKxrAilOSwALJmJ+m7sMiXwMKrZn1cd4gzXObZEQimQoWgSEQbPO7rfpUn1UfI8K5SzmUFUTxc5X3D8zFonaEBp6QCjtdLegKGgioCDcQFdz20Y0PFAa1Itug7YbZdCFpfit570eQQinmqdVryiNyn6CLQdMgIejuBxoEpoTSWszB5eFKEdn5g/+8wcvhp6RpNBQ0hikF+6688TOVK/j8n3JDwKVltJ/WNHjVO+lxa2aLIMJRgs5ZRuzuz6OSMf10KqJjSWZE04w==");
|
||||||
@ -34,7 +34,7 @@ namespace hirsTest {
|
|||||||
idClaimResp.CredentialBlob = Google.Protobuf.ByteString.CopyFrom(credentialBlob);
|
idClaimResp.CredentialBlob = Google.Protobuf.ByteString.CopyFrom(credentialBlob);
|
||||||
CertificateResponse certResp = new();
|
CertificateResponse certResp = new();
|
||||||
certResp.Status = ResponseStatus.Pass;
|
certResp.Status = ResponseStatus.Pass;
|
||||||
certResp.Certificate = Google.Protobuf.ByteString.CopyFrom(acaIssuedCert);
|
certResp.Certificate = acaIssuedCert;
|
||||||
|
|
||||||
IHirsAcaTpm tpm = A.Fake<IHirsAcaTpm>();
|
IHirsAcaTpm tpm = A.Fake<IHirsAcaTpm>();
|
||||||
byte[] name = null, qualifiedName = null;
|
byte[] name = null, qualifiedName = null;
|
||||||
|
@ -95,8 +95,8 @@ message CertificateRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message CertificateResponse {
|
message CertificateResponse {
|
||||||
optional bytes certificate = 1;
|
optional string certificate = 1;
|
||||||
optional ResponseStatus status = 2 [default = FAIL];
|
optional ResponseStatus status = 2 [default = FAIL];
|
||||||
optional bytes ldevidCertificate = 3;
|
optional string ldevidCertificate = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user