From 8964f31aea5ba3a1922b6f215953632c05c8ec79 Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Thu, 19 Feb 2026 17:51:18 -0500
Subject: [PATCH 01/25] v3.1_issue_1090: First cut of the fixing the ecc
provisioning issue.
---
.../AttestationCertificateAuthority.java | 7 +-
...estfulAttestationCertificateAuthority.java | 7 +-
.../persist/RestfulInterface.java | 4 +-
.../persist/enums/PublicKeyAlgorithm.java | 34 ++++
.../CertificateRequestProcessor.java | 30 ++--
.../provision/IdentityClaimProcessor.java | 4 +-
.../provision/helper/ProvisionUtils.java | 156 ++++++++++--------
.../AttestationCertificateAuthorityTest.java | 86 +++++-----
.../converters/SimpleStructBuilder.java | 2 +-
9 files changed, 195 insertions(+), 135 deletions(-)
create mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java
index f45c7269e..c34dbeb36 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java
@@ -15,6 +15,7 @@
import hirs.structs.converters.StructConverter;
import lombok.extern.log4j.Log4j2;
+import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
@@ -23,7 +24,7 @@
* Identity Request.
*/
@Log4j2
-public abstract class AttestationCertificateAuthority {
+public abstract class AttestationCertificateAuthority implements RestfulInterface {
/**
* Container wired ACA private key.
@@ -125,7 +126,7 @@ public AttestationCertificateAuthority(
* @param identityClaim a byte array representation of the identity claim
* @return processed identity claim response
*/
- byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
+ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
return this.identityClaimHandler.processIdentityClaimTpm2(identityClaim);
}
@@ -135,7 +136,7 @@ byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
* @param certificateRequest a byte array representation of the certificate request
* @return processed certificate request response
*/
- byte[] processCertificateRequest(final byte[] certificateRequest) {
+ public byte[] processCertificateRequest(final byte[] certificateRequest) throws GeneralSecurityException {
return this.certificateRequestHandler.processCertificateRequest(certificateRequest);
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java
index 58a3b42f1..5bafc5b92 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java
@@ -25,6 +25,7 @@
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
+import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
@@ -42,9 +43,7 @@
@Log4j2
@RestController
@RequestMapping("/HIRS_AttestationCA")
-public class RestfulAttestationCertificateAuthority extends AttestationCertificateAuthority
- implements RestfulInterface {
-
+public class RestfulAttestationCertificateAuthority extends AttestationCertificateAuthority {
/**
* Constructor.
*
@@ -118,7 +117,7 @@ public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim)
@ResponseBody
@PostMapping(value = "/request-certificate-tpm2",
consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
- public byte[] processCertificateRequest(@RequestBody final byte[] certificateRequest) {
+ public byte[] processCertificateRequest(@RequestBody final byte[] certificateRequest) throws GeneralSecurityException {
return super.processCertificateRequest(certificateRequest);
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulInterface.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulInterface.java
index a4bb8a00a..0c8bf7766 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulInterface.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulInterface.java
@@ -1,5 +1,7 @@
package hirs.attestationca.persist;
+import java.security.GeneralSecurityException;
+
/**
* Defines the responsibilities of the Attestation Certificate Authority.
*/
@@ -19,6 +21,6 @@ public interface RestfulInterface {
* @param certificateRequest a byte array representation of the certificate request
* @return a byte array representation of the certificate request response
*/
- byte[] processCertificateRequest(byte[] certificateRequest);
+ byte[] processCertificateRequest(byte[] certificateRequest) throws GeneralSecurityException;
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
new file mode 100644
index 000000000..1842b61b7
--- /dev/null
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
@@ -0,0 +1,34 @@
+package hirs.attestationca.persist.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.ToString;
+
+import java.security.PublicKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPublicKey;
+
+/**
+ * Enum representing public key algorithms for asymmetric cryptography.
+ *
+ * This enum currently includes:
+ *
+ * - {@link #RSA} – RSA public-key algorithm.
+ * - {@link #EC} – Elliptic Curve (EC) public-key algorithm, commonly referred to as ECC.
+ *
+ *
+ * Each enum constant also holds its corresponding JCA (Java Cryptography Architecture)
+ * standard name, which can be used when creating KeyFactory or Cipher instances.
+ */
+@Getter
+@AllArgsConstructor
+@ToString
+public enum PublicKeyAlgorithm {
+ RSA("RSA", RSAPublicKey.class),
+ EC("EC", ECPublicKey.class),
+ UNKNOWN("", null);
+
+ private final String algorithmName;
+ private final Class extends PublicKey> keyClass;
+}
+
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
index cc9e0b197..f51c53ae5 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
@@ -23,9 +23,10 @@
import org.apache.commons.lang3.ArrayUtils;
import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
import java.security.PrivateKey;
+import java.security.PublicKey;
import java.security.cert.X509Certificate;
-import java.security.interfaces.RSAPublicKey;
import java.util.List;
@Log4j2
@@ -75,12 +76,13 @@ public CertificateRequestProcessor(final SupplyChainValidationService supplyChai
* claim handshake
* @return a certificateResponse containing the signed certificate
*/
- public byte[] processCertificateRequest(final byte[] certificateRequest) {
+ public byte[] processCertificateRequest(final byte[] certificateRequest) throws GeneralSecurityException {
log.info("Certificate Request has been received and is ready to be processed");
if (ArrayUtils.isEmpty(certificateRequest)) {
- throw new IllegalArgumentException("The CertificateRequest sent by the client"
- + " cannot be null or empty.");
+ final String errorMsg = "The CertificateRequest sent by the client cannot be null or empty.";
+ log.error(errorMsg);
+ throw new IllegalArgumentException(errorMsg);
}
final PolicyRepository policyRepository = this.getPolicyRepository();
@@ -91,15 +93,16 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
try {
request = ProvisionerTpm2.CertificateRequest.parseFrom(certificateRequest);
} catch (InvalidProtocolBufferException ipbe) {
- throw new CertificateProcessingException(
- "Could not deserialize Protobuf Certificate Request object.", ipbe);
+ final String errorMsg = "Could not deserialize Protobuf Certificate Request object.";
+ log.error(errorMsg);
+ throw new CertificateProcessingException(errorMsg, ipbe);
}
String certificateRequestJsonString = "";
try {
certificateRequestJsonString = JsonFormat.printer().print(request);
} catch (InvalidProtocolBufferException exception) {
- log.error("Certificate request could not be parsed properly into a json string");
+ log.error("Certificate request could not be parsed properly into a JSON string");
}
// attempt to retrieve provisioner state based on nonce in request
@@ -111,23 +114,22 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
ProvisionerTpm2.IdentityClaim claim = ProvisionUtils.parseIdentityClaim(identityClaim);
// Get endorsement public key
- RSAPublicKey ekPub = ProvisionUtils.parsePublicKey(claim.getEkPublicArea().toByteArray());
+ PublicKey ekPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(claim.getEkPublicArea().toByteArray());
// Get attestation public key
- RSAPublicKey akPub = ProvisionUtils.parsePublicKey(claim.getAkPublicArea().toByteArray());
+ PublicKey akPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(claim.getAkPublicArea().toByteArray());
// Get Endorsement Credential if it exists or was uploaded
- EndorsementCredential endorsementCredential = parseEcFromIdentityClaim(claim,
- ekPub, certificateRepository);
+ EndorsementCredential endorsementCredential = parseEcFromIdentityClaim(claim, ekPub, certificateRepository);
// Get Platform Credentials if they exist or were uploaded
List platformCredentials = parsePcsFromIdentityClaim(claim,
endorsementCredential, certificateRepository);
// Get LDevID public key if it exists
- RSAPublicKey ldevidPub = null;
+ PublicKey ldevidPub = null;
if (claim.hasLdevidPublicArea()) {
- ldevidPub = ProvisionUtils.parsePublicKey(claim.getLdevidPublicArea().toByteArray());
+ ldevidPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(claim.getLdevidPublicArea().toByteArray());
}
// Get device name and device
@@ -136,7 +138,7 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
// Parse through the Provisioner supplied TPM Quote and pcr values
// these fields are optional
- if (request.getQuote() != null && !request.getQuote().isEmpty()) {
+ if (!request.getQuote().isEmpty()) {
TPMInfo savedInfo = device.getDeviceInfo().getTpmInfo();
TPMInfo tpmInfo = new TPMInfo(savedInfo.getTpmMake(),
savedInfo.getTpmVersionMajor(),
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
index 4866ff654..8252ce2d7 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
@@ -156,7 +156,7 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
// parse the EK Public key from the IdentityClaim once for use in supply chain validation
// and later tpm20MakeCredential function
- RSAPublicKey ekPub = ProvisionUtils.parsePublicKey(claim.getEkPublicArea().toByteArray());
+ RSAPublicKey ekPub = ProvisionUtils.parseRSAKeyFromPublicDataSegment(claim.getEkPublicArea().toByteArray());
AppraisalStatus.Status validationResult = AppraisalStatus.Status.FAIL;
try {
@@ -168,7 +168,7 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
ByteString blobStr = ByteString.copyFrom(new byte[]{});
if (validationResult == AppraisalStatus.Status.PASS) {
- RSAPublicKey akPub = ProvisionUtils.parsePublicKey(claim.getAkPublicArea().toByteArray());
+ RSAPublicKey akPub = ProvisionUtils.parseRSAKeyFromPublicDataSegment(claim.getAkPublicArea().toByteArray());
byte[] nonce = ProvisionUtils.generateRandomBytes(NONCE_LENGTH);
blobStr = ProvisionUtils.tpm20MakeCredential(ekPub, akPub, nonce);
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index 88c747fe7..4ff13866b 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -3,13 +3,13 @@
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
+import hirs.attestationca.persist.enums.PublicKeyAlgorithm;
import hirs.attestationca.persist.exceptions.CertificateProcessingException;
import hirs.attestationca.persist.exceptions.IdentityProcessingException;
import hirs.attestationca.persist.exceptions.UnexpectedServerException;
import hirs.structs.converters.SimpleStructBuilder;
import hirs.structs.elements.aca.SymmetricAttestation;
import hirs.structs.elements.tpm.EncryptionScheme;
-import hirs.structs.elements.tpm.IdentityRequest;
import hirs.structs.elements.tpm.SymmetricKey;
import hirs.structs.elements.tpm.SymmetricKeyParams;
import hirs.utils.HexUtils;
@@ -32,6 +32,7 @@
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
@@ -42,10 +43,12 @@
import java.security.SecureRandom;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.RSAPublicKeySpec;
+import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
@Log4j2
@@ -112,7 +115,6 @@ private ProvisionUtils() {
* @param identityClaim byte array that should be converted to a Protobuf IdentityClaim
* object
* @return the Protobuf generated Identity Claim object
- * @throws {@link InvalidProtocolBufferException} if byte array could not be parsed
*/
public static ProvisionerTpm2.IdentityClaim parseIdentityClaim(final byte[] identityClaim) {
try {
@@ -128,7 +130,6 @@ public static ProvisionerTpm2.IdentityClaim parseIdentityClaim(final byte[] iden
*
* @param certificate the X509 certificate to be converted to DER encoding
* @return the byte array representing the DER encoded certificate
- * @throws {@link UnexpectedServerException} if error occurs during encoding retrieval
*/
public static byte[] getDerEncodedCertificate(final X509Certificate certificate) {
try {
@@ -145,7 +146,6 @@ public static byte[] getDerEncodedCertificate(final X509Certificate certificate)
* 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) {
@@ -165,13 +165,31 @@ public static String getPemEncodedCertificate(final X509Certificate certificate)
}
/**
- * Parse public key from public data segment generated by TPM 2.0.
+ * Parses a public key from a byte array and returns it as a generic PublicKey.
+ * Supports RSA and EC (Elliptic Curve) keys.
+ *
+ * @param keyBytes the DER-encoded public key bytes
+ * @return the parsed PublicKey instance
+ * @throws GeneralSecurityException if the key cannot be parsed
+ */
+ public static PublicKey parsePublicKeyFromPublicDataSegment(byte[] keyBytes) throws GeneralSecurityException {
+ PublicKeyAlgorithm publicKeyAlgorithm = determineKeyType(keyBytes);
+
+ return switch (publicKeyAlgorithm) {
+ case RSA -> parseRSAKeyFromPublicDataSegment(keyBytes);
+ case EC -> parseECKeyFromPublicDataSegment(keyBytes);
+ default -> throw new GeneralSecurityException("Unsupported or invalid public key");
+ };
+ }
+
+ /**
+ * Parses the RSA public key from public data segment generated by TPM 2.0.
*
* @param publicArea the public area segment to parse
* @return the RSA public key of the supplied public data
*/
- public static RSAPublicKey parsePublicKey(final byte[] publicArea) {
- int pubLen = publicArea.length;
+ public static RSAPublicKey parseRSAKeyFromPublicDataSegment(final byte[] publicArea) {
+ final int pubLen = publicArea.length;
if (pubLen < RSA_MODULUS_LENGTH) {
throw new IllegalArgumentException(
"EK or AK public data segment is not long enough");
@@ -180,36 +198,36 @@ public static RSAPublicKey parsePublicKey(final byte[] publicArea) {
byte[] modulus = HexUtils.subarray(publicArea,
pubLen - RSA_MODULUS_LENGTH,
pubLen - 1);
- return (RSAPublicKey) assemblePublicKey(modulus);
+ return (RSAPublicKey) assembleRSAPublicKey(modulus);
}
/**
- * Constructs a public key where the modulus is in raw form.
+ * Constructs an RSA public key where the modulus is in raw form.
*
* @param modulus in byte array form
- * @return public key using specific modulus and the well known exponent
+ * @return RSA public key using specific modulus and the well known exponent
*/
- public static PublicKey assemblePublicKey(final byte[] modulus) {
- return assemblePublicKey(Hex.encodeHexString(modulus));
+ public static PublicKey assembleRSAPublicKey(final byte[] modulus) {
+ return assembleRSAPublicKey(Hex.encodeHexString(modulus));
}
/**
- * Constructs a public key where the modulus is Hex encoded.
+ * Constructs an RSA public key where the modulus is Hex encoded.
*
* @param modulus hex encoded modulus
- * @return public key using specific modulus and the well known exponent
+ * @return RSA public key using specific modulus and the well known exponent
*/
- public static PublicKey assemblePublicKey(final String modulus) {
- return assemblePublicKey(new BigInteger(modulus, DEFAULT_IV_SIZE));
+ public static PublicKey assembleRSAPublicKey(final String modulus) {
+ return assembleRSAPublicKey(new BigInteger(modulus, DEFAULT_IV_SIZE));
}
/**
- * Assembles a public key using a defined big int modulus and the well known exponent.
+ * Assembles an RSA public key using a defined big int modulus and the well known exponent.
*
* @param modulus modulus
- * @return public key using the provided integer modulus
+ * @return RSA public key using the provided integer modulus
*/
- public static PublicKey assemblePublicKey(final BigInteger modulus) {
+ public static PublicKey assembleRSAPublicKey(final BigInteger modulus) {
// generate a key spec using mod and exp
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, EXPONENT);
@@ -223,6 +241,16 @@ public static PublicKey assemblePublicKey(final BigInteger modulus) {
}
}
+ /**
+ * Parses the ECC public key from public data segment generated by TPM 2.0.
+ *
+ * @param publicArea the public area segment to parse
+ * @return the ECC public key of the supplied public data
+ */
+ public static ECPublicKey parseECKeyFromPublicDataSegment(final byte[] publicArea) {
+ return null;
+ }
+
/**
* Will attempt to decrypt the asymmetric blob that originated from an
* {@link hirs.structs.elements.tpm.IdentityRequest} using the cipher transformation.
@@ -290,8 +318,7 @@ public static byte[] decryptSymmetricBlob(final byte[] symmetricBlob, final byte
} catch (IllegalBlockSizeException | InvalidKeyException | NoSuchAlgorithmException
| BadPaddingException | NoSuchPaddingException
| InvalidAlgorithmParameterException exception) {
- log.error("Encountered error while decrypting symmetric blob of an identity request: "
- + exception.getMessage(), exception);
+ log.error("Encountered error while decrypting symmetric blob of an identity request: {}", exception.getMessage(), exception);
}
return new byte[0];
@@ -308,12 +335,10 @@ public static SymmetricKey generateSymmetricKey() {
generateRandomBytes(DEFAULT_IV_SIZE);
// create a symmetric key struct for the CA contents
- SymmetricKey sessionKey =
- new SimpleStructBuilder<>(SymmetricKey.class)
- .set("algorithmId", SymmetricKey.ALGORITHM_AES)
- .set("encryptionScheme", SymmetricKey.SCHEME_CBC)
- .set("key", responseSymmetricKey).build();
- return sessionKey;
+ return new SimpleStructBuilder<>(SymmetricKey.class)
+ .set("algorithmId", SymmetricKey.ALGORITHM_AES)
+ .set("encryptionScheme", SymmetricKey.SCHEME_CBC)
+ .set("key", responseSymmetricKey).build();
}
/**
@@ -452,35 +477,6 @@ public static byte[] generateAsymmetricContents(final byte[] identityKey,
}
}
- /**
- * Extracts the IV from the identity request. That is, take the first block of data from the
- * symmetric blob and treat that as the IV. This modifies the original symmetric block.
- *
- * @param identityRequest to extract the IV from
- * @return the IV from the identity request
- */
- public static byte[] extractInitialValue(final IdentityRequest identityRequest) {
- // make a reference to the symmetric blob
- byte[] symmetricBlob = identityRequest.getSymmetricBlob();
-
- // create the IV
- byte[] iv = new byte[DEFAULT_IV_SIZE];
-
- // initialize a new symmetric blob with the length of the original minus the IV
- byte[] updatedBlob = new byte[symmetricBlob.length - iv.length];
-
- // copy the IV out of the original symmetric blob
- System.arraycopy(symmetricBlob, 0, iv, 0, iv.length);
-
- // copy everything but the IV out of the original blob into the new blob
- System.arraycopy(symmetricBlob, iv.length, updatedBlob, 0, updatedBlob.length);
-
- // reassign the symmetric blob to the request.
- identityRequest.setSymmetricBlob(updatedBlob);
-
- return iv;
- }
-
/**
* Generate the Identity Response using the identity credential and the session key.
*
@@ -513,17 +509,15 @@ public static SymmetricAttestation generateAttestation(final X509Certificate cre
byte[] credentialBytes = ArrayUtils.addAll(credentialIV, encryptedCredential);
// create attestation for identity response that contains the credential
- SymmetricAttestation attestation =
- new SimpleStructBuilder<>(SymmetricAttestation.class)
- .set("credential", credentialBytes)
- .set("algorithm",
- new SimpleStructBuilder<>(SymmetricKeyParams.class)
- .set("algorithmId", SymmetricKeyParams.ALGORITHM_AES)
- .set("encryptionScheme",
- SymmetricKeyParams.SCHEME_CBC_PKCS5PADDING)
- .set("signatureScheme", 0).build()).build();
-
- return attestation;
+
+ return new SimpleStructBuilder<>(SymmetricAttestation.class)
+ .set("credential", credentialBytes)
+ .set("algorithm",
+ new SimpleStructBuilder<>(SymmetricKeyParams.class)
+ .set("algorithmId", SymmetricKeyParams.ALGORITHM_AES)
+ .set("encryptionScheme",
+ SymmetricKeyParams.SCHEME_CBC_PKCS5PADDING)
+ .set("signatureScheme", 0).build()).build();
} catch (BadPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException
| InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException
@@ -746,4 +740,32 @@ public static int daysBetween(final Date date1, final Date date2) {
return (int) ((date2.getTime() - date1.getTime())
/ (millisecondsInASecond * secondsInAnHour * hoursInADay));
}
+
+ /**
+ * Helper method that determines the public key algorithm associated with the supplied byte array.
+ *
+ * @param keyBytes byte array representation of the key
+ * @return {@link PublicKeyAlgorithm}
+ */
+ private static PublicKeyAlgorithm determineKeyType(byte[] keyBytes) {
+ // Loop over supported algorithms
+ for (PublicKeyAlgorithm publicKeyAlgorithm : PublicKeyAlgorithm.values()) {
+ if (publicKeyAlgorithm == PublicKeyAlgorithm.UNKNOWN) continue; // Skip UNKNOWN
+
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance(publicKeyAlgorithm.getAlgorithmName());
+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
+ PublicKey publicKey = keyFactory.generatePublic(keySpec);
+
+ // Check if the parsed key matches the expected type
+ if (publicKeyAlgorithm.getKeyClass().isInstance(publicKey)) {
+ return publicKeyAlgorithm;
+ }
+ } catch (Exception ignored) {
+ // Ignore and try next algorithm
+ }
+ }
+
+ return PublicKeyAlgorithm.UNKNOWN;
+ }
}
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java
index 8dcca210d..2ff41e57f 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java
@@ -51,7 +51,6 @@
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
-import java.util.Random;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
@@ -61,6 +60,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
+import java.util.Random;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -121,12 +121,43 @@ public class AttestationCertificateAuthorityTest {
private static final String AK_NAME_HEX = "00 0b 6e 8f 79 1c 7e 16 96 1b 11 71 65 9c e0 cd"
+ "ae 0d 4d aa c5 41 be 58 89 74 67 55 96 c2 5e 38"
+ "e2 94";
+ private final Random random = new Random();
// object in test
private AttestationCertificateAuthority aca;
private AccessAbstractProcessor abstractProcessor;
// test key pair
private KeyPair keyPair;
- private Random random = new Random();
+
+ /**
+ * Creates a self-signed X.509 public-key certificate.
+ *
+ * @param pair KeyPair to create the cert for
+ * @return self-signed X509Certificate
+ */
+ private static X509Certificate createSelfSignedCertificate(final KeyPair pair) {
+ Security.addProvider(new BouncyCastleProvider());
+ final int timeRange = 10000;
+ X509Certificate cert = null;
+ try {
+
+ X500Name issuerName = new X500Name("CN=TEST2, OU=TEST2, O=TEST2, C=TEST2");
+ X500Name subjectName = new X500Name("CN=TEST, OU=TEST, O=TEST, C=TEST");
+ BigInteger serialNumber = BigInteger.ONE;
+ Date notBefore = new Date(System.currentTimeMillis() - timeRange);
+ Date notAfter = new Date(System.currentTimeMillis() + timeRange);
+ X509v3CertificateBuilder builder =
+ new JcaX509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter,
+ subjectName, pair.getPublic());
+ ContentSigner signer =
+ new JcaContentSignerBuilder("SHA256WithRSA").setProvider("BC").build(
+ pair.getPrivate());
+ return new JcaX509CertificateConverter().setProvider("BC").getCertificate(
+ builder.build(signer));
+ } catch (Exception e) {
+ fail("Exception occurred while creating a cert", e);
+ }
+ return cert;
+ }
/**
* Registers bouncy castle as a security provider. Normally the JEE container will handle this,
@@ -169,7 +200,7 @@ public void testProcessIdentityClaimTpm2NullRequest() {
public void testGetPublicKey() {
// encoded byte array to be returned by public key
- byte[] encoded = new byte[] {0, 1, 0, 1, 0};
+ byte[] encoded = new byte[]{0, 1, 0, 1, 0};
// create mocks for testing
X509Certificate acaCertificate = mock(X509Certificate.class);
@@ -285,7 +316,7 @@ private void assertTrue(final boolean b) {
public void testGenerateAsymmetricContents() throws Exception {
// "encoded" identity proof (returned by struct converter)
- byte[] identityProofEncoded = new byte[] {0, 0, 1, 1};
+ byte[] identityProofEncoded = new byte[]{0, 0, 1, 1};
// generate a random session key to be used for encryption and decryption
byte[] sessionKey = new byte[ENCRYPTION_IV_LEN];
@@ -381,37 +412,6 @@ public void testGenerateAttestation() throws Exception {
verifyNoMoreInteractions(certificate, symmetricKey);
}
- /**
- * Creates a self-signed X.509 public-key certificate.
- *
- * @param pair KeyPair to create the cert for
- * @return self-signed X509Certificate
- */
- private static X509Certificate createSelfSignedCertificate(final KeyPair pair) {
- Security.addProvider(new BouncyCastleProvider());
- final int timeRange = 10000;
- X509Certificate cert = null;
- try {
-
- X500Name issuerName = new X500Name("CN=TEST2, OU=TEST2, O=TEST2, C=TEST2");
- X500Name subjectName = new X500Name("CN=TEST, OU=TEST, O=TEST, C=TEST");
- BigInteger serialNumber = BigInteger.ONE;
- Date notBefore = new Date(System.currentTimeMillis() - timeRange);
- Date notAfter = new Date(System.currentTimeMillis() + timeRange);
- X509v3CertificateBuilder builder =
- new JcaX509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter,
- subjectName, pair.getPublic());
- ContentSigner signer =
- new JcaContentSignerBuilder("SHA256WithRSA").setProvider("BC").build(
- pair.getPrivate());
- return new JcaX509CertificateConverter().setProvider("BC").getCertificate(
- builder.build(signer));
- } catch (Exception e) {
- fail("Exception occurred while creating a cert", e);
- }
- return cert;
- }
-
/**
* Tests {@link AttestationCertificateAuthority#
* AttestationCertificateAuthority(SupplyChainValidationService, PrivateKey,
@@ -488,7 +488,7 @@ public void testGenerateCredential() throws Exception {
}
/**
- * Tests {@link ProvisionUtils#assemblePublicKey(byte[])}.
+ * Tests {@link ProvisionUtils#assembleRSAPublicKey(byte[])}.
*/
@Test
public void testAssemblePublicKeyUsingByteArray() {
@@ -496,7 +496,7 @@ public void testAssemblePublicKeyUsingByteArray() {
final BigInteger modulus = ((RSAPublicKey) keyPair.getPublic()).getModulus();
// perform test
- RSAPublicKey publicKey = (RSAPublicKey) ProvisionUtils.assemblePublicKey(modulus.toByteArray());
+ RSAPublicKey publicKey = (RSAPublicKey) ProvisionUtils.assembleRSAPublicKey(modulus.toByteArray());
// assert that the exponent and the modulus are the same. the exponents should be the well
// known prime, 101
@@ -506,7 +506,7 @@ public void testAssemblePublicKeyUsingByteArray() {
}
/**
- * Tests {@link ProvisionUtils#assemblePublicKey(String)}.
+ * Tests {@link ProvisionUtils#assembleRSAPublicKey(String)}.
*/
@Test
public void testAssemblePublicKeyUsingHexEncodedString() {
@@ -518,7 +518,7 @@ public void testAssemblePublicKeyUsingHexEncodedString() {
((RSAPublicKey) keyPair.getPublic()).getModulus().toByteArray());
// perform test
- RSAPublicKey publicKey = (RSAPublicKey) ProvisionUtils.assemblePublicKey(modulusString);
+ RSAPublicKey publicKey = (RSAPublicKey) ProvisionUtils.assembleRSAPublicKey(modulusString);
// assert that the exponent and the modulus are the same. the exponents should be the well
// known prime, 101.
@@ -540,7 +540,7 @@ public void testParseEk() throws URISyntaxException, IOException {
byte[] ekFile = Files.readAllBytes(ekPath);
- RSAPublicKey ek = ProvisionUtils.parsePublicKey(ekFile);
+ RSAPublicKey ek = ProvisionUtils.parseRSAKeyFromPublicDataSegment(ekFile);
final int radix = 16;
assertTrue(ek.getPublicExponent().equals(new BigInteger("010001", radix)));
@@ -569,7 +569,7 @@ public void testParseAk() throws URISyntaxException, IOException {
byte[] akFile = Files.readAllBytes(akPath);
- RSAPublicKey ak = ProvisionUtils.parsePublicKey(akFile);
+ RSAPublicKey ak = ProvisionUtils.parseRSAKeyFromPublicDataSegment(akFile);
final int radix = 16;
assertTrue(ak.getPublicExponent().equals(new BigInteger("010001", radix)));
@@ -633,8 +633,8 @@ public void testMakeCredential() throws URISyntaxException, IOException {
byte[] ekPubFile = Files.readAllBytes(ekPubPath);
byte[] akPubFile = Files.readAllBytes(akPubPath);
- RSAPublicKey ekPub = ProvisionUtils.parsePublicKey(ekPubFile);
- RSAPublicKey akPub = ProvisionUtils.parsePublicKey(akPubFile);
+ RSAPublicKey ekPub = ProvisionUtils.parseRSAKeyFromPublicDataSegment(ekPubFile);
+ RSAPublicKey akPub = ProvisionUtils.parseRSAKeyFromPublicDataSegment(akPubFile);
// prepare the nonce and wrap it with keys
final byte[] nonce = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
diff --git a/HIRS_Structs/src/main/java/hirs/structs/converters/SimpleStructBuilder.java b/HIRS_Structs/src/main/java/hirs/structs/converters/SimpleStructBuilder.java
index 45a8d3175..b910dfa0f 100644
--- a/HIRS_Structs/src/main/java/hirs/structs/converters/SimpleStructBuilder.java
+++ b/HIRS_Structs/src/main/java/hirs/structs/converters/SimpleStructBuilder.java
@@ -13,7 +13,7 @@
*
* @param the type of Struct to build
*/
-public class SimpleStructBuilder implements StructBuilder {
+public class SimpleStructBuilder implements StructBuilder {
private final Class clazz;
private T struct;
From 331328bd76a2c15548e5f875df7a7575511bb527 Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Fri, 20 Feb 2026 13:35:38 -0500
Subject: [PATCH 02/25] v3.1_issue_1090: Added a new property that keeps track
of the algorithm used throughout the application (prop has been added to the
app.properties for both win and linux machines), deleted a repo that wasnt
being used anywhere, changed the name of the rest controller and service
class, re-wrote the workflow from rest controller to backend since it was
setup incorrectly. Provisioning is sort-of crypto-agile. It can parse the rsa
key without an issue, now need to work on doing the same for the ecc key.
---
.../AttestationCertificateAuthority.java | 151 ------------------
...ionCertificateAuthorityRestController.java | 72 +++++++++
...ttestationCertificateAuthorityService.java | 60 +++++++
...CertificateAuthorityServiceInterface.java} | 4 +-
...estfulAttestationCertificateAuthority.java | 137 ----------------
.../SupplyChainValidationRepository.java | 28 ----
...upplyChainValidationSummaryRepository.java | 3 +-
.../persist/enums/PublicKeyAlgorithm.java | 19 ++-
.../CertificateProcessingException.java | 4 +-
.../IdentityProcessingException.java | 4 +-
.../exceptions/UnexpectedServerException.java | 4 +-
.../CertificateRequestProcessor.java | 32 +++-
.../provision/IdentityClaimProcessor.java | 4 +
.../provision/helper/ProvisionUtils.java | 44 +----
.../service/SupplyChainValidationService.java | 7 +-
.../AttestationCertificateAuthorityTest.java | 17 +-
.../src/main/resources/application.properties | 1 +
.../main/resources/application.win.properties | 1 +
package/linux/aca/aca_setup.sh | 3 +
19 files changed, 214 insertions(+), 381 deletions(-)
delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java
create mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
create mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/{RestfulInterface.java => AttestationCertificateAuthorityServiceInterface.java} (81%)
delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java
delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationRepository.java
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java
deleted file mode 100644
index c34dbeb36..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package hirs.attestationca.persist;
-
-import hirs.attestationca.persist.entity.manager.CertificateRepository;
-import hirs.attestationca.persist.entity.manager.ComponentInfoRepository;
-import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
-import hirs.attestationca.persist.entity.manager.DeviceRepository;
-import hirs.attestationca.persist.entity.manager.IssuedCertificateRepository;
-import hirs.attestationca.persist.entity.manager.PolicyRepository;
-import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository;
-import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository;
-import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository;
-import hirs.attestationca.persist.provision.CertificateRequestProcessor;
-import hirs.attestationca.persist.provision.IdentityClaimProcessor;
-import hirs.attestationca.persist.service.SupplyChainValidationService;
-import hirs.structs.converters.StructConverter;
-import lombok.extern.log4j.Log4j2;
-
-import java.security.GeneralSecurityException;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
-/**
- * Provides base implementation of common tasks of an ACA that are required for attestation of an
- * Identity Request.
- */
-@Log4j2
-public abstract class AttestationCertificateAuthority implements RestfulInterface {
-
- /**
- * Container wired ACA private key.
- */
- private final PrivateKey privateKey;
-
- /**
- * Container wired ACA certificate.
- */
- private final X509Certificate acaCertificate;
-
- /**
- * Container wired {@link StructConverter} to be used in
- * serialization / deserialization of TPM data structures.
- */
- private final StructConverter structConverter;
-
- /**
- * A handle to the service used to validate the supply chain.
- */
- private final SupplyChainValidationService supplyChainValidationService;
- private final ComponentResultRepository componentResultRepository;
- private final CertificateRepository certificateRepository;
- private final IssuedCertificateRepository issuedCertificateRepository;
- private final ReferenceManifestRepository referenceManifestRepository;
- private final DeviceRepository deviceRepository;
- // private final DBManager tpm2ProvisionerStateDBManager;
- private final ReferenceDigestValueRepository referenceDigestValueRepository;
- private final PolicyRepository policyRepository;
- private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
- private final ComponentInfoRepository componentInfoRepository;
- private final CertificateRequestProcessor certificateRequestHandler;
- private final IdentityClaimProcessor identityClaimHandler;
- /**
- * Container wired application configuration property identifying the number of days that
- * certificates issued by this ACA are valid for.
- */
- private Integer validDays = 1;
-
- /**
- * Constructor.
- *
- * @param supplyChainValidationService the supply chain service
- * @param privateKey the ACA private key
- * @param acaCertificate the ACA certificate
- * @param structConverter the struct converter
- * @param componentResultRepository the component result manager
- * @param componentInfoRepository the component info manager
- * @param certificateRepository the certificate manager
- * @param issuedCertificateRepository the issued certificate repository
- * @param referenceManifestRepository the Reference Manifest manager
- * @param validDays the number of days issued certs are valid
- * @param deviceRepository the device manager
- * @param referenceDigestValueRepository the reference event manager
- * @param policyRepository policy setting repository
- * @param tpm2ProvisionerStateRepository tpm2 provisioner state repository
- */
- public AttestationCertificateAuthority(
- final SupplyChainValidationService supplyChainValidationService,
- final PrivateKey privateKey, final X509Certificate acaCertificate,
- final StructConverter structConverter,
- final ComponentResultRepository componentResultRepository,
- final ComponentInfoRepository componentInfoRepository,
- final CertificateRepository certificateRepository,
- final IssuedCertificateRepository issuedCertificateRepository,
- final ReferenceManifestRepository referenceManifestRepository,
- final int validDays,
- final DeviceRepository deviceRepository,
- final ReferenceDigestValueRepository referenceDigestValueRepository,
- final PolicyRepository policyRepository,
- final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository) {
- this.supplyChainValidationService = supplyChainValidationService;
- this.privateKey = privateKey;
- this.acaCertificate = acaCertificate;
- this.structConverter = structConverter;
- this.componentResultRepository = componentResultRepository;
- this.componentInfoRepository = componentInfoRepository;
- this.certificateRepository = certificateRepository;
- this.issuedCertificateRepository = issuedCertificateRepository;
- this.referenceManifestRepository = referenceManifestRepository;
- this.validDays = validDays;
- this.deviceRepository = deviceRepository;
- this.referenceDigestValueRepository = referenceDigestValueRepository;
- this.policyRepository = policyRepository;
- this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
-
- this.certificateRequestHandler = new CertificateRequestProcessor(supplyChainValidationService,
- certificateRepository, deviceRepository,
- privateKey, acaCertificate, validDays, tpm2ProvisionerStateRepository, policyRepository);
- this.identityClaimHandler = new IdentityClaimProcessor(supplyChainValidationService,
- certificateRepository, componentResultRepository, componentInfoRepository,
- referenceManifestRepository, referenceDigestValueRepository,
- deviceRepository, tpm2ProvisionerStateRepository, policyRepository);
- }
-
- /**
- * Processes the provided identity claim.
- *
- * @param identityClaim a byte array representation of the identity claim
- * @return processed identity claim response
- */
- public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
- return this.identityClaimHandler.processIdentityClaimTpm2(identityClaim);
- }
-
- /**
- * Processes the provided certificate request.
- *
- * @param certificateRequest a byte array representation of the certificate request
- * @return processed certificate request response
- */
- public byte[] processCertificateRequest(final byte[] certificateRequest) throws GeneralSecurityException {
- return this.certificateRequestHandler.processCertificateRequest(certificateRequest);
- }
-
- /**
- * Retrieves the encoded public key.
- *
- * @return encoded public key
- */
- public byte[] getPublicKey() {
- return acaCertificate.getPublicKey().getEncoded();
- }
-}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
new file mode 100644
index 000000000..b97608fa8
--- /dev/null
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
@@ -0,0 +1,72 @@
+package hirs.attestationca.persist;
+
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * REST Controller for the ACA that communicates with the Provisioner during the provisioning process.
+ */
+@Log4j2
+@RestController
+@RequestMapping("/HIRS_AttestationCA")
+public class AttestationCertificateAuthorityRestController {
+ private final AttestationCertificateAuthorityService attestationCertificateAuthorityService;
+
+ /**
+ * Constructor.
+ *
+ * @param attestationCertificateAuthorityService Attestation Certificate Authority service
+ */
+ @Autowired
+ public AttestationCertificateAuthorityRestController(
+ final AttestationCertificateAuthorityService attestationCertificateAuthorityService) {
+ this.attestationCertificateAuthorityService = attestationCertificateAuthorityService;
+ }
+
+ /**
+ * Processes a given IdentityClaim and generates a response containing an encrypted nonce to be returned by the
+ * client in a future handshake request.
+ *
+ * @param identityClaim The request object from the provisioner.
+ * @return The response to the provisioner.
+ */
+ @ResponseBody
+ @PostMapping(value = "/identity-claim-tpm2/process", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
+ public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim) {
+ return this.attestationCertificateAuthorityService.processIdentityClaimTpm2(identityClaim);
+ }
+
+ /**
+ * Processes a given Certificate Request and generates a response containing the signed, public certificate for
+ * the client's desired attestation key, if the correct nonce is supplied.
+ *
+ * @param certificateRequest request containing nonce from earlier identity
+ * claim handshake
+ * @return The response to the client provisioner.
+ */
+ @ResponseBody
+ @PostMapping(value = "/request-certificate-tpm2", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
+ public byte[] processCertificateRequest(@RequestBody final byte[] certificateRequest) throws GeneralSecurityException {
+ return this.attestationCertificateAuthorityService.processCertificateRequest(certificateRequest);
+ }
+
+ /**
+ * Processes a GET request to retrieve the byte array representation of the public key.
+ *
+ * @return byte array representation of the public key
+ */
+ @ResponseBody
+ @GetMapping("/public-key")
+ public byte[] getLeafACACertPublicKey() {
+ return this.attestationCertificateAuthorityService.getLeafACACertPublicKey();
+ }
+}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java
new file mode 100644
index 000000000..eaa7fbe4c
--- /dev/null
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java
@@ -0,0 +1,60 @@
+package hirs.attestationca.persist;
+
+import hirs.attestationca.persist.provision.CertificateRequestProcessor;
+import hirs.attestationca.persist.provision.IdentityClaimProcessor;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.stereotype.Service;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * Service layer class responsible for handling both certificate and identity claim requests made by the provisioner.
+ */
+@Service
+@Log4j2
+public class AttestationCertificateAuthorityService implements AttestationCertificateAuthorityServiceInterface {
+ private final CertificateRequestProcessor certificateRequestProcessor;
+ private final IdentityClaimProcessor identityClaimProcessor;
+
+ /**
+ * Constructor.
+ *
+ * @param certificateRequestProcessor certificate request processor service
+ * @param identityClaimProcessor identity claim processor service
+ */
+ public AttestationCertificateAuthorityService(
+ final CertificateRequestProcessor certificateRequestProcessor,
+ final IdentityClaimProcessor identityClaimProcessor) {
+ this.certificateRequestProcessor = certificateRequestProcessor;
+ this.identityClaimProcessor = identityClaimProcessor;
+ }
+
+ /**
+ * Processes the provided identity claim.
+ *
+ * @param identityClaim a byte array representation of the identity claim
+ * @return processed identity claim response
+ */
+ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
+ return this.identityClaimProcessor.processIdentityClaimTpm2(identityClaim);
+ }
+
+ /**
+ * Processes the provided certificate request.
+ *
+ * @param certificateRequest a byte array representation of the certificate request
+ * @return processed certificate request response
+ */
+ public byte[] processCertificateRequest(final byte[] certificateRequest) throws GeneralSecurityException {
+ return this.certificateRequestProcessor.processCertificateRequest(certificateRequest);
+ }
+
+ /**
+ * Retrieves the encoded public key.
+ *
+ * @return encoded public key
+ */
+ public byte[] getLeafACACertPublicKey() {
+ return this.certificateRequestProcessor.getLeafACACertificatePublicKey();
+ }
+}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulInterface.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceInterface.java
similarity index 81%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulInterface.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceInterface.java
index 0c8bf7766..7e4520d4a 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulInterface.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceInterface.java
@@ -3,9 +3,9 @@
import java.security.GeneralSecurityException;
/**
- * Defines the responsibilities of the Attestation Certificate Authority.
+ * Interface that defines the responsibilities of the Attestation Certificate Authority service.
*/
-public interface RestfulInterface {
+public interface AttestationCertificateAuthorityServiceInterface {
/**
* Processes the provided identity claim.
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java
deleted file mode 100644
index 5bafc5b92..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package hirs.attestationca.persist;
-
-import hirs.attestationca.persist.entity.manager.CertificateRepository;
-import hirs.attestationca.persist.entity.manager.ComponentInfoRepository;
-import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
-import hirs.attestationca.persist.entity.manager.DeviceRepository;
-import hirs.attestationca.persist.entity.manager.IssuedCertificateRepository;
-import hirs.attestationca.persist.entity.manager.PolicyRepository;
-import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository;
-import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository;
-import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository;
-import hirs.attestationca.persist.service.SupplyChainValidationService;
-import hirs.structs.converters.StructConverter;
-import lombok.extern.log4j.Log4j2;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.PropertySource;
-import org.springframework.context.annotation.PropertySources;
-import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.security.GeneralSecurityException;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
-/**
- * Restful implementation of the {@link AttestationCertificateAuthority}.
- * Exposes the ACA methods as REST endpoints.
- */
-@PropertySources({
- // detects if file exists, if not, ignore errors
- @PropertySource(value = "file:/etc/hirs/aca/application.properties",
- ignoreResourceNotFound = true),
- @PropertySource(value = "file:C:/ProgramData/hirs/aca/application.win.properties",
- ignoreResourceNotFound = true)
-})
-@Log4j2
-@RestController
-@RequestMapping("/HIRS_AttestationCA")
-public class RestfulAttestationCertificateAuthority extends AttestationCertificateAuthority {
- /**
- * Constructor.
- *
- * @param supplyChainValidationService scp service
- * @param privateKey the ACA private key
- * @param acaCertificate the ACA certificate
- * @param structConverter the struct converter
- * @param componentResultRepository the component result repository
- * @param componentInfoRepository the component info repository
- * @param certificateRepository the certificate manager
- * @param issuedCertificateRepository the issued certificate repository
- * @param referenceManifestRepository the referenceManifestManager
- * @param validDays the number of days issued certs are valid
- * @param deviceRepository the device manager
- * @param referenceDigestValueRepository the reference event repository
- * @param policyRepository the provisioning policy entity
- * @param tpm2ProvisionerStateRepository the provisioner state
- */
- @Autowired
- public RestfulAttestationCertificateAuthority(
- final SupplyChainValidationService supplyChainValidationService,
- final PrivateKey privateKey,
- @Qualifier("leafACACert") final X509Certificate acaCertificate,
- final StructConverter structConverter,
- final ComponentResultRepository componentResultRepository,
- final ComponentInfoRepository componentInfoRepository,
- final CertificateRepository certificateRepository,
- final IssuedCertificateRepository issuedCertificateRepository,
- final ReferenceManifestRepository referenceManifestRepository,
- final DeviceRepository deviceRepository,
- final ReferenceDigestValueRepository referenceDigestValueRepository,
- @Value("${aca.certificates.validity}") final int validDays,
- final PolicyRepository policyRepository,
- final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository) {
- super(supplyChainValidationService, privateKey, acaCertificate, structConverter,
- componentResultRepository, componentInfoRepository,
- certificateRepository, issuedCertificateRepository,
- referenceManifestRepository,
- validDays, deviceRepository,
- referenceDigestValueRepository, policyRepository, tpm2ProvisionerStateRepository);
- }
-
- /**
- * Listener for identity requests from TPM 2.0 provisioning.
- *
- * Processes a given IdentityClaim and generates a response
- * containing an encrypted nonce to be returned by the client in
- * a future handshake request.
- *
- * @param identityClaim The request object from the provisioner.
- * @return The response to the provisioner.
- */
- @Override
- @ResponseBody
- @PostMapping(value = "/identity-claim-tpm2/process",
- consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
- public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim) {
- return super.processIdentityClaimTpm2(identityClaim);
- }
-
- /**
- * Processes a given CertificateRequest
- * and generates a response containing the signed, public certificate for
- * the client's desired attestation key, if the correct nonce is supplied.
- *
- * @param certificateRequest request containing nonce from earlier identity
- * claim handshake
- * @return The response to the client provisioner.
- */
- @Override
- @ResponseBody
- @PostMapping(value = "/request-certificate-tpm2",
- consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
- public byte[] processCertificateRequest(@RequestBody final byte[] certificateRequest) throws GeneralSecurityException {
- return super.processCertificateRequest(certificateRequest);
- }
-
- /**
- * (non-javadoc)
- *
- * Wrap the {@link AttestationCertificateAuthority#getPublicKey()} with a Spring
- * {@link org.springframework.web.bind.annotation.RequestMapping} such that Spring can serialize
- * the certificate to be returned to an HTTP Request.
- */
- @Override
- @ResponseBody
- @GetMapping("/public-key")
- public byte[] getPublicKey() {
- return super.getPublicKey();
- }
-}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationRepository.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationRepository.java
deleted file mode 100644
index b7571b423..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationRepository.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package hirs.attestationca.persist.entity.manager;
-
-import hirs.attestationca.persist.entity.userdefined.SupplyChainValidation;
-import hirs.attestationca.persist.enums.AppraisalStatus;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
-import java.util.UUID;
-
-@Repository
-public interface SupplyChainValidationRepository extends JpaRepository {
- /**
- * Query that retrieves a list of supply chain validation using the provided validate type.
- *
- * @param validationType string representation of the validate type
- * @return a list of supply chain validation
- */
- List findByValidationType(SupplyChainValidation.ValidationType validationType);
-
- /**
- * Query that retrieves a list of supply chain validation using the provided validation result.
- *
- * @param validationResult string representation of the validation result
- * @return a list of supply chain validation
- */
- List findByValidationResult(AppraisalStatus.Status validationResult);
-}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationSummaryRepository.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationSummaryRepository.java
index bf4964b3e..a3c68c020 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationSummaryRepository.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationSummaryRepository.java
@@ -11,8 +11,7 @@
import java.util.UUID;
@Repository
-public interface SupplyChainValidationSummaryRepository
- extends JpaRepository {
+public interface SupplyChainValidationSummaryRepository extends JpaRepository {
/**
* Query that retrieves a supply chain validation summary using the provided device.
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
index 1842b61b7..2f7b17389 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
@@ -14,7 +14,7 @@
* This enum currently includes:
*
* - {@link #RSA} – RSA public-key algorithm.
- * - {@link #EC} – Elliptic Curve (EC) public-key algorithm, commonly referred to as ECC.
+ * - {@link #ECC} – Elliptic Curve (EC) public-key algorithm, commonly referred to as ECC.
*
*
* Each enum constant also holds its corresponding JCA (Java Cryptography Architecture)
@@ -25,10 +25,25 @@
@ToString
public enum PublicKeyAlgorithm {
RSA("RSA", RSAPublicKey.class),
- EC("EC", ECPublicKey.class),
+ ECC("ECC", ECPublicKey.class),
UNKNOWN("", null);
private final String algorithmName;
private final Class extends PublicKey> keyClass;
+
+ /**
+ * Converts the provided string public key algorithm into an ENUM.
+ *
+ * @param algorithmAsString public key algorithm name as a string
+ * @return ENUM representation of the public key algorithm
+ */
+ public static PublicKeyAlgorithm fromString(final String algorithmAsString) {
+ for (PublicKeyAlgorithm algorithmEnum : PublicKeyAlgorithm.values()) {
+ if (algorithmEnum.getAlgorithmName().equalsIgnoreCase(algorithmAsString)) {
+ return algorithmEnum;
+ }
+ }
+ return UNKNOWN; // Return UNKNOWN if no match is found
+ }
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/CertificateProcessingException.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/CertificateProcessingException.java
index cab0c0911..6389e4be3 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/CertificateProcessingException.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/CertificateProcessingException.java
@@ -1,7 +1,9 @@
package hirs.attestationca.persist.exceptions;
+import hirs.attestationca.persist.AttestationCertificateAuthorityService;
+
/**
- * Generic exception thrown while a {@link hirs.attestationca.persist.AttestationCertificateAuthority}
+ * Generic exception thrown while a {@link AttestationCertificateAuthorityService}
* is processing a newly created Attestation Certificate for a validated identity.
*/
public class CertificateProcessingException extends RuntimeException {
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/IdentityProcessingException.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/IdentityProcessingException.java
index 165784739..ebca3311a 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/IdentityProcessingException.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/IdentityProcessingException.java
@@ -1,7 +1,9 @@
package hirs.attestationca.persist.exceptions;
+import hirs.attestationca.persist.AttestationCertificateAuthorityService;
+
/**
- * Generic exception thrown while a {@link hirs.attestationca.persist.AttestationCertificateAuthority}
+ * Generic exception thrown while a {@link AttestationCertificateAuthorityService}
* is processing a newly submitted Identity.
*/
public class IdentityProcessingException extends RuntimeException {
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/UnexpectedServerException.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/UnexpectedServerException.java
index ed3da171d..df4eb2668 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/UnexpectedServerException.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/UnexpectedServerException.java
@@ -1,7 +1,9 @@
package hirs.attestationca.persist.exceptions;
+import hirs.attestationca.persist.AttestationCertificateAuthorityService;
+
/**
- * Generic exception thrown when a {@link hirs.attestationca.persist.AttestationCertificateAuthority}
+ * Generic exception thrown when a {@link AttestationCertificateAuthorityService}
* encounters an unexpected condition that can't be handled.
*/
public class UnexpectedServerException extends RuntimeException {
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
index f51c53ae5..309a299d3 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
@@ -16,11 +16,16 @@
import hirs.attestationca.persist.entity.userdefined.info.TPMInfo;
import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
import hirs.attestationca.persist.enums.AppraisalStatus;
+import hirs.attestationca.persist.enums.PublicKeyAlgorithm;
import hirs.attestationca.persist.exceptions.CertificateProcessingException;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
import hirs.attestationca.persist.service.SupplyChainValidationService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ArrayUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
@@ -29,6 +34,7 @@
import java.security.cert.X509Certificate;
import java.util.List;
+@Service
@Log4j2
public class CertificateRequestProcessor extends AbstractProcessor {
@@ -37,6 +43,7 @@ public class CertificateRequestProcessor extends AbstractProcessor {
private final DeviceRepository deviceRepository;
private final X509Certificate acaCertificate;
private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
+ private final PublicKeyAlgorithm publicKeyAlgorithm;
/**
* Constructor.
@@ -50,12 +57,14 @@ public class CertificateRequestProcessor extends AbstractProcessor {
* @param tpm2ProvisionerStateRepository db connector for provisioner state.
* @param policyRepository db connector for policies.
*/
+ @Autowired
public CertificateRequestProcessor(final SupplyChainValidationService supplyChainValidationService,
final CertificateRepository certificateRepository,
final DeviceRepository deviceRepository,
final PrivateKey privateKey,
- final X509Certificate acaCertificate,
- final int validDays,
+ @Qualifier("leafACACert") final X509Certificate acaCertificate,
+ @Value("${aca.current.public.key.algorithm}") final String publicKeyAlgorithmStr,
+ @Value("${aca.certificates.validity}") final int validDays,
final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
final PolicyRepository policyRepository) {
super(privateKey, validDays);
@@ -64,9 +73,19 @@ public CertificateRequestProcessor(final SupplyChainValidationService supplyChai
this.deviceRepository = deviceRepository;
this.acaCertificate = acaCertificate;
this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
+ this.publicKeyAlgorithm = PublicKeyAlgorithm.fromString(publicKeyAlgorithmStr);
setPolicyRepository(policyRepository);
}
+ /**
+ * Retrieves the byte array representation of the ACA certificate public key.
+ *
+ * @return byte array representation of the ACA certificate public key
+ */
+ public byte[] getLeafACACertificatePublicKey() {
+ return acaCertificate.getPublicKey().getEncoded();
+ }
+
/**
* Basic implementation of the ACA processCertificateRequest method.
* Parses the nonce, validates its correctness, generates the signed,
@@ -114,10 +133,12 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) throws
ProvisionerTpm2.IdentityClaim claim = ProvisionUtils.parseIdentityClaim(identityClaim);
// Get endorsement public key
- PublicKey ekPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(claim.getEkPublicArea().toByteArray());
+ PublicKey ekPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(publicKeyAlgorithm,
+ claim.getEkPublicArea().toByteArray());
// Get attestation public key
- PublicKey akPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(claim.getAkPublicArea().toByteArray());
+ PublicKey akPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(publicKeyAlgorithm,
+ claim.getAkPublicArea().toByteArray());
// Get Endorsement Credential if it exists or was uploaded
EndorsementCredential endorsementCredential = parseEcFromIdentityClaim(claim, ekPub, certificateRepository);
@@ -129,7 +150,8 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) throws
// Get LDevID public key if it exists
PublicKey ldevidPub = null;
if (claim.hasLdevidPublicArea()) {
- ldevidPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(claim.getLdevidPublicArea().toByteArray());
+ ldevidPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(publicKeyAlgorithm,
+ claim.getLdevidPublicArea().toByteArray());
}
// Get device name and device
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
index 8252ce2d7..0363057ac 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
@@ -48,6 +48,8 @@
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.ArrayUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
import java.io.IOException;
import java.net.InetAddress;
@@ -69,6 +71,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+@Service
@Log4j2
public class IdentityClaimProcessor extends AbstractProcessor {
/**
@@ -102,6 +105,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
* @param tpm2ProvisionerStateRepository tpm2 provisioner state repository
* @param policyRepository policy repository
*/
+ @Autowired
public IdentityClaimProcessor(
final SupplyChainValidationService supplyChainValidationService,
final CertificateRepository certificateRepository,
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index 4ff13866b..7cc8081d4 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -48,7 +48,6 @@
import java.security.spec.InvalidKeySpecException;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.RSAPublicKeySpec;
-import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
@Log4j2
@@ -168,16 +167,16 @@ public static String getPemEncodedCertificate(final X509Certificate certificate)
* Parses a public key from a byte array and returns it as a generic PublicKey.
* Supports RSA and EC (Elliptic Curve) keys.
*
- * @param keyBytes the DER-encoded public key bytes
+ * @param publicKeyAlgorithm public key algorithm
+ * @param keyBytes the DER-encoded public key bytes
* @return the parsed PublicKey instance
* @throws GeneralSecurityException if the key cannot be parsed
*/
- public static PublicKey parsePublicKeyFromPublicDataSegment(byte[] keyBytes) throws GeneralSecurityException {
- PublicKeyAlgorithm publicKeyAlgorithm = determineKeyType(keyBytes);
-
+ public static PublicKey parsePublicKeyFromPublicDataSegment(final PublicKeyAlgorithm publicKeyAlgorithm,
+ byte[] keyBytes) throws GeneralSecurityException {
return switch (publicKeyAlgorithm) {
case RSA -> parseRSAKeyFromPublicDataSegment(keyBytes);
- case EC -> parseECKeyFromPublicDataSegment(keyBytes);
+ case ECC -> parseECCKeyFromPublicDataSegment(keyBytes);
default -> throw new GeneralSecurityException("Unsupported or invalid public key");
};
}
@@ -247,7 +246,7 @@ public static PublicKey assembleRSAPublicKey(final BigInteger modulus) {
* @param publicArea the public area segment to parse
* @return the ECC public key of the supplied public data
*/
- public static ECPublicKey parseECKeyFromPublicDataSegment(final byte[] publicArea) {
+ public static ECPublicKey parseECCKeyFromPublicDataSegment(final byte[] publicArea) {
return null;
}
@@ -318,7 +317,8 @@ public static byte[] decryptSymmetricBlob(final byte[] symmetricBlob, final byte
} catch (IllegalBlockSizeException | InvalidKeyException | NoSuchAlgorithmException
| BadPaddingException | NoSuchPaddingException
| InvalidAlgorithmParameterException exception) {
- log.error("Encountered error while decrypting symmetric blob of an identity request: {}", exception.getMessage(), exception);
+ log.error("Encountered error while decrypting symmetric blob of an identity request: {}",
+ exception.getMessage(), exception);
}
return new byte[0];
@@ -740,32 +740,4 @@ public static int daysBetween(final Date date1, final Date date2) {
return (int) ((date2.getTime() - date1.getTime())
/ (millisecondsInASecond * secondsInAnHour * hoursInADay));
}
-
- /**
- * Helper method that determines the public key algorithm associated with the supplied byte array.
- *
- * @param keyBytes byte array representation of the key
- * @return {@link PublicKeyAlgorithm}
- */
- private static PublicKeyAlgorithm determineKeyType(byte[] keyBytes) {
- // Loop over supported algorithms
- for (PublicKeyAlgorithm publicKeyAlgorithm : PublicKeyAlgorithm.values()) {
- if (publicKeyAlgorithm == PublicKeyAlgorithm.UNKNOWN) continue; // Skip UNKNOWN
-
- try {
- KeyFactory keyFactory = KeyFactory.getInstance(publicKeyAlgorithm.getAlgorithmName());
- X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
- PublicKey publicKey = keyFactory.generatePublic(keySpec);
-
- // Check if the parsed key matches the expected type
- if (publicKeyAlgorithm.getKeyClass().isInstance(publicKey)) {
- return publicKeyAlgorithm;
- }
- } catch (Exception ignored) {
- // Ignore and try next algorithm
- }
- }
-
- return PublicKeyAlgorithm.UNKNOWN;
- }
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java
index c6ef4c6d6..943461db3 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java
@@ -9,7 +9,6 @@
import hirs.attestationca.persist.entity.manager.PolicyRepository;
import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository;
import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository;
-import hirs.attestationca.persist.entity.manager.SupplyChainValidationRepository;
import hirs.attestationca.persist.entity.manager.SupplyChainValidationSummaryRepository;
import hirs.attestationca.persist.entity.userdefined.Device;
import hirs.attestationca.persist.entity.userdefined.PolicySettings;
@@ -45,8 +44,8 @@
import static hirs.attestationca.persist.enums.AppraisalStatus.Status.FAIL;
import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS;
-@Log4j2
@Service
+@Log4j2
public class SupplyChainValidationService {
private final CACredentialRepository caCredentialRepository;
@@ -56,7 +55,6 @@ public class SupplyChainValidationService {
private final ComponentResultRepository componentResultRepository;
private final ComponentAttributeRepository componentAttributeRepository;
private final CertificateRepository certificateRepository;
- private final SupplyChainValidationRepository supplyChainValidationRepository;
private final SupplyChainValidationSummaryRepository supplyChainValidationSummaryRepository;
private UUID provisionSessionId;
@@ -69,7 +67,6 @@ public class SupplyChainValidationService {
* @param componentResultRepository the comp result manager
* @param componentAttributeRepository component attribute repository
* @param referenceManifestRepository the RIM manager
- * @param supplyChainValidationRepository the scv manager
* @param supplyChainValidationSummaryRepository the summary manager
* @param referenceDigestValueRepository the even manager
*/
@@ -81,7 +78,6 @@ public SupplyChainValidationService(
final ComponentResultRepository componentResultRepository,
final ComponentAttributeRepository componentAttributeRepository,
final ReferenceManifestRepository referenceManifestRepository,
- final SupplyChainValidationRepository supplyChainValidationRepository,
final SupplyChainValidationSummaryRepository supplyChainValidationSummaryRepository,
final ReferenceDigestValueRepository referenceDigestValueRepository) {
this.caCredentialRepository = caCredentialRepository;
@@ -90,7 +86,6 @@ public SupplyChainValidationService(
this.componentResultRepository = componentResultRepository;
this.componentAttributeRepository = componentAttributeRepository;
this.referenceManifestRepository = referenceManifestRepository;
- this.supplyChainValidationRepository = supplyChainValidationRepository;
this.supplyChainValidationSummaryRepository = supplyChainValidationSummaryRepository;
this.referenceDigestValueRepository = referenceDigestValueRepository;
}
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java
index 2ff41e57f..c9721002c 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java
@@ -73,7 +73,7 @@
import static org.mockito.Mockito.when;
/**
- * Test suite for {@link AttestationCertificateAuthority}.
+ * Test suite for {@link AttestationCertificateAuthorityService}.
*/
@TestInstance(TestInstance.Lifecycle.PER_CLASS) // needed to use non-static BeforeAll
public class AttestationCertificateAuthorityTest {
@@ -123,7 +123,7 @@ public class AttestationCertificateAuthorityTest {
+ "e2 94";
private final Random random = new Random();
// object in test
- private AttestationCertificateAuthority aca;
+ private AttestationCertificateAuthorityService aca;
private AccessAbstractProcessor abstractProcessor;
// test key pair
private KeyPair keyPair;
@@ -174,9 +174,8 @@ public void setupTests() throws Exception {
keyPair = keyPairGenerator.generateKeyPair();
//BeforeTest
- aca = new AttestationCertificateAuthority(null, keyPair.getPrivate(),
- null, null, null, null, null, null, null, 1,
- null, null, null, null) {
+ aca = new AttestationCertificateAuthorityService(null,
+ null) {
};
abstractProcessor = new AccessAbstractProcessor(keyPair.getPrivate(), 1);
@@ -184,7 +183,7 @@ public void setupTests() throws Exception {
}
/**
- * Tests {@link AttestationCertificateAuthority#processIdentityClaimTpm2(byte[])}
+ * Tests {@link AttestationCertificateAuthorityService#processIdentityClaimTpm2(byte[])}
* where the byte array is null. Expects an illegal argument exception to be thrown.
*/
@Test
@@ -194,7 +193,7 @@ public void testProcessIdentityClaimTpm2NullRequest() {
}
/**
- * Tests {@link AttestationCertificateAuthority#getPublicKey()}.
+ * Tests {@link AttestationCertificateAuthorityService#getLeafACACertPublicKey()}.
*/
@Test
public void testGetPublicKey() {
@@ -216,7 +215,7 @@ public void testGetPublicKey() {
when(publicKey.getEncoded()).thenReturn(encoded);
// assert what the ACA returns is as expected
- assertArrayEquals(encoded, aca.getPublicKey());
+ assertArrayEquals(encoded, aca.getLeafACACertPublicKey());
// verify mock interactions
verify(acaCertificate).getPublicKey();
@@ -413,7 +412,7 @@ public void testGenerateAttestation() throws Exception {
}
/**
- * Tests {@link AttestationCertificateAuthority#
+ * Tests {@link AttestationCertificateAuthorityService#
* AttestationCertificateAuthority(SupplyChainValidationService, PrivateKey,
* X509Certificate, StructConverter, CertificateManager, DeviceRegister, int,
* DeviceManager, DBManager)}.
diff --git a/HIRS_AttestationCAPortal/src/main/resources/application.properties b/HIRS_AttestationCAPortal/src/main/resources/application.properties
index 0a5040c45..f75e7b107 100644
--- a/HIRS_AttestationCAPortal/src/main/resources/application.properties
+++ b/HIRS_AttestationCAPortal/src/main/resources/application.properties
@@ -33,6 +33,7 @@ aca.certificates.leaf-three-key-alias=HIRS_leaf_ca3_rsa_3k_sha384
aca.certificates.intermediate-key-alias=HIRS_intermediate_ca_rsa_3k_sha384
aca.certificates.root-key-alias=HIRS_root_ca_rsa_3k_sha384
aca.certificates.validity=3652
+aca.current.public.key.algorithm=rsa
# Compression settings
server.compression.enabled=true
# Compression content types
diff --git a/HIRS_AttestationCAPortal/src/main/resources/application.win.properties b/HIRS_AttestationCAPortal/src/main/resources/application.win.properties
index 946fb2d2f..7d39de846 100644
--- a/HIRS_AttestationCAPortal/src/main/resources/application.win.properties
+++ b/HIRS_AttestationCAPortal/src/main/resources/application.win.properties
@@ -39,6 +39,7 @@ aca.certificates.leaf-three-key-alias=HIRS_leaf_ca3_rsa_3k_sha384
aca.certificates.intermediate-key-alias=HIRS_intermediate_ca_rsa_3k_sha384
aca.certificates.root-key-alias=HIRS_root_ca_rsa_3k_sha384
aca.certificates.validity=3652
+aca.current.public.key.algorithm=rsa
# Compression settings
server.compression.enabled=true
# Compression content types
diff --git a/package/linux/aca/aca_setup.sh b/package/linux/aca/aca_setup.sh
index cb87799ad..399035847 100755
--- a/package/linux/aca/aca_setup.sh
+++ b/package/linux/aca/aca_setup.sh
@@ -218,15 +218,18 @@ fi
sed -i '/aca.certificates.leaf-three-key-alias/d' $SPRING_PROP_FILE
sed -i '/aca.certificates.intermediate-key-alias/d' $SPRING_PROP_FILE
sed -i '/aca.certificates.root-key-alias/d' $SPRING_PROP_FILE
+ sed -i '/aca.current.public.key.algorithm/d' $SPRING_PROP_FILE
if [ "$ACA_ALG" == "rsa" ]; then
# Add new lines for aca aliases
echo "aca.certificates.leaf-three-key-alias=HIRS_leaf_ca3_rsa_3k_sha384_key" >> $SPRING_PROP_FILE
echo "aca.certificates.intermediate-key-alias=HIRS_intermediate_ca_rsa_3k_sha384_key" >> $SPRING_PROP_FILE
echo "aca.certificates.root-key-alias=HIRS_root_ca_rsa_3k_sha384_key" >> $SPRING_PROP_FILE
+ echo "aca.current.public.key.algorithm=rsa" >> $SPRING_PROP_FILE
elif [ "$ACA_ALG" == "ecc" ]; then
echo "aca.certificates.leaf-three-key-alias=HIRS_leaf_ca3_ecc_512_sha384_key" >> $SPRING_PROP_FILE
echo "aca.certificates.intermediate-key-alias=HIRS_intermediate_ca_ecc_512_sha384_key" >> $SPRING_PROP_FILE
echo "aca.certificates.root-key-alias=HIRS_root_ca_ecc_512_sha384_key" >> $SPRING_PROP_FILE
+ echo "aca.current.public.key.algorithm=ecc" >> $SPRING_PROP_FILE
fi
echo "ACA setup complete" | tee -a "$LOG_FILE"
From 879ec7e2598ab60380778972fbdaa045d9cb673c Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Fri, 20 Feb 2026 17:41:15 -0500
Subject: [PATCH 03/25] v3.1_issue_1090: Figuring out how to parse the ecc key
from the bytes array. Fixing up some warnings for the shell scripts.
---
.ci/system-tests/sys_test_common.sh | 8 +--
...ionCertificateAuthorityRestController.java | 19 +++---
...ttestationCertificateAuthorityService.java | 46 ++-----------
...tationCertificateAuthorityServiceImpl.java | 60 +++++++++++++++++
...nCertificateAuthorityServiceInterface.java | 26 --------
.../persist/enums/PublicKeyAlgorithm.java | 2 +-
.../CertificateProcessingException.java | 4 +-
.../IdentityProcessingException.java | 4 +-
.../exceptions/UnexpectedServerException.java | 4 +-
.../provision/IdentityClaimProcessor.java | 8 ++-
.../provision/helper/ProvisionUtils.java | 64 ++++++++++++-------
.../AttestationCertificateAuthorityTest.java | 12 ++--
package/linux/aca/aca_check_setup.sh | 35 +++++-----
package/linux/aca/aca_remove_setup.sh | 10 +--
package/linux/aca/aca_setup.sh | 50 +++++++++------
15 files changed, 191 insertions(+), 161 deletions(-)
create mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceImpl.java
delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceInterface.java
diff --git a/.ci/system-tests/sys_test_common.sh b/.ci/system-tests/sys_test_common.sh
index a31313432..a7791eff5 100644
--- a/.ci/system-tests/sys_test_common.sh
+++ b/.ci/system-tests/sys_test_common.sh
@@ -13,11 +13,11 @@ tpm2_container=hirs-provisioner1-tpm2
checkContainerStatus() {
container_name=$1
container_id="$(docker ps -aqf "name=$container_name")"
- container_status="$(docker inspect $container_id --format='{{.State.Status}}')"
+ container_status="$(docker inspect "$container_id" --format='{{.State.Status}}')"
echo "Container id is $container_id and the status is $container_status"
if [ "$container_status" != "running" ]; then
- container_exit_code="$(docker inspect $container_id --format='{{.State.ExitCode}}')"
+ container_exit_code="$(docker inspect "$container_id" --format='{{.State.ExitCode}}')"
echo "Container Exit Code: $container_exit_code"
docker info
exit 1;
@@ -61,7 +61,7 @@ clearAcaDb() {
docker exec -i $aca_container mysql -u root -proot -e "use hirs_db; set foreign_key_checks=0; truncate Appraiser;
truncate Certificate;truncate Issued_Attestation_Platform_Join_Table;truncate CertificatesUsedToValidate;truncate ComponentAttributeResult;
truncate ComponentInfo;truncate ComponentResult;truncate Device;truncate DeviceInfoReport;truncate PortalInfo;
- truncate ReferenceDigestValue;truncate ReferenceManifest;truncate Report;truncate SupplyChainValidation;
+ truncate ReferenceDigestValue;truncate ReferenceManifest;truncate Report;
truncate SupplyChainValidationSummary;truncate SupplyChainValidationSummary_SupplyChainValidation;
truncate TPM2ProvisionerState;set foreign_key_checks=1;"
}
@@ -146,6 +146,6 @@ setAppsettings() {
# write_to_logs
writeToLogs() {
line=$1
- echo $line;
+ echo "$line";
docker exec -i $aca_container /bin/bash -c "cd .. && echo '$line' >> /var/log/hirs/HIRS_AttestationCA_Portal.log"
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
index b97608fa8..ff991839b 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
@@ -19,17 +19,17 @@
@RestController
@RequestMapping("/HIRS_AttestationCA")
public class AttestationCertificateAuthorityRestController {
- private final AttestationCertificateAuthorityService attestationCertificateAuthorityService;
+ private final AttestationCertificateAuthorityServiceImpl attestationCertificateAuthorityServiceImpl;
/**
* Constructor.
*
- * @param attestationCertificateAuthorityService Attestation Certificate Authority service
+ * @param attestationCertificateAuthorityServiceImpl Attestation Certificate Authority service
*/
@Autowired
public AttestationCertificateAuthorityRestController(
- final AttestationCertificateAuthorityService attestationCertificateAuthorityService) {
- this.attestationCertificateAuthorityService = attestationCertificateAuthorityService;
+ final AttestationCertificateAuthorityServiceImpl attestationCertificateAuthorityServiceImpl) {
+ this.attestationCertificateAuthorityServiceImpl = attestationCertificateAuthorityServiceImpl;
}
/**
@@ -41,8 +41,8 @@ public AttestationCertificateAuthorityRestController(
*/
@ResponseBody
@PostMapping(value = "/identity-claim-tpm2/process", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
- public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim) {
- return this.attestationCertificateAuthorityService.processIdentityClaimTpm2(identityClaim);
+ public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim) throws GeneralSecurityException {
+ return this.attestationCertificateAuthorityServiceImpl.processIdentityClaimTpm2(identityClaim);
}
/**
@@ -55,8 +55,9 @@ public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim)
*/
@ResponseBody
@PostMapping(value = "/request-certificate-tpm2", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
- public byte[] processCertificateRequest(@RequestBody final byte[] certificateRequest) throws GeneralSecurityException {
- return this.attestationCertificateAuthorityService.processCertificateRequest(certificateRequest);
+ public byte[] processCertificateRequest(@RequestBody final byte[] certificateRequest)
+ throws GeneralSecurityException {
+ return this.attestationCertificateAuthorityServiceImpl.processCertificateRequest(certificateRequest);
}
/**
@@ -67,6 +68,6 @@ public byte[] processCertificateRequest(@RequestBody final byte[] certificateReq
@ResponseBody
@GetMapping("/public-key")
public byte[] getLeafACACertPublicKey() {
- return this.attestationCertificateAuthorityService.getLeafACACertPublicKey();
+ return this.attestationCertificateAuthorityServiceImpl.getLeafACACertPublicKey();
}
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java
index eaa7fbe4c..54a40c9ba 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java
@@ -1,60 +1,26 @@
package hirs.attestationca.persist;
-import hirs.attestationca.persist.provision.CertificateRequestProcessor;
-import hirs.attestationca.persist.provision.IdentityClaimProcessor;
-import lombok.extern.log4j.Log4j2;
-import org.springframework.stereotype.Service;
-
import java.security.GeneralSecurityException;
/**
- * Service layer class responsible for handling both certificate and identity claim requests made by the provisioner.
+ * Interface that defines the responsibilities of the Attestation Certificate Authority service.
*/
-@Service
-@Log4j2
-public class AttestationCertificateAuthorityService implements AttestationCertificateAuthorityServiceInterface {
- private final CertificateRequestProcessor certificateRequestProcessor;
- private final IdentityClaimProcessor identityClaimProcessor;
-
- /**
- * Constructor.
- *
- * @param certificateRequestProcessor certificate request processor service
- * @param identityClaimProcessor identity claim processor service
- */
- public AttestationCertificateAuthorityService(
- final CertificateRequestProcessor certificateRequestProcessor,
- final IdentityClaimProcessor identityClaimProcessor) {
- this.certificateRequestProcessor = certificateRequestProcessor;
- this.identityClaimProcessor = identityClaimProcessor;
- }
+public interface AttestationCertificateAuthorityService {
/**
* Processes the provided identity claim.
*
* @param identityClaim a byte array representation of the identity claim
- * @return processed identity claim response
+ * @return a byte array representation of the identity claim response
*/
- public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
- return this.identityClaimProcessor.processIdentityClaimTpm2(identityClaim);
- }
+ byte[] processIdentityClaimTpm2(byte[] identityClaim) throws GeneralSecurityException;
/**
* Processes the provided certificate request.
*
* @param certificateRequest a byte array representation of the certificate request
- * @return processed certificate request response
+ * @return a byte array representation of the certificate request response
*/
- public byte[] processCertificateRequest(final byte[] certificateRequest) throws GeneralSecurityException {
- return this.certificateRequestProcessor.processCertificateRequest(certificateRequest);
- }
+ byte[] processCertificateRequest(byte[] certificateRequest) throws GeneralSecurityException;
- /**
- * Retrieves the encoded public key.
- *
- * @return encoded public key
- */
- public byte[] getLeafACACertPublicKey() {
- return this.certificateRequestProcessor.getLeafACACertificatePublicKey();
- }
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceImpl.java
new file mode 100644
index 000000000..6b77a05d4
--- /dev/null
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceImpl.java
@@ -0,0 +1,60 @@
+package hirs.attestationca.persist;
+
+import hirs.attestationca.persist.provision.CertificateRequestProcessor;
+import hirs.attestationca.persist.provision.IdentityClaimProcessor;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.stereotype.Service;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * Service layer class responsible for handling both certificate and identity claim requests made by the provisioner.
+ */
+@Service
+@Log4j2
+public class AttestationCertificateAuthorityServiceImpl implements AttestationCertificateAuthorityService {
+ private final CertificateRequestProcessor certificateRequestProcessor;
+ private final IdentityClaimProcessor identityClaimProcessor;
+
+ /**
+ * Constructor.
+ *
+ * @param certificateRequestProcessor certificate request processor service
+ * @param identityClaimProcessor identity claim processor service
+ */
+ public AttestationCertificateAuthorityServiceImpl(
+ final CertificateRequestProcessor certificateRequestProcessor,
+ final IdentityClaimProcessor identityClaimProcessor) {
+ this.certificateRequestProcessor = certificateRequestProcessor;
+ this.identityClaimProcessor = identityClaimProcessor;
+ }
+
+ /**
+ * Processes the provided identity claim.
+ *
+ * @param identityClaim a byte array representation of the identity claim
+ * @return processed identity claim response
+ */
+ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) throws GeneralSecurityException {
+ return this.identityClaimProcessor.processIdentityClaimTpm2(identityClaim);
+ }
+
+ /**
+ * Processes the provided certificate request.
+ *
+ * @param certificateRequest a byte array representation of the certificate request
+ * @return processed certificate request response
+ */
+ public byte[] processCertificateRequest(final byte[] certificateRequest) throws GeneralSecurityException {
+ return this.certificateRequestProcessor.processCertificateRequest(certificateRequest);
+ }
+
+ /**
+ * Retrieves the encoded public key.
+ *
+ * @return encoded public key
+ */
+ public byte[] getLeafACACertPublicKey() {
+ return this.certificateRequestProcessor.getLeafACACertificatePublicKey();
+ }
+}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceInterface.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceInterface.java
deleted file mode 100644
index 7e4520d4a..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceInterface.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package hirs.attestationca.persist;
-
-import java.security.GeneralSecurityException;
-
-/**
- * Interface that defines the responsibilities of the Attestation Certificate Authority service.
- */
-public interface AttestationCertificateAuthorityServiceInterface {
-
- /**
- * Processes the provided identity claim.
- *
- * @param identityClaim a byte array representation of the identity claim
- * @return a byte array representation of the identity claim response
- */
- byte[] processIdentityClaimTpm2(byte[] identityClaim);
-
- /**
- * Processes the provided certificate request.
- *
- * @param certificateRequest a byte array representation of the certificate request
- * @return a byte array representation of the certificate request response
- */
- byte[] processCertificateRequest(byte[] certificateRequest) throws GeneralSecurityException;
-
-}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
index 2f7b17389..a4a8c85ad 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
@@ -26,7 +26,7 @@
public enum PublicKeyAlgorithm {
RSA("RSA", RSAPublicKey.class),
ECC("ECC", ECPublicKey.class),
- UNKNOWN("", null);
+ UNKNOWN("UNKNOWN", null);
private final String algorithmName;
private final Class extends PublicKey> keyClass;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/CertificateProcessingException.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/CertificateProcessingException.java
index 6389e4be3..84d5eaa1f 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/CertificateProcessingException.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/CertificateProcessingException.java
@@ -1,9 +1,9 @@
package hirs.attestationca.persist.exceptions;
-import hirs.attestationca.persist.AttestationCertificateAuthorityService;
+import hirs.attestationca.persist.AttestationCertificateAuthorityServiceImpl;
/**
- * Generic exception thrown while a {@link AttestationCertificateAuthorityService}
+ * Generic exception thrown while a {@link AttestationCertificateAuthorityServiceImpl}
* is processing a newly created Attestation Certificate for a validated identity.
*/
public class CertificateProcessingException extends RuntimeException {
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/IdentityProcessingException.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/IdentityProcessingException.java
index ebca3311a..5b6cc5eec 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/IdentityProcessingException.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/IdentityProcessingException.java
@@ -1,9 +1,9 @@
package hirs.attestationca.persist.exceptions;
-import hirs.attestationca.persist.AttestationCertificateAuthorityService;
+import hirs.attestationca.persist.AttestationCertificateAuthorityServiceImpl;
/**
- * Generic exception thrown while a {@link AttestationCertificateAuthorityService}
+ * Generic exception thrown while a {@link AttestationCertificateAuthorityServiceImpl}
* is processing a newly submitted Identity.
*/
public class IdentityProcessingException extends RuntimeException {
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/UnexpectedServerException.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/UnexpectedServerException.java
index df4eb2668..890f6c2af 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/UnexpectedServerException.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/UnexpectedServerException.java
@@ -1,9 +1,9 @@
package hirs.attestationca.persist.exceptions;
-import hirs.attestationca.persist.AttestationCertificateAuthorityService;
+import hirs.attestationca.persist.AttestationCertificateAuthorityServiceImpl;
/**
- * Generic exception thrown when a {@link AttestationCertificateAuthorityService}
+ * Generic exception thrown when a {@link AttestationCertificateAuthorityServiceImpl}
* encounters an unexpected condition that can't be handled.
*/
public class UnexpectedServerException extends RuntimeException {
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
index 0363057ac..89272bca6 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
@@ -35,6 +35,7 @@
import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue;
import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest;
import hirs.attestationca.persist.enums.AppraisalStatus;
+import hirs.attestationca.persist.enums.PublicKeyAlgorithm;
import hirs.attestationca.persist.exceptions.IdentityProcessingException;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
import hirs.attestationca.persist.service.SupplyChainValidationService;
@@ -49,6 +50,7 @@
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.IOException;
@@ -78,8 +80,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
* Number of bytes to include in the TPM2.0 nonce.
*/
public static final int NONCE_LENGTH = 20;
- private static final String PCR_QUOTE_MASK = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,"
- + "14,15,16,17,18,19,20,21,22,23";
+ private static final String PCR_QUOTE_MASK = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23";
private static final int NUM_OF_VARIABLES = 5;
private static final int MAC_BYTES = 6;
@@ -91,6 +92,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
private final ReferenceDigestValueRepository referenceDigestValueRepository;
private final DeviceRepository deviceRepository;
private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
+ private final PublicKeyAlgorithm publicKeyAlgorithm;
/**
* Constructor.
@@ -107,6 +109,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
*/
@Autowired
public IdentityClaimProcessor(
+ @Value("${aca.current.public.key.algorithm}") final String publicKeyAlgorithmStr,
final SupplyChainValidationService supplyChainValidationService,
final CertificateRepository certificateRepository,
final ComponentResultRepository componentResultRepository,
@@ -124,6 +127,7 @@ public IdentityClaimProcessor(
this.referenceDigestValueRepository = referenceDigestValueRepository;
this.deviceRepository = deviceRepository;
this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
+ this.publicKeyAlgorithm = PublicKeyAlgorithm.fromString(publicKeyAlgorithmStr);
setPolicyRepository(policyRepository);
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index 7cc8081d4..4080e2234 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -10,6 +10,7 @@
import hirs.structs.converters.SimpleStructBuilder;
import hirs.structs.elements.aca.SymmetricAttestation;
import hirs.structs.elements.tpm.EncryptionScheme;
+import hirs.structs.elements.tpm.IdentityRequest;
import hirs.structs.elements.tpm.SymmetricKey;
import hirs.structs.elements.tpm.SymmetricKeyParams;
import hirs.utils.HexUtils;
@@ -45,6 +46,7 @@
import java.security.cert.X509Certificate;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
+import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.RSAPublicKeySpec;
@@ -91,7 +93,9 @@ public final class ProvisionUtils {
private static final int TPM2_CREDENTIAL_BLOB_SIZE = 392;
- private static final int RSA_MODULUS_LENGTH = 256;
+ private static final int DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES = 256;
+
+ private static final int DEFAULT_ECC_LENGTH = 0;
// Constants used to parse out the ak name from the ak public data. Used in generateAkName
private static final String AK_NAME_PREFIX = "000b";
@@ -108,11 +112,9 @@ private ProvisionUtils() {
}
/**
- * Helper method to parse a byte array into an
- * {@link hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2.IdentityClaim}.
+ * Helper method to parse a byte array into an {@link ProvisionerTpm2.IdentityClaim}.
*
- * @param identityClaim byte array that should be converted to a Protobuf IdentityClaim
- * object
+ * @param identityClaim byte array that should be converted to a Protobuf IdentityClaim object
* @return the Protobuf generated Identity Claim object
*/
public static ProvisionerTpm2.IdentityClaim parseIdentityClaim(final byte[] identityClaim) {
@@ -173,7 +175,7 @@ public static String getPemEncodedCertificate(final X509Certificate certificate)
* @throws GeneralSecurityException if the key cannot be parsed
*/
public static PublicKey parsePublicKeyFromPublicDataSegment(final PublicKeyAlgorithm publicKeyAlgorithm,
- byte[] keyBytes) throws GeneralSecurityException {
+ final byte[] keyBytes) throws GeneralSecurityException {
return switch (publicKeyAlgorithm) {
case RSA -> parseRSAKeyFromPublicDataSegment(keyBytes);
case ECC -> parseECCKeyFromPublicDataSegment(keyBytes);
@@ -189,14 +191,13 @@ public static PublicKey parsePublicKeyFromPublicDataSegment(final PublicKeyAlgor
*/
public static RSAPublicKey parseRSAKeyFromPublicDataSegment(final byte[] publicArea) {
final int pubLen = publicArea.length;
- if (pubLen < RSA_MODULUS_LENGTH) {
- throw new IllegalArgumentException(
- "EK or AK public data segment is not long enough");
+
+ if (pubLen < DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES) {
+ throw new IllegalArgumentException("EK or AK public data segment is not long enough");
}
+
// public data ends with 256 byte modulus
- byte[] modulus = HexUtils.subarray(publicArea,
- pubLen - RSA_MODULUS_LENGTH,
- pubLen - 1);
+ byte[] modulus = HexUtils.subarray(publicArea, pubLen - DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES, pubLen - 1);
return (RSAPublicKey) assembleRSAPublicKey(modulus);
}
@@ -227,16 +228,16 @@ public static PublicKey assembleRSAPublicKey(final String modulus) {
* @return RSA public key using the provided integer modulus
*/
public static PublicKey assembleRSAPublicKey(final BigInteger modulus) {
- // generate a key spec using mod and exp
+ // generate an RSA key spec using mod and exp
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, EXPONENT);
- // create the public key
+ // create the RSA public key
try {
- KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ KeyFactory keyFactory = KeyFactory.getInstance(PublicKeyAlgorithm.RSA.getAlgorithmName());
return keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
throw new UnexpectedServerException(
- "Encountered unexpected error creating public key: " + e.getMessage(), e);
+ "Encountered unexpected error creating RSA public key: " + e.getMessage(), e);
}
}
@@ -247,12 +248,27 @@ public static PublicKey assembleRSAPublicKey(final BigInteger modulus) {
* @return the ECC public key of the supplied public data
*/
public static ECPublicKey parseECCKeyFromPublicDataSegment(final byte[] publicArea) {
- return null;
+ final int pubLen = publicArea.length;
+
+ return (ECPublicKey) assembleECCPublicKey();
+ }
+
+ public static PublicKey assembleECCPublicKey() {
+ ECPublicKeySpec ecPublicKeySpec = null;
+
+ // create the RSA public key
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance(PublicKeyAlgorithm.ECC.getAlgorithmName());
+ return keyFactory.generatePublic(ecPublicKeySpec);
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+ throw new UnexpectedServerException(
+ "Encountered unexpected error creating ECC public key: " + e.getMessage(), e);
+ }
}
/**
* Will attempt to decrypt the asymmetric blob that originated from an
- * {@link hirs.structs.elements.tpm.IdentityRequest} using the cipher transformation.
+ * {@link IdentityRequest} using the cipher transformation.
*
* @param asymmetricBlob to be decrypted
* @param scheme to decrypt with
@@ -291,7 +307,7 @@ public static byte[] decryptAsymmetricBlob(final byte[] asymmetricBlob,
/**
* Will attempt to decrypt the symmetric blob that originated from an
- * {@link hirs.structs.elements.tpm.IdentityRequest} using the specified symmetric key
+ * {@link IdentityRequest} using the specified symmetric key
* and cipher transformation.
*
* @param symmetricBlob to be decrypted
@@ -379,14 +395,14 @@ public static ByteString tpm20MakeCredential(final RSAPublicKey ek, final RSAPub
// generate ak name from akMod
byte[] akModTemp = ak.getModulus().toByteArray();
- byte[] akMod = new byte[RSA_MODULUS_LENGTH];
+ byte[] akMod = new byte[DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES];
int startpos = 0;
// BigIntegers are signed, so a modulus that has a first bit of 1
// will be padded with a zero byte that must be removed
if (akModTemp[0] == 0x00) {
startpos = 1;
}
- System.arraycopy(akModTemp, startpos, akMod, 0, RSA_MODULUS_LENGTH);
+ System.arraycopy(akModTemp, startpos, akMod, 0, DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES);
byte[] akName = ProvisionUtils.generateAkName(akMod);
// generate AES and HMAC keys from seed
@@ -588,7 +604,7 @@ public static byte[] assembleCredential(final byte[] topSize, final byte[] integ
*
* @param akModulus modulus of an attestation key
* @return the ak name byte array
- * @throws java.security.NoSuchAlgorithmException Underlying SHA256 method used a bad algorithm
+ * @throws NoSuchAlgorithmException Underlying SHA256 method used a bad algorithm
*/
public static byte[] generateAkName(final byte[] akModulus) throws NoSuchAlgorithmException {
byte[] namePrefix = HexUtils.hexStringToByteArray(AK_NAME_PREFIX);
@@ -614,8 +630,8 @@ public static byte[] generateAkName(final byte[] akModulus) throws NoSuchAlgorit
* @param context second portion of message used to generate key
* @param sizeInBytes size of key to generate in bytes
* @return the derived key
- * @throws NoSuchAlgorithmException Wrong crypto algorithm selected
- * @throws java.security.InvalidKeyException Invalid key used
+ * @throws NoSuchAlgorithmException Wrong crypto algorithm selected
+ * @throws InvalidKeyException Invalid key used
*/
public static byte[] cryptKDFa(final byte[] seed, final String label, final byte[] context,
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java
index c9721002c..8bebef547 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java
@@ -73,7 +73,7 @@
import static org.mockito.Mockito.when;
/**
- * Test suite for {@link AttestationCertificateAuthorityService}.
+ * Test suite for {@link AttestationCertificateAuthorityServiceImpl}.
*/
@TestInstance(TestInstance.Lifecycle.PER_CLASS) // needed to use non-static BeforeAll
public class AttestationCertificateAuthorityTest {
@@ -123,7 +123,7 @@ public class AttestationCertificateAuthorityTest {
+ "e2 94";
private final Random random = new Random();
// object in test
- private AttestationCertificateAuthorityService aca;
+ private AttestationCertificateAuthorityServiceImpl aca;
private AccessAbstractProcessor abstractProcessor;
// test key pair
private KeyPair keyPair;
@@ -174,7 +174,7 @@ public void setupTests() throws Exception {
keyPair = keyPairGenerator.generateKeyPair();
//BeforeTest
- aca = new AttestationCertificateAuthorityService(null,
+ aca = new AttestationCertificateAuthorityServiceImpl(null,
null) {
};
abstractProcessor = new AccessAbstractProcessor(keyPair.getPrivate(), 1);
@@ -183,7 +183,7 @@ public void setupTests() throws Exception {
}
/**
- * Tests {@link AttestationCertificateAuthorityService#processIdentityClaimTpm2(byte[])}
+ * Tests {@link AttestationCertificateAuthorityServiceImpl#processIdentityClaimTpm2(byte[])}
* where the byte array is null. Expects an illegal argument exception to be thrown.
*/
@Test
@@ -193,7 +193,7 @@ public void testProcessIdentityClaimTpm2NullRequest() {
}
/**
- * Tests {@link AttestationCertificateAuthorityService#getLeafACACertPublicKey()}.
+ * Tests {@link AttestationCertificateAuthorityServiceImpl#getLeafACACertPublicKey()}.
*/
@Test
public void testGetPublicKey() {
@@ -412,7 +412,7 @@ public void testGenerateAttestation() throws Exception {
}
/**
- * Tests {@link AttestationCertificateAuthorityService#
+ * Tests {@link AttestationCertificateAuthorityServiceImpl#
* AttestationCertificateAuthority(SupplyChainValidationService, PrivateKey,
* X509Certificate, StructConverter, CertificateManager, DeviceRegister, int,
* DeviceManager, DBManager)}.
diff --git a/package/linux/aca/aca_check_setup.sh b/package/linux/aca/aca_check_setup.sh
index d6dd8fca1..b3a5b2e1b 100755
--- a/package/linux/aca/aca_check_setup.sh
+++ b/package/linux/aca/aca_check_setup.sh
@@ -167,15 +167,15 @@ check_pwds () {
PRESENT=true
echo "Checking if ACA passwords are present..."
- if [ -z $hirs_pki_password ]; then
+ if [ -z "$hirs_pki_password" ]; then
echo "ACA pki password not set"
PRESENT=false
fi
- if [ -z $hirs_db_username ]; then
+ if [ -z "$hirs_db_username" ]; then
echo "hirs db username not set"
PRESENT=false
fi
- if [ -z $hirs_db_password ]; then
+ if [ -z "$hirs_db_password" ]; then
echo "hirs db user password not set"
PRESENT=false
fi
@@ -204,8 +204,8 @@ check_mysql_setup () {
echo " Mysql client ($DB_CLIENT_CONF) is configured for command line use of TLS"
fi
- if [ ! -z $mysql_admin_password ]; then
- mysql -u root --password=$mysql_admin_password -e "STATUS;" &> /dev/null
+ if [ ! -z "$mysql_admin_password" ]; then
+ mysql -u root --password="$mysql_admin_password" -e "STATUS;" &> /dev/null
if [ $? -eq 0 ]; then
echo "Mysql Root password verified"
else
@@ -213,10 +213,11 @@ check_mysql_setup () {
fi
if [ ! -z "${ARG_VERBOSE}" ]; then
echo "Mysql status:"
- mysql -u root --password=$mysql_admin_password -e "STATUS;"
+ mysql -u root --password="$mysql_admin_password" -e "STATUS;"
echo "Listing mysql users:"
- mysql -u root --password=$mysql_admin_password -e "Select user from mysql.user;"
+ mysql -u root --password="$mysql_admin_password" -e "Select user from mysql.user;"
echo "Listing all databses:"
+ # shellcheck disable=SC2086
mysql -u root --password=$mysql_admin_password -e "show databases;"
fi
fi
@@ -225,7 +226,7 @@ check_mysql_setup () {
check_cert () {
TRUST_STORE=$1
CERT=$2
- RESULT=$(openssl verify -CAfile "$TRUST_STORE" $CERT)
+ RESULT=$(openssl verify -CAfile "$TRUST_STORE" "$CERT")
if [ $? -ne 0 ]; then
ALL_CHECKS_PASSED=false
ALL_CERTS_PASSED=false
@@ -242,7 +243,7 @@ check_pki () {
Skipping PKI Checks."
fi
- pushd $CERT_PATH$RSA_PATH > /dev/null
+ pushd $CERT_PATH$RSA_PATH > /dev/null || echo "Unable to push the directory to the stack"
check_cert $RSA_TRUST_STORE $RSA_HIRS_ROOT
check_cert $RSA_TRUST_STORE $RSA_HIRS_INTERMEDIATE
check_cert $RSA_TRUST_STORE $RSA_HIRS_CA1
@@ -302,7 +303,7 @@ check_db () {
fi
- RESULT=$(mysqlshow --user=hirs_db --password=$hirs_db_password hirs_db| grep -o hirs_db)
+ RESULT=$(mysqlshow --user=hirs_db --password="$hirs_db_password" hirs_db| grep -o hirs_db)
if [ "$RESULT" == "hirs_db" ]; then
echo " The hirs_db database is visible by the hirs_db user"
else
@@ -311,26 +312,26 @@ check_db () {
fi
if [ ! -z "${ARG_VERBOSE}" ]; then
echo " Show hirs_db user config using hirs_db password"
- mysql -u hirs_db --password=$hirs_db_password -e "SHOW CREATE USER 'hirs_db'@'localhost';" \
+ mysql -u hirs_db --password="$hirs_db_password" -e "SHOW CREATE USER 'hirs_db'@'localhost';" \
--ssl-ca=/etc/hirs/certificates/HIRS/rsa_3k_sha384_certs/HIRS_rsa_3k_sha384_Cert_Chain.pem \
--ssl-cert=/etc/hirs/certificates/HIRS/rsa_3k_sha384_certs/HIRS_db_client_rsa_3k_sha384.pem \
--ssl-key=/etc/hirs/certificates/HIRS/rsa_3k_sha384_certs/HIRS_db_client_rsa_3k_sha384.key
echo "Mysql TLS configuration"
- mysql -u root --password=$mysql_admin_password -e "SHOW VARIABLES LIKE '%ssl%'"
+ mysql -u root --password="$mysql_admin_password" -e "SHOW VARIABLES LIKE '%ssl%'"
echo "TLS versions allowed on mariadb:"
- mysql -u root --password=$mysql_admin_password -e "SHOW GLOBAL VARIABLES LIKE 'tls_version'";
+ mysql -u root --password="$mysql_admin_password" -e "SHOW GLOBAL VARIABLES LIKE 'tls_version'";
echo "hirs_db user database access:"
- mysql -u hirs_db --password=$hirs_db_password -e "SHOW DATABASES;";
+ mysql -u hirs_db --password="$hirs_db_password" -e "SHOW DATABASES;";
echo "Privileges for the hirs_db user:"
- mysql -u hirs_db --password=$hirs_db_password -e "SHOW GRANTS FOR 'hirs_db'@'localhost'"
+ mysql -u hirs_db --password="$hirs_db_password" -e "SHOW GRANTS FOR 'hirs_db'@'localhost'"
echo "MYSQL Log:"
- mysql -u root --password=$mysql_admin_password -e "SHOW GLOBAL VARIABLES LIKE 'log_error'"
+ mysql -u root --password="$mysql_admin_password" -e "SHOW GLOBAL VARIABLES LIKE 'log_error'"
fi
}
# Check selinux status and files that require specific contexts
check_selinux () {
- if [ $ID = "ubuntu" ]; then
+ if [ "$ID" = "ubuntu" ]; then
echo "Skipping selinux check on ubuntu"
return
fi
diff --git a/package/linux/aca/aca_remove_setup.sh b/package/linux/aca/aca_remove_setup.sh
index fa7db8be9..646be847a 100755
--- a/package/linux/aca/aca_remove_setup.sh
+++ b/package/linux/aca/aca_remove_setup.sh
@@ -8,7 +8,7 @@
SCRIPT_DIR=$( dirname -- "$( readlink -f -- "$0"; )"; )
OPTION_IN=$1; # per Fedora packing guidelines: $1 = 1 for an upgrade, 0 for a remove
-if [ -z $1 ]; then OPTION_IN="2"; fi # Set if called by command line
+if [ -z "$1" ]; then OPTION_IN="2"; fi # Set if called by command line
case $OPTION_IN in
"0")
echo "Package removal requested"
@@ -48,7 +48,7 @@ if [ ! -d "/opt/hirs" ]; then
fi
-source $SCRIPT_DIR/../db/mysql_util.sh
+source "$SCRIPT_DIR"/../db/mysql_util.sh
# Make sure mysql root password is available before continuing...
check_mariadb_install
@@ -57,9 +57,9 @@ check_mysql_root
# remove the hrs-db and hirs_db user
if [ $OPTION = "ACA_SET_REMOVE" ] || [ $OPTION = "ACA_PKG_REMOVE" ]; then
- pushd $SCRIPT_DIR/../db/ &>/dev/null
- ./db_drop.sh $DB_ADMIN_PWD
- popd &>/dev/null
+ pushd "$SCRIPT_DIR"/../db/ &>/dev/null || echo "Unable to push directory to stack"
+ ./db_drop.sh "$DB_ADMIN_PWD"
+ popd &>/dev/null || echo "Unable to pop directory from stack"
fi
# remove pki files and config files if not installed by rpm
diff --git a/package/linux/aca/aca_setup.sh b/package/linux/aca/aca_setup.sh
index 399035847..91b75a49d 100755
--- a/package/linux/aca/aca_setup.sh
+++ b/package/linux/aca/aca_setup.sh
@@ -82,30 +82,33 @@ while [[ $# -gt 0 ]]; do
;;
esac
done
+
# Set default algorithms to rsa
-if [ -z $ARG_ACA_ALG ]; then
+if [ -z "$ARG_ACA_ALG" ]; then
ACA_ALG="rsa"
echo "Using default algorithm ($ACA_ALG) for Attestation Certs"
fi
-if [ -z $ARG_TLS_ALG ]; then
+
+if [ -z "$ARG_TLS_ALG" ]; then
TLS_ALG="rsa"
echo "Using default algorithm ($TLS_ALG) for the ACA portal"
fi
-if [ -z $ARG_DB_ALG ]; then
+
+if [ -z "$ARG_DB_ALG" ]; then
DB_ALG="rsa"
echo "Using default algorithm ($DB_ALG) for the Database"
fi
# Check for valid algorithms
-if [ ! $ACA_ALG == "rsa" ] && [ ! $ACA_ALG == "ecc" ] ; then
+if [ ! "$ACA_ALG" == "rsa" ] && [ ! "$ACA_ALG" == "ecc" ] ; then
echo "Invalid ACA algorithm $ACA_ALG specified. Valid options are rsa or ecc."
exit 1;
fi
-if [ ! $TLS_ALG == "rsa" ] && [ ! $TLS_ALG == "ecc" ] ; then
+if [ ! "$TLS_ALG" == "rsa" ] && [ ! "$TLS_ALG" == "ecc" ] ; then
echo "Invalid TLS algorithm $TLS_ALG specified. Valid options are rsa or ecc."
exit 1;
fi
-if [ ! $DB_ALG == "rsa" ] && [ ! $DB_ALG == "ecc" ] ; then
+if [ ! "$DB_ALG" == "rsa" ] && [ ! "$DB_ALG" == "ecc" ] ; then
echo "Invalid DB algorithm $DB_ALG specified. Valid options are rsa or ecc."
exit 1;
fi
@@ -127,7 +130,7 @@ fi
#fi
# Check for existing installation folders and exist if found
-if [ -z $ARG_UNATTEND ]; then
+if [ -z "$ARG_UNATTEND" ]; then
if [ -d "/etc/hirs" ]; then
echo "/etc/hirs exists, aborting install."
exit 1
@@ -141,7 +144,7 @@ fi
mkdir -p $HIRS_CONF_DIR $LOG_DIR $HIRS_JSON_DIR $ACA_OPT_DIR
touch "$LOG_FILE"
-pushd $SCRIPT_DIR &>/dev/null
+pushd "$SCRIPT_DIR" &>/dev/null
# Check if build environment is being used and set up property files
if [ -f $PROP_FILE ]; then
cp -n $PROP_FILE $HIRS_CONF_DIR/
@@ -163,12 +166,12 @@ if command -v git &> /dev/null; then
git rev-parse --is-inside-work-tree &> /dev/null;
if [ $? -eq 0 ]; then
jarVersion=$(cat '../../../VERSION').$(date +%s).$(git rev-parse --short HEAD)
- echo $jarVersion > $ACA_VERSION_FILE
+ echo "$jarVersion" > $ACA_VERSION_FILE
fi
fi
# Set HIRS PKI password
-if [ -z $HIRS_PKI_PWD ]; then
+if [ -z "$HIRS_PKI_PWD" ]; then
# Create a 32 character random password
PKI_PASS=$(head -c 64 /dev/urandom | md5sum | tr -dc 'a-zA-Z0-9')
echo "Using randomly generated password for the PKI key password" | tee -a "$LOG_FILE"
@@ -178,7 +181,7 @@ if [ -z $HIRS_PKI_PWD ]; then
fi
if [ -z "${ARG_SKIP_PKI}" ]; then
- ../pki/pki_setup.sh $LOG_FILE $PKI_PASS $ARG_UNATTEND
+ ../pki/pki_setup.sh "$LOG_FILE" "$PKI_PASS" "$ARG_UNATTEND"
if [ $? -eq 0 ]; then
echo "ACA PKI setup complete" | tee -a "$LOG_FILE"
else
@@ -190,7 +193,7 @@ if [ -z "${ARG_SKIP_PKI}" ]; then
fi
if [ -z "${ARG_SKIP_DB}" ]; then
- ../db/db_create.sh $LOG_FILE $PKI_PASS $DB_ALG $ARG_UNATTEND
+ ../db/db_create.sh "$LOG_FILE" "$PKI_PASS" "$DB_ALG" "$ARG_UNATTEND"
if [ $? -eq 0 ]; then
echo "ACA database setup complete" | tee -a "$LOG_FILE"
else
@@ -220,16 +223,21 @@ fi
sed -i '/aca.certificates.root-key-alias/d' $SPRING_PROP_FILE
sed -i '/aca.current.public.key.algorithm/d' $SPRING_PROP_FILE
if [ "$ACA_ALG" == "rsa" ]; then
- # Add new lines for aca aliases
- echo "aca.certificates.leaf-three-key-alias=HIRS_leaf_ca3_rsa_3k_sha384_key" >> $SPRING_PROP_FILE
- echo "aca.certificates.intermediate-key-alias=HIRS_intermediate_ca_rsa_3k_sha384_key" >> $SPRING_PROP_FILE
- echo "aca.certificates.root-key-alias=HIRS_root_ca_rsa_3k_sha384_key" >> $SPRING_PROP_FILE
- echo "aca.current.public.key.algorithm=rsa" >> $SPRING_PROP_FILE
+ # Add new lines for aca aliases for the RSA public key algorithm
+ {
+ echo "aca.certificates.leaf-three-key-alias=HIRS_leaf_ca3_rsa_3k_sha384_key"
+ echo "aca.certificates.intermediate-key-alias=HIRS_intermediate_ca_rsa_3k_sha384_key"
+ echo "aca.certificates.root-key-alias=HIRS_root_ca_rsa_3k_sha384_key"
+ echo "aca.current.public.key.algorithm=rsa"
+ } >> $SPRING_PROP_FILE
elif [ "$ACA_ALG" == "ecc" ]; then
- echo "aca.certificates.leaf-three-key-alias=HIRS_leaf_ca3_ecc_512_sha384_key" >> $SPRING_PROP_FILE
- echo "aca.certificates.intermediate-key-alias=HIRS_intermediate_ca_ecc_512_sha384_key" >> $SPRING_PROP_FILE
- echo "aca.certificates.root-key-alias=HIRS_root_ca_ecc_512_sha384_key" >> $SPRING_PROP_FILE
- echo "aca.current.public.key.algorithm=ecc" >> $SPRING_PROP_FILE
+ {
+ # Add new lines for aca aliases for the ECC public key algorithm
+ echo "aca.certificates.leaf-three-key-alias=HIRS_leaf_ca3_ecc_512_sha384_key"
+ echo "aca.certificates.intermediate-key-alias=HIRS_intermediate_ca_ecc_512_sha384_key"
+ echo "aca.certificates.root-key-alias=HIRS_root_ca_ecc_512_sha384_key"
+ echo "aca.current.public.key.algorithm=ecc"
+ } >> $SPRING_PROP_FILE
fi
echo "ACA setup complete" | tee -a "$LOG_FILE"
From 9d14600ba63482cd57a2e6558d19b95d1236c1b1 Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Mon, 23 Feb 2026 15:54:08 -0500
Subject: [PATCH 04/25] v3.1_issue_1090: Fixing warnings/errors pointed out by
shell plugin in bash scripts. Took care of a majority of them.
---
package/linux/aca/aca_bootRun.sh | 6 +--
package/linux/aca/aca_check_setup.sh | 47 ++++++++++----------
package/linux/aca/aca_remove_setup.sh | 3 +-
package/linux/aca/check_for_aca.sh | 2 +-
package/linux/db/db_create.sh | 64 ++++++++++++++-------------
package/linux/db/db_drop.sh | 14 +++---
package/linux/db/mysql_util.sh | 32 +++++++-------
7 files changed, 85 insertions(+), 83 deletions(-)
mode change 100644 => 100755 package/linux/aca/check_for_aca.sh
diff --git a/package/linux/aca/aca_bootRun.sh b/package/linux/aca/aca_bootRun.sh
index 20536795f..b469b0894 100755
--- a/package/linux/aca/aca_bootRun.sh
+++ b/package/linux/aca/aca_bootRun.sh
@@ -79,7 +79,7 @@ fi
set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
-source $SCRIPT_DIR/../db/mysql_util.sh
+source "$SCRIPT_DIR"/../db/mysql_util.sh
if [ $ALG = "RSA" ]; then
CERT_PATH="/etc/hirs/certificates/HIRS/$RSA_PATH"
@@ -143,9 +143,9 @@ else
echo "Booting the ACA from a war file..."
if [ "$DEBUG_ACA" == YES ]; then
echo "... in debug"
- java $DEBUG_OPTIONS -jar $WAR_PATH --spring.config.location=$SPRING_PROP_FILE &
+ java "$DEBUG_OPTIONS" -jar "$WAR_PATH" --spring.config.location=$SPRING_PROP_FILE &
else
- java -jar $WAR_PATH --spring.config.location=$SPRING_PROP_FILE &
+ java -jar "$WAR_PATH" --spring.config.location=$SPRING_PROP_FILE &
fi
exit 0
fi
diff --git a/package/linux/aca/aca_check_setup.sh b/package/linux/aca/aca_check_setup.sh
index b3a5b2e1b..1ffbceee7 100755
--- a/package/linux/aca/aca_check_setup.sh
+++ b/package/linux/aca/aca_check_setup.sh
@@ -40,11 +40,11 @@ DB_CLIENT_CONF="/etc/my.cnf.d/client.cnf"
ALL_CHECKS_PASSED=true
ALL_CERTS_PASSED=true
-source $SCRIPT_DIR/../db/mysql_util.sh
+source "$SCRIPT_DIR"/../db/mysql_util.sh
source /etc/os-release
# Setup distro specifc paths and variables
-if [ $ID = "ubuntu" ]; then
+if [ "$ID" = "ubuntu" ]; then
DB_SRV_CONF="/etc/mysql/mariadb.conf.d/50-server.cnf"
DB_CLIENT_CONF="/etc/mysql/mariadb.conf.d/50-client.cnf"
fi
@@ -85,13 +85,13 @@ fi
echo "Checking HIRS ACA Setup on this device..."
# Check if aca setup was performed
# Check is RPM was installed via RPM package
- if [ $ID = "rhel" ]; then
+ if [ "$ID" = "rhel" ]; then
echo "RHEL distro detected"
rpm -q --quiet HIRS_AttestationCA
- elif [ $ID = 'ubuntu' ]; then
+ elif [ "$ID" = 'ubuntu' ]; then
echo "Ubuntu distro detected"
dpkg -l "hirs-attestationca" > /dev/null
- elif [ $ID = 'rocky' ]; then
+ elif [ "$ID" = 'rocky' ]; then
echo "Rocky distro detected"
rpm -q --quiet HIRS_AttestationCA
else
@@ -99,7 +99,7 @@ echo "Checking HIRS ACA Setup on this device..."
fi
if [ $? -eq 0 ]; then
echo "HIRS ACA was installed via an OS package on this device."
- if [ $SYSD_SERVICE = true ]; then
+ if [ "$SYSD_SERVICE" = true ]; then
systemctl is-active --quiet hirs-aca
if [[ $? -eq 0 ]]; then
echo " The hirs-aca service is active"
@@ -191,34 +191,33 @@ check_mysql_setup () {
# make sure mysql is running and restart if its not...
check_mysql
# Check DB server/client TLS setup.
- if [[ $(cat "$DB_SRV_CONF" | grep -c "HIRS") < 1 ]]; then
+ if [[ "$(grep -c "HIRS" "$DB_SRV_CONF")" -lt 1 ]]; then
echo " Mysql server ($DB_SRV_CONF) is NOT configured for Server Side TLS"
ALL_CHECKS_PASSED=false
else
echo " Mysql server ($DB_SRV_CONF) is configured for Server Side TLS"
fi
- if [[ $(cat "$DB_CLIENT_CONF" | grep -c "HIRS") < 1 ]]; then
+ if [[ "$(grep -c "HIRS" "$DB_CLIENT_CONF")" -lt 1 ]]; then
echo " Mysql client ($DB_CLIENT_CONF)is NOT configured for command line use of TLS without provding key/cert ino the commandline"
ALL_CHECKS_PASSED=false
else
echo " Mysql client ($DB_CLIENT_CONF) is configured for command line use of TLS"
fi
- if [ ! -z "$mysql_admin_password" ]; then
+ if [ -n "$mysql_admin_password" ]; then
mysql -u root --password="$mysql_admin_password" -e "STATUS;" &> /dev/null
if [ $? -eq 0 ]; then
echo "Mysql Root password verified"
else
echo "Mysql Root password verification failed!"
fi
- if [ ! -z "${ARG_VERBOSE}" ]; then
+ if [ -n "${ARG_VERBOSE}" ]; then
echo "Mysql status:"
mysql -u root --password="$mysql_admin_password" -e "STATUS;"
echo "Listing mysql users:"
mysql -u root --password="$mysql_admin_password" -e "Select user from mysql.user;"
- echo "Listing all databses:"
- # shellcheck disable=SC2086
- mysql -u root --password=$mysql_admin_password -e "show databases;"
+ echo "Listing all databases:"
+ mysql -u root --password="$mysql_admin_password" -e "show databases;"
fi
fi
}
@@ -231,8 +230,8 @@ check_cert () {
ALL_CHECKS_PASSED=false
ALL_CERTS_PASSED=false
fi
- if [ ! -z "${ARG_VERBOSE}" ]; then
- echo " "$RESULT
+ if [ -n "${ARG_VERBOSE}" ]; then
+ echo " ""$RESULT"
fi
}
@@ -254,8 +253,8 @@ check_pki () {
check_cert $RSA_TRUST_STORE $RSA_DB_CLIENT_CERT
check_cert $RSA_TRUST_STORE $RSA_WEB_TLS_CERT
- popd > /dev/null
- pushd $CERT_PATH$ECC_PATH > /dev/null
+ popd > /dev/null || echo "Unable to pop the directory from the stack"
+ pushd $CERT_PATH$ECC_PATH > /dev/null || echo "Unable to push the directory to the stack"
check_cert $ECC_TRUST_STORE $ECC_HIRS_ROOT
check_cert $ECC_TRUST_STORE $ECC_HIRS_INTERMEDIATE
check_cert $ECC_TRUST_STORE $ECC_HIRS_CA1
@@ -265,7 +264,7 @@ check_pki () {
check_cert $ECC_TRUST_STORE $ECC_DN_SRV_CERT
check_cert $ECC_TRUST_STORE $ECC_DB_CLIENT_CERT
check_cert $ECC_TRUST_STORE $ECC_WEB_TLS_CERT
- popd > /dev/null
+ popd > /dev/null || echo "Unable to pop the directory from the stack"
if [ -z "${ARG_VERBOSE}" ]; then
if [ $ALL_CERTS_PASSED == true ]; then
@@ -273,15 +272,15 @@ check_pki () {
else
echo " Error: There were error in the certificates under $CERT_PATH"
fi
- keytool -list -keystore /etc/hirs/certificates/HIRS/TrustStore.jks -storepass $hirs_pki_password | grep hirs | sed -e 's/^/ /' > /dev/null
+ keytool -list -keystore /etc/hirs/certificates/HIRS/TrustStore.jks -storepass "$hirs_pki_password" | grep hirs | sed -e 's/^/ /' > /dev/null
else #verbose
echo " Checking TrustStore, aliases, and pki password"
echo " Truststore alias list:"
- keytool -list -keystore /etc/hirs/certificates/HIRS/TrustStore.jks -storepass $hirs_pki_password | sed -e 's/^/ /' 2>/dev/null
+ keytool -list -keystore /etc/hirs/certificates/HIRS/TrustStore.jks -storepass "$hirs_pki_password" | sed -e 's/^/ /' 2>/dev/null
echo " Checking KeyStore, aliases, and pki password"
echo " Keystore alias list:"
- keytool -list -keystore /etc/hirs/certificates/HIRS/KeyStore.jks -storepass $hirs_pki_password | sed -e 's/^/ /' 2>/dev/null
+ keytool -list -keystore /etc/hirs/certificates/HIRS/KeyStore.jks -storepass "$hirs_pki_password" | sed -e 's/^/ /' 2>/dev/null
fi
if [ $? -eq 0 ]; then
@@ -294,7 +293,7 @@ check_pki () {
check_db () {
echo "Checking DB server TLS configuration..."
- RESULT=$(mysql -u root --password=$mysql_admin_password -e "SHOW VARIABLES LIKE '%have_ssl%'" | grep -o YES )
+ RESULT=$(mysql -u root --password="$mysql_admin_password" -e "SHOW VARIABLES LIKE '%have_ssl%'" | grep -o YES )
if [ "$RESULT" == "YES" ]; then
echo " Mysql Server side TLS is enabled:"
else
@@ -310,7 +309,7 @@ check_db () {
echo " Error: The hirs_db database is NOT visible by the hirs_db user"
ALL_CHECKS_PASSED=false
fi
- if [ ! -z "${ARG_VERBOSE}" ]; then
+ if [ -n "${ARG_VERBOSE}" ]; then
echo " Show hirs_db user config using hirs_db password"
mysql -u hirs_db --password="$hirs_db_password" -e "SHOW CREATE USER 'hirs_db'@'localhost';" \
--ssl-ca=/etc/hirs/certificates/HIRS/rsa_3k_sha384_certs/HIRS_rsa_3k_sha384_Cert_Chain.pem \
@@ -361,7 +360,7 @@ check_selinux () {
check_fips () {
echo "Checking FIPS mode on this device..."
fips=$(sysctl -a 2>&1 | grep crypto.fips_enabled)
- echo " "$fips
+ echo " ""$fips"
}
# Run Checks
diff --git a/package/linux/aca/aca_remove_setup.sh b/package/linux/aca/aca_remove_setup.sh
index 646be847a..6e20a0d01 100755
--- a/package/linux/aca/aca_remove_setup.sh
+++ b/package/linux/aca/aca_remove_setup.sh
@@ -25,7 +25,6 @@ case $OPTION_IN in
*)
echo "$1 is an unknown parameter for aca_remove_setup"
exit 1
- break
;;
esac
@@ -81,5 +80,5 @@ fi
# Remove current ACA process
echo "Shutting down the aca..."
-ps axf | grep HIRS_AttestationCAPortal.war | grep -v grep | awk '{print "kill " $1}' | sh >/dev/null 2>&1
+pgrep HIRS_AttestationCAPortal.war | xargs kill >/dev/null 2>&1
echo "ACA setup removal complete."
diff --git a/package/linux/aca/check_for_aca.sh b/package/linux/aca/check_for_aca.sh
old mode 100644
new mode 100755
index 62c573780..21dd8fa77
--- a/package/linux/aca/check_for_aca.sh
+++ b/package/linux/aca/check_for_aca.sh
@@ -8,7 +8,7 @@
ACA_URL="https://localhost:8443/HIRS_AttestationCAPortal/portal/index"
echo "Waiting for tomcat..."
count=0
- until [ "`curl --silent --connect-timeout 1 --insecure -I $ACA_URL | grep -c 'Date'`" == 1 ] || [[ $count -gt 20 ]]; do
+ until [ "$(curl --silent --connect-timeout 1 --insecure -I $ACA_URL | grep -c 'Date')" == 1 ] || [[ $count -gt 20 ]]; do
((count++))
sleep 1
done
diff --git a/package/linux/db/db_create.sh b/package/linux/db/db_create.sh
index f88a258cb..fd27d786e 100755
--- a/package/linux/db/db_create.sh
+++ b/package/linux/db/db_create.sh
@@ -19,7 +19,7 @@ SCRIPT_DIR=$( dirname -- "$( readlink -f -- "$0"; )"; )
SPRING_PROP_FILE="/etc/hirs/aca/application.properties"
ACA_PROP_FILE="/etc/hirs/aca/aca.properties"
DB_ADMIN_PWD=""
-# Db Configuration fileis, use RHELpaths as default
+# Db Configuration files, use RHELpaths as default
DB_SRV_CONF="/etc/my.cnf.d/mariadb-server.cnf"
DB_CLIENT_CONF="/etc/my.cnf.d/client.cnf"
# Default Certificates
@@ -47,22 +47,22 @@ mkdir -p /etc/hirs/aca/
mkdir -p /var/log/hirs/
source $ACA_PROP_FILE
-source $SCRIPT_DIR/mysql_util.sh
+source "$SCRIPT_DIR"/mysql_util.sh
source /etc/os-release
# Setup distro specifc paths and variables
-if [ $ID = "ubuntu" ]; then
+if [ "$ID" = "ubuntu" ]; then
DB_SRV_CONF="/etc/mysql/mariadb.conf.d/50-server.cnf"
DB_CLIENT_CONF="/etc/mysql/mariadb.conf.d/50-client.cnf"
mkdir -p /var/log/mariadb >> /dev/null
- if [[ $(cat "$DB_SRV_CONF" | grep -c "log-error") < 1 ]]; then
+ if [[ "$(grep -c "log-error" "$DB_SRV_CONF")" -lt 1 ]]; then
echo "log_error=/var/log/mariadb/mariadb.log" >> $DB_SRV_CONF
echo "tls_version = TLSv1.2,TLSv1.3" >> $DB_SRV_CONF
fi
fi
touch $ACA_PROP_FILE
-touch $LOG_FILE
+touch "$LOG_FILE"
touch $DB_SRV_CONF
touch $DB_LOG_FILE
@@ -73,19 +73,19 @@ check_mysql_root_pwd () {
# Check if property file exists and look for properties
if [ -f $ACA_PROP_FILE ]; then
source $ACA_PROP_FILE
- if [ ! -z $hirs_pki_password ]; then PKI_PASS=$hirs_pki_password; fi
- if [ ! -z $mysql_admin_password ]; then HIRS_MYSQL_ROOT_PWD=$mysql_admin_password; fi
- if [ ! -z $hirs_db_password ]; then HIRS_DB_PWD=$hirs_db_password; fi
+ if [ -n "$hirs_pki_password" ]; then PKI_PASS=$hirs_pki_password; fi
+ if [ -n "$mysql_admin_password" ]; then HIRS_MYSQL_ROOT_PWD=$mysql_admin_password; fi
+ if [ -n "$hirs_db_password" ]; then HIRS_DB_PWD=$hirs_db_password; fi
fi
fi
- if [ -z $HIRS_MYSQL_ROOT_PWD ]; then
+ if [ -z "$HIRS_MYSQL_ROOT_PWD" ]; then
# Create a 32 character random password
echo "Using randomly generated password for the DB admin" | tee -a "$LOG_FILE"
DB_ADMIN_PWD=$(head -c 64 /dev/urandom | md5sum | tr -dc 'a-zA-Z0-9')
echo "DB Admin will be set to $DB_ADMIN_PWD , please make note for next mysql use."
# Check UNATTENDED flag set m if not then prompt user for permission ot store mysql root password
- if [ -z $UNATTENDED ]; then
+ if [ -z "$UNATTENDED" ]; then
read -p "Do you wish to save this password to the aca.properties file? " confirm
if [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]]; then
echo "mysql_admin_password=$DB_ADMIN_PWD" >> $ACA_PROP_FILE
@@ -117,18 +117,20 @@ check_mysql_root_pwd () {
set_mysql_server_tls () {
# Check DB server setup. If HIRS ssl params dont exist then we need to add them.
- if [[ $(cat "$DB_SRV_CONF" | grep -c "HIRS") < 1 ]]; then
+ if [[ "$(grep -c "HIRS" "$DB_SRV_CONF")" -lt 1 ]]; then
# Add TLS files to my.cnf
echo "Updating $DB_SRV_CONF with ssl parameters..." | tee -a "$LOG_FILE"
- echo "ssl_ca=$SSL_DB_SRV_CHAIN" >> "$DB_SRV_CONF"
- echo "ssl_cert=$SSL_DB_SRV_CERT" >> "$DB_SRV_CONF"
- echo "ssl_key=$SSL_DB_SRV_KEY" >> "$DB_SRV_CONF"
- # The following arent avialble in Mariadb 10.3
+ {
+ echo "ssl_ca=$SSL_DB_SRV_CHAIN"
+ echo "ssl_cert=$SSL_DB_SRV_CERT"
+ echo "ssl_key=$SSL_DB_SRV_KEY"
+ } >> "$DB_SRV_CONF"
+ # The following arent available in Mariadb 10.3
#echo "tls_version=TLSv1.2,TLSv1.3" >> "$DB_SRV_CONF"
#echo "require_secure_transport=ON" >> "$DB_SRV_CONF"
# Make sure mysql can access them
- chown mysql:mysql $SSL_DB_SRV_CHAIN $SSL_DB_SRV_CERT $SSL_DB_SRV_KEY
+ chown mysql:mysql "$SSL_DB_SRV_CHAIN" "$SSL_DB_SRV_CERT" "$SSL_DB_SRV_KEY"
chmod 644 $DB_SRV_CONF $DB_CLIENT_CONF
# Make selinux contexts for config files, if selinux is enabled
if [[ $ID = "rhel" ]] || [[ $ID = "rocky" ]] ||[[ $ID = "fedora" ]]; then
@@ -142,18 +144,20 @@ set_mysql_server_tls () {
fi
fi
else
- echo "mysql.cnf contians existing entry for ssl, skipping..." | tee -a "$LOG_FILE"
+ echo "mysql.cnf contains existing entry for ssl, skipping..." | tee -a "$LOG_FILE"
fi
}
set_mysql_client_tls () {
# Update ACA property file with client cert info, if not there already
-if [[ $(cat "$DB_CLIENT_CONF" | grep -c "HIRS") < 1 ]]; then
+if [[ "$(grep -c "HIRS" "$DB_CLIENT_CONF")" -lt 1 ]]; then
echo "Updating $DB_CLIENT_CONF with ssl parameters..." | tee -a "$LOG_FILE"
- echo "ssl_ca=$SSL_DB_CLIENT_CHAIN" >> $DB_CLIENT_CONF
- echo "ssl_cert=$SSL_DB_CLIENT_CERT" >> $DB_CLIENT_CONF
- echo "ssl_key=$SSL_DB_CLIENT_KEY" >> $DB_CLIENT_CONF
- chown mysql:mysql $SSL_DB_CLIENT_CHAIN $SSL_DB_CLIENT_CERT $SSL_DB_CLIENT_KEY
+ {
+ echo "ssl_ca=$SSL_DB_CLIENT_CHAIN"
+ echo "ssl_cert=$SSL_DB_CLIENT_CERT"
+ echo "ssl_key=$SSL_DB_CLIENT_KEY"
+ } >> $DB_CLIENT_CONF
+ chown mysql:mysql "$SSL_DB_CLIENT_CHAIN" "$SSL_DB_CLIENT_CERT" "$SSL_DB_CLIENT_KEY"
# Make selinux contexts for config files, if selinux is enabled
if [[ $ID = "rhel" ]] || [[ $ID = "rocky" ]] ||[[ $ID = "fedora" ]]; then
command -v selinuxenabled > /dev/null
@@ -173,7 +177,7 @@ set_hirs_db_pwd () {
check_hirs_db
if [[ $HIRS_DB_USER_EXISTS != "1" ]]; then
# Check if Mysql HIRS DB password set by system variable or set to random number
- if [ -z $HIRS_DB_PWD ]; then
+ if [ -z "$HIRS_DB_PWD" ]; then
HIRS_DB_PWD=$(head -c 64 /dev/urandom | md5sum | tr -dc 'a-zA-Z0-9')
fi
# Add key/values only if they dont exist
@@ -202,13 +206,13 @@ create_hirs_db_with_tls () {
echo "hirs_db already exists, skipping"
else
# Check if hirs_db not created and create it if it wasn't
- mysqlshow --user=root --password="$DB_ADMIN_PWD" | grep "hirs_db" >> $LOG_FILE 2>&1
+ mysqlshow --user=root --password="$DB_ADMIN_PWD" | grep "hirs_db" >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
echo "hirs_db exists, skipping hirs_db create"
else
- mysql -u root --password=$DB_ADMIN_PWD < $MYSQL_DIR/db_create.sql
- mysql -u root --password=$DB_ADMIN_PWD < $MYSQL_DIR/secure_mysql.sql
- mysql -u root --password=$DB_ADMIN_PWD -e "SET PASSWORD FOR 'hirs_db'@'localhost' = PASSWORD('"$HIRS_DB_PWD"'); FLUSH PRIVILEGES;";
+ mysql -u root --password="$DB_ADMIN_PWD" < "$MYSQL_DIR"/db_create.sql
+ mysql -u root --password="$DB_ADMIN_PWD" < "$MYSQL_DIR"/secure_mysql.sql
+ mysql -u root --password="$DB_ADMIN_PWD" -e "SET PASSWORD FOR 'hirs_db'@'localhost' = PASSWORD('"$HIRS_DB_PWD"'); FLUSH PRIVILEGES;";
echo "**** Setting hirs_db pwd to $HIRS_DB_PWD ***"
fi
fi
@@ -219,7 +223,7 @@ create_hibernate_url () {
ALG=$1
db_username=$2
- if [ $ALG = "rsa" ]; then
+ if [ "$ALG" = "rsa" ]; then
CERT_PATH="/etc/hirs/certificates/HIRS/$RSA_PATH"
CERT_CHAIN="$CERT_PATH/HIRS_rsa_3k_sha384_Cert_Chain.pem"
CLIENT_DB_P12=$CERT_PATH/HIRS_db_client_rsa_3k_sha384.p12
@@ -241,7 +245,7 @@ keyStorePassword=$PKI_PASS&\
keyStore="$CLIENT_DB_P12" "
if [[ $(grep -c "hibernate.connection.url" $SPRING_PROP_FILE) -eq 0 ]]; then
- echo $CONNECTOR_URL >> $SPRING_PROP_FILE
+ echo "$CONNECTOR_URL" >> $SPRING_PROP_FILE
fi
}
@@ -255,5 +259,5 @@ set_hirs_db_pwd
create_hirs_db_with_tls
set_mysql_server_tls
set_mysql_client_tls
-create_hibernate_url $DB_ALG "hirs_db"
+create_hibernate_url "$DB_ALG" "hirs_db"
mysqld_reboot
diff --git a/package/linux/db/db_drop.sh b/package/linux/db/db_drop.sh
index f409f90e7..32607330d 100755
--- a/package/linux/db/db_drop.sh
+++ b/package/linux/db/db_drop.sh
@@ -7,7 +7,7 @@ LOG_FILE=/dev/null
DB_ADMIN_PWD=$1
#source /etc/hirs/aca/aca.properties;
-source $SCRIPT_DIR/mysql_util.sh
+source "$SCRIPT_DIR"/mysql_util.sh
source /etc/os-release
check_systemd
@@ -19,7 +19,7 @@ if [ "$EUID" -ne 0 ]
fi
# Setup distro specifc paths and variables
-if [ $ID = "ubuntu" ]; then
+if [ "$ID" = "ubuntu" ]; then
DB_SRV_CONF="/etc/mysql/mariadb.conf.d/50-server.cnf"
DB_CLIENT_CONF="/etc/mysql/mariadb.conf.d/50-client.cnf"
fi
@@ -32,16 +32,16 @@ fi
echo "dropping hirs_db database"
- mysql -u root --password=$DB_ADMIN_PWD -e "FLUSH HOSTS; FLUSH LOGS; FLUSH STATUS; FLUSH PRIVILEGES; FLUSH USER_RESOURCES"
- mysql -u root --password=$DB_ADMIN_PWD -e "DROP USER 'hirs_db'@'localhost';"
- mysql -u root --password=$DB_ADMIN_PWD -e "DROP DATABASE IF EXISTS hirs_db;"
+ mysql -u root --password="$DB_ADMIN_PWD" -e "FLUSH HOSTS; FLUSH LOGS; FLUSH STATUS; FLUSH PRIVILEGES; FLUSH USER_RESOURCES"
+ mysql -u root --password="$DB_ADMIN_PWD" -e "DROP USER 'hirs_db'@'localhost';"
+ mysql -u root --password="$DB_ADMIN_PWD" -e "DROP DATABASE IF EXISTS hirs_db;"
echo "hirs_db database and hirs_db user removed"
# reset the mysql root if the password was left in the properties fiel
-if [ ! -z $DB_ADMIN_PWD ]; then
+if [ -n "$DB_ADMIN_PWD" ]; then
echo "Resetting mysql root password to empty"
- mysql -u root --password=$DB_ADMIN_PWD -e "SET PASSWORD FOR "root@localhost" = PASSWORD('');"
+ mysql -u root --password="$DB_ADMIN_PWD" -e "SET PASSWORD FOR "root@localhost" = PASSWORD('');"
mysql -u "root" -e "FLUSH LOGS;"
else
echo "Note root password was NOT reset"
diff --git a/package/linux/db/mysql_util.sh b/package/linux/db/mysql_util.sh
index e16f0acc6..da62a7c67 100755
--- a/package/linux/db/mysql_util.sh
+++ b/package/linux/db/mysql_util.sh
@@ -33,7 +33,7 @@ check_systemd () {
# Check for mysql command line
check_mariadb_install () {
type mysql >/dev/null 2>&1 && installed=true || installed=false
- if [ $installed = true ]; then
+ if [ "$installed" = true ]; then
echo "mysql has been installed"
else
echo "mysql has NOT been installed, aborting install"
@@ -45,12 +45,12 @@ start_mysqlsd () {
PRINT_STATUS=$1
PROCESS="mysqld"
source /etc/os-release
- if [ $ID = "ubuntu" ]; then
+ if [ "$ID" = "ubuntu" ]; then
PROCESS="mariadb"
fi
# Make sure log file has correct permissions
chown -R mysql:mysql /var/lib/mysql/ >> "$LOG_FILE"
- if [ $DB_SERVICE = true ]; then
+ if [ "$DB_SERVICE" = true ]; then
systemctl is-active --quiet mariadb
if [[ $? -ne 0 ]]; then
echo "mariadb service not running , attempting to restart"
@@ -78,12 +78,12 @@ start_mysqlsd () {
check_mysql () {
PROCESS="mysqld"
source /etc/os-release
- if [ $ID = "ubuntu" ]; then
+ if [ "$ID" = "ubuntu" ]; then
PROCESS="mariadb"
fi
echo "Checking mysqld status..."
- if [ $DB_SERVICE = true ]; then
+ if [ "$DB_SERVICE" = true ]; then
systemctl is-active --quiet mariadb
if [[ $? -ne 0 ]]; then
echo "mariadb service not running , attempting to restart"
@@ -97,7 +97,7 @@ check_mysql () {
fi
fi
- if [ $DB_SERVICE = true ]; then
+ if [ "$DB_SERVICE" = true ]; then
systemctl is-active --quiet mariadb
if [[ $? -eq 0 ]]; then
echo "mariadb service started" | tee -a "$LOG_FILE";
@@ -124,7 +124,7 @@ fi
# Check for mysql root password , abort if not available
check_mysql_root () {
- if [ -z $HIRS_MYSQL_ROOT_PWD ]; then
+ if [ -z "$HIRS_MYSQL_ROOT_PWD" ]; then
if [ ! -f /etc/hirs/aca/aca.properties ]; then
echo "aca.properties does not exist." | tee -a "$LOG_FILE";
else
@@ -136,7 +136,7 @@ check_mysql_root () {
fi
# Allow user to enter password if not using env variabel or file
-if [ -z $DB_ADMIN_PWD ]; then
+if [ -z "$DB_ADMIN_PWD" ]; then
read -p "Enter mysql root password" DB_ADMIN_PWD
else
DB_ADMIN_PWD=$mysql_admin_password
@@ -156,7 +156,7 @@ $(mysql -u root -p$DB_ADMIN_PWD -e 'quit' &> /dev/null);
check_hirs_db_user () {
PRINT_STATUS=$1
-HIRS_DB_USER_EXISTS="$(mysql -uroot --password=$DB_ADMIN_PWD -sse "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'hirs_db')")"
+HIRS_DB_USER_EXISTS="$(mysql -uroot --password="$DB_ADMIN_PWD" -sse "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'hirs_db')")"
if [[ $HIRS_DB_USER_EXISTS == "1" ]]; then
if [[ $PRINT_STATUS == "-p" ]];then echo " hirs_db user exists" | tee -a "$LOG_FILE"; fi;
else
@@ -166,7 +166,7 @@ HIRS_DB_USER_EXISTS="$(mysql -uroot --password=$DB_ADMIN_PWD -sse "SELECT EXISTS
check_hirs_db () {
PRINT_STATUS=$1
-HIRS_DB_EXISTS="$(mysql -uroot --password=$DB_ADMIN_PWD -e "SHOW DATABASES" | grep hirs_db)"
+HIRS_DB_EXISTS="$(mysql -uroot --password="$DB_ADMIN_PWD" -e "SHOW DATABASES" | grep hirs_db)"
if [[ $HIRS_DB_EXISTS == "hirs_db" ]]; then
if [[ $PRINT_STATUS == "-p" ]];then echo " hirs_db database exists" | tee -a "$LOG_FILE"; fi;
else
@@ -187,7 +187,7 @@ check_db_cleared () {
else
echo " hirs_db user does not exist" | tee -a "$LOG_FILE";
fi
- HIRS_DB_EXISTS=`mysql -uroot -e "SHOW DATABASES" | grep hirs_db`
+ HIRS_DB_EXISTS=$(mysql -uroot -e "SHOW DATABASES" | grep hirs_db)
if [[ $HIRS_DB_EXISTS == "1" ]]; then
echo " hirs_db databse exists" | tee -a "$LOG_FILE";
else
@@ -200,7 +200,7 @@ $(mysql -u root -e 'quit' &> /dev/null);
if [ $? -eq 0 ]; then
HIRS_DB_USER_EXISTS="$(mysql -uroot -sse "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'hirs_db')")"
if [[ $HIRS_DB_USER_EXISTS == "1" ]]; then
- mysql -u root --password=$DB_ADMIN_PWD -e "DROP USER 'hirs_db'@'localhost';"
+ mysql -u root --password="$DB_ADMIN_PWD" -e "DROP USER 'hirs_db'@'localhost';"
echo "hirs_db user found and deleted"
fi
fi
@@ -209,7 +209,7 @@ $(mysql -u root -e 'quit' &> /dev/null);
clear_hirs_db () {
$(mysql -u root -e 'quit' &> /dev/null);
if [ $? -eq 0 ]; then
- mysql -u root --password=$DB_ADMIN_PWD -e "DROP DATABASE IF EXISTS hirs_db;"
+ mysql -u root --password="$DB_ADMIN_PWD" -e "DROP DATABASE IF EXISTS hirs_db;"
fi
}
@@ -232,18 +232,18 @@ mysqld_reboot () {
# reboot mysql server
PROCESS="mysqld"
source /etc/os-release
- if [ $ID = "ubuntu" ]; then
+ if [ "$ID" = "ubuntu" ]; then
PROCESS="mariadb"
fi
echo "Restarting Mariadb ...." | tee -a "$LOG_FILE";
- if [ $DB_SERVICE = true ]; then
+ if [ "$DB_SERVICE" = true ]; then
echo "Shutting down and restarting mysql service" | tee -a "$LOG_FILE";
systemctl stop mariadb >> "$LOG_FILE";
sleep 2
systemctl start mariadb >> "$LOG_FILE";
else # No systemd
echo "Shutting down and restarting mysql process" | tee -a "$LOG_FILE";
- mysql -u root --password=$DB_ADMIN_PWD -e "SHUTDOWN"
+ mysql -u root --password="$DB_ADMIN_PWD" -e "SHUTDOWN"
sleep 1
# Make sure mysql has stopped
if [[ $(pgrep -c $PROCESS) -ne 0 ]]; then
From 4f1e778ee39c05053a624f76b984c12183bd832e Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Tue, 24 Feb 2026 17:58:33 -0500
Subject: [PATCH 05/25] v3.1_issue_1090: Fixed a lot of tests. Removed a lot of
unused methods in the utils class.
---
.../config/spotbugs/spotbugs-exclude.xml | 4 -
...ionCertificateAuthorityRestController.java | 14 +-
...ttestationCertificateAuthorityService.java | 9 +-
...tationCertificateAuthorityServiceImpl.java | 8 +-
.../CertificateProcessingException.java | 4 +-
.../IdentityProcessingException.java | 4 +-
.../exceptions/UnexpectedServerException.java | 4 +-
.../CertificateRequestProcessor.java | 7 +-
.../provision/IdentityClaimProcessor.java | 6 +-
.../provision/helper/ProvisionUtils.java | 201 +----
...tationCertificateAuthorityServiceTest.java | 468 +++++++++++
.../AttestationCertificateAuthorityTest.java | 795 ------------------
12 files changed, 501 insertions(+), 1023 deletions(-)
create mode 100644 HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
delete mode 100644 HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java
diff --git a/HIRS_AttestationCA/config/spotbugs/spotbugs-exclude.xml b/HIRS_AttestationCA/config/spotbugs/spotbugs-exclude.xml
index acdcaa9b1..8641638f1 100644
--- a/HIRS_AttestationCA/config/spotbugs/spotbugs-exclude.xml
+++ b/HIRS_AttestationCA/config/spotbugs/spotbugs-exclude.xml
@@ -15,9 +15,5 @@
-
-
-
-
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
index ff991839b..e3ecf4801 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
@@ -19,17 +19,17 @@
@RestController
@RequestMapping("/HIRS_AttestationCA")
public class AttestationCertificateAuthorityRestController {
- private final AttestationCertificateAuthorityServiceImpl attestationCertificateAuthorityServiceImpl;
+ private final AttestationCertificateAuthorityService attestationCertificateAuthorityService;
/**
* Constructor.
*
- * @param attestationCertificateAuthorityServiceImpl Attestation Certificate Authority service
+ * @param attestationCertificateAuthorityService Attestation Certificate Authority service
*/
@Autowired
public AttestationCertificateAuthorityRestController(
- final AttestationCertificateAuthorityServiceImpl attestationCertificateAuthorityServiceImpl) {
- this.attestationCertificateAuthorityServiceImpl = attestationCertificateAuthorityServiceImpl;
+ final AttestationCertificateAuthorityService attestationCertificateAuthorityService) {
+ this.attestationCertificateAuthorityService = attestationCertificateAuthorityService;
}
/**
@@ -42,7 +42,7 @@ public AttestationCertificateAuthorityRestController(
@ResponseBody
@PostMapping(value = "/identity-claim-tpm2/process", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim) throws GeneralSecurityException {
- return this.attestationCertificateAuthorityServiceImpl.processIdentityClaimTpm2(identityClaim);
+ return this.attestationCertificateAuthorityService.processIdentityClaimTpm2(identityClaim);
}
/**
@@ -57,7 +57,7 @@ public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim)
@PostMapping(value = "/request-certificate-tpm2", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public byte[] processCertificateRequest(@RequestBody final byte[] certificateRequest)
throws GeneralSecurityException {
- return this.attestationCertificateAuthorityServiceImpl.processCertificateRequest(certificateRequest);
+ return this.attestationCertificateAuthorityService.processCertificateRequest(certificateRequest);
}
/**
@@ -68,6 +68,6 @@ public byte[] processCertificateRequest(@RequestBody final byte[] certificateReq
@ResponseBody
@GetMapping("/public-key")
public byte[] getLeafACACertPublicKey() {
- return this.attestationCertificateAuthorityServiceImpl.getLeafACACertPublicKey();
+ return this.attestationCertificateAuthorityService.getLeafACACertPublicKey();
}
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java
index 54a40c9ba..81727a0cd 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java
@@ -13,7 +13,7 @@ public interface AttestationCertificateAuthorityService {
* @param identityClaim a byte array representation of the identity claim
* @return a byte array representation of the identity claim response
*/
- byte[] processIdentityClaimTpm2(byte[] identityClaim) throws GeneralSecurityException;
+ byte[] processIdentityClaimTpm2(byte[] identityClaim);
/**
* Processes the provided certificate request.
@@ -23,4 +23,11 @@ public interface AttestationCertificateAuthorityService {
*/
byte[] processCertificateRequest(byte[] certificateRequest) throws GeneralSecurityException;
+
+ /**
+ * Retrieves the encoded public key of the leaf certificate.
+ *
+ * @return encoded public key of the leaf certificate
+ */
+ byte[] getLeafACACertPublicKey();
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceImpl.java
index 6b77a05d4..5ccab1685 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceImpl.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceImpl.java
@@ -3,6 +3,7 @@
import hirs.attestationca.persist.provision.CertificateRequestProcessor;
import hirs.attestationca.persist.provision.IdentityClaimProcessor;
import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.security.GeneralSecurityException;
@@ -22,6 +23,7 @@ public class AttestationCertificateAuthorityServiceImpl implements AttestationCe
* @param certificateRequestProcessor certificate request processor service
* @param identityClaimProcessor identity claim processor service
*/
+ @Autowired
public AttestationCertificateAuthorityServiceImpl(
final CertificateRequestProcessor certificateRequestProcessor,
final IdentityClaimProcessor identityClaimProcessor) {
@@ -35,7 +37,7 @@ public AttestationCertificateAuthorityServiceImpl(
* @param identityClaim a byte array representation of the identity claim
* @return processed identity claim response
*/
- public byte[] processIdentityClaimTpm2(final byte[] identityClaim) throws GeneralSecurityException {
+ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
return this.identityClaimProcessor.processIdentityClaimTpm2(identityClaim);
}
@@ -50,9 +52,9 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) throws
}
/**
- * Retrieves the encoded public key.
+ * Retrieves the encoded public key of the leaf certificate.
*
- * @return encoded public key
+ * @return encoded public key of the leaf certificate
*/
public byte[] getLeafACACertPublicKey() {
return this.certificateRequestProcessor.getLeafACACertificatePublicKey();
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/CertificateProcessingException.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/CertificateProcessingException.java
index 84d5eaa1f..49f1d23b1 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/CertificateProcessingException.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/CertificateProcessingException.java
@@ -1,9 +1,7 @@
package hirs.attestationca.persist.exceptions;
-import hirs.attestationca.persist.AttestationCertificateAuthorityServiceImpl;
-
/**
- * Generic exception thrown while a {@link AttestationCertificateAuthorityServiceImpl}
+ * Generic exception thrown when the the Attestation Certificate Authority Service
* is processing a newly created Attestation Certificate for a validated identity.
*/
public class CertificateProcessingException extends RuntimeException {
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/IdentityProcessingException.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/IdentityProcessingException.java
index 5b6cc5eec..27efa4728 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/IdentityProcessingException.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/IdentityProcessingException.java
@@ -1,9 +1,7 @@
package hirs.attestationca.persist.exceptions;
-import hirs.attestationca.persist.AttestationCertificateAuthorityServiceImpl;
-
/**
- * Generic exception thrown while a {@link AttestationCertificateAuthorityServiceImpl}
+ * Generic exception thrown when the Attestation Certificate Authority Service
* is processing a newly submitted Identity.
*/
public class IdentityProcessingException extends RuntimeException {
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/UnexpectedServerException.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/UnexpectedServerException.java
index 890f6c2af..59dbe2102 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/UnexpectedServerException.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/UnexpectedServerException.java
@@ -1,9 +1,7 @@
package hirs.attestationca.persist.exceptions;
-import hirs.attestationca.persist.AttestationCertificateAuthorityServiceImpl;
-
/**
- * Generic exception thrown when a {@link AttestationCertificateAuthorityServiceImpl}
+ * Generic exception thrown when the Attestation Certificate Authority Service
* encounters an unexpected condition that can't be handled.
*/
public class UnexpectedServerException extends RuntimeException {
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
index 309a299d3..bf013c0bf 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
@@ -37,7 +37,6 @@
@Service
@Log4j2
public class CertificateRequestProcessor extends AbstractProcessor {
-
private final SupplyChainValidationService supplyChainValidationService;
private final CertificateRepository certificateRepository;
private final DeviceRepository deviceRepository;
@@ -53,7 +52,7 @@ public class CertificateRequestProcessor extends AbstractProcessor {
* @param deviceRepository database connector for Devices.
* @param privateKey private key used for communication authentication
* @param acaCertificate object used to create credential
- * @param validDays int for the time in which a certificate is valid.
+ * @param certificateValidityInDays int for the time in which a certificate is valid.
* @param tpm2ProvisionerStateRepository db connector for provisioner state.
* @param policyRepository db connector for policies.
*/
@@ -64,10 +63,10 @@ public CertificateRequestProcessor(final SupplyChainValidationService supplyChai
final PrivateKey privateKey,
@Qualifier("leafACACert") final X509Certificate acaCertificate,
@Value("${aca.current.public.key.algorithm}") final String publicKeyAlgorithmStr,
- @Value("${aca.certificates.validity}") final int validDays,
+ @Value("${aca.certificates.validity}") final int certificateValidityInDays,
final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
final PolicyRepository policyRepository) {
- super(privateKey, validDays);
+ super(privateKey, certificateValidityInDays);
this.supplyChainValidationService = supplyChainValidationService;
this.certificateRepository = certificateRepository;
this.deviceRepository = deviceRepository;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
index 89272bca6..3dcaa6c46 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
@@ -144,9 +144,9 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
log.info("Identity Claim has been received and is ready to be processed");
if (ArrayUtils.isEmpty(identityClaim)) {
- log.error("Identity claim empty throwing exception.");
- throw new IllegalArgumentException("The IdentityClaim sent by the client"
- + " cannot be null or empty.");
+ final String errorMsg = "The IdentityClaim sent by the client cannot be null or empty.";
+ log.error(errorMsg);
+ throw new IllegalArgumentException(errorMsg);
}
final PolicyRepository policyRepository = this.getPolicyRepository();
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index 4080e2234..65cf49d6c 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -4,19 +4,11 @@
import com.google.protobuf.InvalidProtocolBufferException;
import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
import hirs.attestationca.persist.enums.PublicKeyAlgorithm;
-import hirs.attestationca.persist.exceptions.CertificateProcessingException;
import hirs.attestationca.persist.exceptions.IdentityProcessingException;
import hirs.attestationca.persist.exceptions.UnexpectedServerException;
-import hirs.structs.converters.SimpleStructBuilder;
-import hirs.structs.elements.aca.SymmetricAttestation;
-import hirs.structs.elements.tpm.EncryptionScheme;
-import hirs.structs.elements.tpm.IdentityRequest;
-import hirs.structs.elements.tpm.SymmetricKey;
-import hirs.structs.elements.tpm.SymmetricKeyParams;
import hirs.utils.HexUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.binary.Hex;
-import org.apache.commons.lang3.ArrayUtils;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import javax.crypto.BadPaddingException;
@@ -39,7 +31,6 @@
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.cert.CertificateEncodingException;
@@ -266,97 +257,6 @@ public static PublicKey assembleECCPublicKey() {
}
}
- /**
- * Will attempt to decrypt the asymmetric blob that originated from an
- * {@link IdentityRequest} using the cipher transformation.
- *
- * @param asymmetricBlob to be decrypted
- * @param scheme to decrypt with
- * @param privateKey cipher private key
- * @return decrypted blob
- */
- public static byte[] decryptAsymmetricBlob(final byte[] asymmetricBlob,
- final EncryptionScheme scheme,
- final PrivateKey privateKey) {
- try {
- // create a cipher from the specified transformation
- Cipher cipher = Cipher.getInstance(scheme.toString());
-
- if (scheme == EncryptionScheme.OAEP) {
- OAEPParameterSpec spec =
- new OAEPParameterSpec("Sha1", "MGF1", MGF1ParameterSpec.SHA1,
- new PSource.PSpecified("".getBytes(StandardCharsets.UTF_8)));
-
- cipher.init(Cipher.PRIVATE_KEY, privateKey, spec);
- } else {
- // initialize the cipher to decrypt using the ACA private key.
- cipher.init(Cipher.DECRYPT_MODE, privateKey);
- }
-
- cipher.update(asymmetricBlob);
-
- return cipher.doFinal();
- } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException
- | BadPaddingException | IllegalBlockSizeException
- | InvalidAlgorithmParameterException e) {
- throw new IdentityProcessingException(
- "Encountered error while decrypting asymmetric blob of an identity request: "
- + e.getMessage(), e);
- }
- }
-
- /**
- * Will attempt to decrypt the symmetric blob that originated from an
- * {@link IdentityRequest} using the specified symmetric key
- * and cipher transformation.
- *
- * @param symmetricBlob to be decrypted
- * @param symmetricKey to use to decrypt
- * @param iv to use with decryption cipher
- * @param transformation of the cipher
- * @return decrypted symmetric blob
- */
- public static byte[] decryptSymmetricBlob(final byte[] symmetricBlob, final byte[] symmetricKey,
- final byte[] iv, final String transformation) {
- try {
- // create a cipher from the specified transformation
- Cipher cipher = Cipher.getInstance(transformation);
-
- // generate a key specification to initialize the cipher
- SecretKeySpec keySpec = new SecretKeySpec(symmetricKey, "AES");
-
- // initialize the cipher to decrypt using the symmetric key
- cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
-
- // decrypt the symmetric blob
- return cipher.doFinal(symmetricBlob);
- } catch (IllegalBlockSizeException | InvalidKeyException | NoSuchAlgorithmException
- | BadPaddingException | NoSuchPaddingException
- | InvalidAlgorithmParameterException exception) {
- log.error("Encountered error while decrypting symmetric blob of an identity request: {}",
- exception.getMessage(), exception);
- }
-
- return new byte[0];
- }
-
- /**
- * Generates a symmetric key.
- *
- * @return a symmetric key
- */
- public static SymmetricKey generateSymmetricKey() {
- // create a session key for the CA contents
- byte[] responseSymmetricKey =
- generateRandomBytes(DEFAULT_IV_SIZE);
-
- // create a symmetric key struct for the CA contents
- return new SimpleStructBuilder<>(SymmetricKey.class)
- .set("algorithmId", SymmetricKey.ALGORITHM_AES)
- .set("encryptionScheme", SymmetricKey.SCHEME_CBC)
- .set("key", responseSymmetricKey).build();
- }
-
/**
* Performs the first step of the TPM 2.0 identity claim process. Takes an ek, ak, and secret
* and then generates a seed that is used to generate AES and HMAC keys. Parses the ak name.
@@ -403,11 +303,11 @@ public static ByteString tpm20MakeCredential(final RSAPublicKey ek, final RSAPub
startpos = 1;
}
System.arraycopy(akModTemp, startpos, akMod, 0, DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES);
- byte[] akName = ProvisionUtils.generateAkName(akMod);
+ byte[] akName = generateAkName(akMod);
// generate AES and HMAC keys from seed
- byte[] aesKey = ProvisionUtils.cryptKDFa(seed, "STORAGE", akName, AES_KEY_LENGTH_BYTES);
- byte[] hmacKey = ProvisionUtils.cryptKDFa(seed, "INTEGRITY", null, HMAC_KEY_LENGTH_BYTES);
+ byte[] aesKey = cryptKDFa(seed, "STORAGE", akName, AES_KEY_LENGTH_BYTES);
+ byte[] hmacKey = cryptKDFa(seed, "INTEGRITY", null, HMAC_KEY_LENGTH_BYTES);
// use two bytes to add a size prefix on secret
ByteBuffer b;
@@ -439,7 +339,7 @@ public static ByteString tpm20MakeCredential(final RSAPublicKey ek, final RSAPub
byte[] topSize = b.array();
// return ordered blob of assembled credentials
- byte[] bytesToReturn = ProvisionUtils.assembleCredential(topSize, integrity, encSecret, encSeed);
+ byte[] bytesToReturn = assembleCredential(topSize, integrity, encSecret, encSeed);
return ByteString.copyFrom(bytesToReturn);
} catch (BadPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException
@@ -451,99 +351,6 @@ public static ByteString tpm20MakeCredential(final RSAPublicKey ek, final RSAPub
}
}
- /**
- * Generate asymmetric contents part of the identity response.
- *
- * @param identityKey identity requests symmetric contents, otherwise, the identity proof
- * @param sessionKey identity response session key
- * @param publicKey of the EK certificate contained within the identity proof
- * @return encrypted asymmetric contents
- */
- public static byte[] generateAsymmetricContents(final byte[] identityKey,
- final byte[] sessionKey,
- final PublicKey publicKey) {
- try {
- // create a SHA1 digest of the identity key
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- md.update(identityKey);
-
- // generate the digest
- byte[] identityDigest = md.digest();
-
- // combine the session key with the digest of the identity key
- byte[] asymmetricContents = ArrayUtils.addAll(sessionKey, identityDigest);
-
- // encrypt the asymmetric contents and return
- OAEPParameterSpec oaepSpec =
- new OAEPParameterSpec("Sha1", "MGF1", MGF1ParameterSpec.SHA1,
- new PSource.PSpecified("TCPA".getBytes(StandardCharsets.UTF_8)));
-
- // initialize the asymmetric cipher using the default OAEP transformation
- Cipher cipher = Cipher.getInstance(EncryptionScheme.OAEP.toString());
-
- // initialize the cipher using the public spec with the additional OAEP specification
- cipher.init(Cipher.PUBLIC_KEY, publicKey, oaepSpec);
-
- return cipher.doFinal(asymmetricContents);
- } catch (NoSuchAlgorithmException | IllegalBlockSizeException | NoSuchPaddingException
- | InvalidKeyException | BadPaddingException
- | InvalidAlgorithmParameterException e) {
- throw new CertificateProcessingException(
- "Encountered error while generating ACA session key: " + e.getMessage(), e);
- }
- }
-
- /**
- * Generate the Identity Response using the identity credential and the session key.
- *
- * @param credential the identity credential
- * @param symmetricKey generated session key for this request/response chain
- * @return identity response for an identity request
- */
- public static SymmetricAttestation generateAttestation(final X509Certificate credential,
- final SymmetricKey symmetricKey) {
- try {
- // initialize the symmetric cipher
- Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
-
- // generate a key specification to initialize the cipher
- SecretKeySpec keySpec = new SecretKeySpec(symmetricKey.getKey(), "AES");
-
- // fill IV with random bytes
- byte[] credentialIV = generateRandomBytes(DEFAULT_IV_SIZE);
-
- // create IV encryption parameter specification
- IvParameterSpec ivParameterSpec = new IvParameterSpec(credentialIV);
-
- // initialize the cipher to decrypt using the symmetric key
- aesCipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec);
-
- // encrypt the credential
- byte[] encryptedCredential = aesCipher.doFinal(credential.getEncoded());
-
- // prepend the IV to the encrypted credential
- byte[] credentialBytes = ArrayUtils.addAll(credentialIV, encryptedCredential);
-
- // create attestation for identity response that contains the credential
-
- return new SimpleStructBuilder<>(SymmetricAttestation.class)
- .set("credential", credentialBytes)
- .set("algorithm",
- new SimpleStructBuilder<>(SymmetricKeyParams.class)
- .set("algorithmId", SymmetricKeyParams.ALGORITHM_AES)
- .set("encryptionScheme",
- SymmetricKeyParams.SCHEME_CBC_PKCS5PADDING)
- .set("signatureScheme", 0).build()).build();
-
- } catch (BadPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException
- | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException
- | CertificateEncodingException exception) {
- throw new CertificateProcessingException(
- "Encountered error while generating Identity Response: "
- + exception.getMessage(), exception);
- }
- }
-
/**
* Assembles a credential blob.
*
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
new file mode 100644
index 000000000..e138eddd3
--- /dev/null
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
@@ -0,0 +1,468 @@
+package hirs.attestationca.persist;
+
+import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
+import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
+import hirs.attestationca.persist.provision.AbstractProcessor;
+import hirs.attestationca.persist.provision.CertificateRequestProcessor;
+import hirs.attestationca.persist.provision.IdentityClaimProcessor;
+import hirs.attestationca.persist.provision.helper.IssuedCertificateAttributeHelper;
+import hirs.attestationca.persist.provision.helper.ProvisionUtils;
+import hirs.structs.elements.tpm.AsymmetricPublicKey;
+import hirs.structs.elements.tpm.IdentityProof;
+import hirs.structs.elements.tpm.StorePubKey;
+import hirs.utils.HexUtils;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.GeneralNames;
+import org.bouncycastle.asn1.x509.TBSCertificate;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+/**
+ *
+ */
+public class AttestationCertificateAuthorityServiceTest {
+ private static final String EK_PUBLIC_PATH = "/tpm2/ek.pub";
+
+ private static final String AK_PUBLIC_PATH = "/tpm2/ak.pub";
+
+ private static final String AK_NAME_PATH = "/tpm2/ak.name";
+
+ private static final String EK_MODULUS_HEX = "a3 b5 c2 1c 57 be 40 c4 3c 78 90 0d 00 81 01 78"
+ + "13 ca 02 ec b6 75 89 60 ca 60 9b 10 b6 b4 d0 0b"
+ + "4d e4 68 ad 01 a6 91 e2 56 20 5e cf 16 fe 77 ae"
+ + "1f 13 d7 ac a1 91 0b 68 f6 07 cf c2 4b 5e c1 2c"
+ + "4c fe 3a c9 62 7e 10 02 5b 33 c8 c2 1a cd 2e 7f"
+ + "dd 7c 43 ac a9 5f b1 d6 07 56 4f 72 9b 0a 00 6c"
+ + "f6 8d 23 a1 84 ca c1 7f 5a 8b ef 0e 23 11 90 00"
+ + "30 f2 99 e9 94 59 c6 b0 fe b2 5c 0c c7 b4 76 69"
+ + "6c f1 b7 d8 e5 60 d6 61 9f ab 7c 17 ce a4 74 6d"
+ + "8c cd e6 9e 6e bb 64 52 a7 c3 bf ac 07 e8 5e 3e"
+ + "ae eb dc c5 95 37 26 6a 5d a6 a2 12 52 fa 03 43"
+ + "b2 62 2d 87 8c a7 06 8f d6 3f 63 b6 2d 73 c4 9d"
+ + "9d d6 55 0e bb db b1 eb dd c5 4b 8f c3 17 cb 3b"
+ + "c3 bf f6 7f 13 44 de 8e d7 b9 f1 a7 15 56 8f 6c"
+ + "cd f2 4c 86 99 39 19 88 d3 4a 2f 38 c4 c4 37 39"
+ + "85 6f 41 98 19 14 a4 1f 95 bc 04 ef 74 c2 0d f3";
+
+ private static final String AK_MODULUS_HEX = "d7 c9 f0 e3 ac 1b 4a 1e 3c 9d 2d 57 02 e9 2a 93"
+ + "b0 c0 e1 50 af e4 61 11 31 73 a1 96 b8 d6 d2 1c"
+ + "40 40 c8 a6 46 a4 10 4b d1 06 74 32 f6 e3 8a 55"
+ + "1e 03 c0 3e cc 75 04 c6 44 88 b6 ad 18 c9 45 65"
+ + "0d be c5 45 22 bd 24 ad 32 8c be 83 a8 9b 1b d9"
+ + "e0 c8 d9 ec 14 67 55 1b fe 68 dd c7 f7 33 e4 cd"
+ + "87 bd ba 9a 07 e7 74 eb 57 ef 80 9c 6d ee f9 35"
+ + "52 67 36 e2 53 98 46 a5 4e 8f 17 41 8d ff eb bb"
+ + "9c d2 b4 df 57 f8 7f 31 ef 2e 2d 6e 06 7f 05 ed"
+ + "3f e9 6f aa b4 b7 5a f9 6d ba ff 2b 5e f7 c1 05"
+ + "90 68 1f b6 4b 38 67 f7 92 d8 73 51 6e 08 19 ad"
+ + "ca 35 48 a7 c1 fb cb 01 9a 28 03 c9 fe bb 49 2f"
+ + "88 3f a1 e7 a8 69 f0 f8 e8 78 db d3 6d c5 80 8d"
+ + "c2 e4 8a af 4b c2 ac 48 2a 44 63 6e 39 b0 8f dd"
+ + "e4 b3 a3 f9 2a b1 c8 d9 3d 6b c4 08 b0 16 c4 e7"
+ + "c7 2f f5 94 c6 43 3e ee 9b 8a da e7 31 d1 54 dd";
+
+ private static final String AK_NAME_HEX = "00 0b 6e 8f 79 1c 7e 16 96 1b 11 71 65 9c e0 cd"
+ + "ae 0d 4d aa c5 41 be 58 89 74 67 55 96 c2 5e 38"
+ + "e2 94";
+
+ private AutoCloseable mocks;
+
+ private KeyPair keyPair;
+
+ @InjectMocks
+ private AttestationCertificateAuthorityServiceImpl attestationCertificateAuthorityService;
+
+ private AccessAbstractProcessor abstractProcessor;
+
+ @Mock
+ private CertificateRequestProcessor certificateRequestProcessor;
+
+ @Mock
+ private IdentityClaimProcessor identityClaimProcessor;
+
+ @BeforeEach
+ public void setupTests() throws NoSuchAlgorithmException {
+ // Initializes mocks before each test
+ mocks = MockitoAnnotations.openMocks(this);
+
+ final int keySize = 2048;
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+ keyPairGenerator.initialize(keySize);
+ keyPair = keyPairGenerator.generateKeyPair();
+ }
+
+ @AfterEach
+ public void afterEach() throws Exception {
+ if (mocks != null) {
+ mocks.close();
+ }
+ }
+
+ /**
+ * Tests {@link AttestationCertificateAuthorityService#processIdentityClaimTpm2(byte[])}
+ * where the byte array is null or empty. Expects an illegal argument exception to be thrown.
+ *
+ * @throws GeneralSecurityException if any issues arise while processing the identity claim request
+ */
+ @Test
+ public void testProcessIdentityClaimTpm2NullOrEmptyRequest() throws GeneralSecurityException {
+ // test 1: test null identity claim
+ when(attestationCertificateAuthorityService.processIdentityClaimTpm2(null)).thenThrow(
+ new IllegalArgumentException("The IdentityClaim sent by the client cannot be null or empty."));
+
+ // Act & Assert: Verify that the exception is thrown
+ IllegalArgumentException illegalArgumentException = assertThrows(IllegalArgumentException.class,
+ () -> attestationCertificateAuthorityService.processIdentityClaimTpm2(null));
+
+ assertEquals("The IdentityClaim sent by the client cannot be null or empty.",
+ illegalArgumentException.getMessage());
+
+ // test 2: test empty identity claim
+
+ // initialize an empty byte array
+ final byte[] emptyArr = {};
+
+ when(attestationCertificateAuthorityService.processIdentityClaimTpm2(emptyArr)).thenThrow(
+ new IllegalArgumentException("The IdentityClaim sent by the client cannot be null or empty."));
+
+ // Act & Assert: Verify that the exception is thrown
+ illegalArgumentException = assertThrows(IllegalArgumentException.class,
+ () -> attestationCertificateAuthorityService.processIdentityClaimTpm2(emptyArr));
+
+ assertEquals("The IdentityClaim sent by the client cannot be null or empty.",
+ illegalArgumentException.getMessage());
+ }
+
+ /**
+ * Tests {@link AttestationCertificateAuthorityService#processCertificateRequest(byte[])}
+ * where the byte array is null or empty. Expects an illegal argument exception to be thrown.
+ *
+ * @throws GeneralSecurityException if any issues arise while processing the certificate request
+ */
+ @Test
+ public void testProcessCertificateRequestNullOrEmptyRequest() throws GeneralSecurityException {
+ // test 1: test null certificate request
+
+ when(attestationCertificateAuthorityService.processCertificateRequest(null)).thenThrow(
+ new IllegalArgumentException("The CertificateRequest sent by the client cannot be null or empty."));
+
+ // Act & Assert: Verify that the exception is thrown
+ IllegalArgumentException illegalArgumentException = assertThrows(IllegalArgumentException.class,
+ () -> attestationCertificateAuthorityService.processCertificateRequest(null));
+
+ assertEquals("The CertificateRequest sent by the client cannot be null or empty.",
+ illegalArgumentException.getMessage());
+
+ // test 2: test empty certificate request
+
+ // initialize an empty byte array
+ final byte[] emptyArr = {};
+
+ when(attestationCertificateAuthorityService.processCertificateRequest(emptyArr)).thenThrow(
+ new IllegalArgumentException("The CertificateRequest sent by the client cannot be null or empty."));
+
+ illegalArgumentException = assertThrows(IllegalArgumentException.class,
+ () -> attestationCertificateAuthorityService.processCertificateRequest(emptyArr));
+
+ assertEquals("The CertificateRequest sent by the client cannot be null or empty.",
+ illegalArgumentException.getMessage());
+ }
+
+ /**
+ * Tests {@link AttestationCertificateAuthorityService#getLeafACACertPublicKey()}.
+ */
+ @Test
+ public void testGetPublicKey() {
+
+ // setup
+
+ // encoded byte array to be returned by public key
+ final byte[] desiredByteArray = new byte[]{0, 1, 0, 1, 0};
+
+ // create mocks for testing
+ X509Certificate mockCertificate = mock(X509Certificate.class);
+ PublicKey mockPublicKey = mock(PublicKey.class);
+
+ // Mock the behavior of getPublicKey().getEncoded() to return the desired byte array
+ when(mockCertificate.getPublicKey()).thenReturn(mockPublicKey);
+ when(mockPublicKey.getEncoded()).thenReturn(desiredByteArray);
+
+ when(attestationCertificateAuthorityService.getLeafACACertPublicKey()).thenReturn(
+ mockCertificate.getPublicKey().getEncoded());
+
+ // Test: Call the service method and assert the return value
+ byte[] actualByteArray = attestationCertificateAuthorityService.getLeafACACertPublicKey();
+
+ // Assert that the byte arrays match
+ assertArrayEquals(desiredByteArray, actualByteArray);
+ }
+
+ /**
+ * Tests {@link ProvisionUtils#assembleRSAPublicKey(byte[])}.
+ */
+ @Test
+ public void testAssemblePublicKeyUsingByteArray() {
+ // obtain the expected modulus from the existing public key
+ final BigInteger modulus = ((RSAPublicKey) keyPair.getPublic()).getModulus();
+
+ // perform test
+ RSAPublicKey publicKey = (RSAPublicKey) ProvisionUtils.assembleRSAPublicKey(modulus.toByteArray());
+
+ // assert that the exponent and the modulus are the same. the exponents should be the well
+ // known prime, 101
+ final int radix = 16;
+ assertEquals(new BigInteger("010001", radix), publicKey.getPublicExponent());
+ assertEquals(publicKey.getModulus(), modulus);
+ }
+
+ /**
+ * Tests parsing the EK from the TPM2 output file.
+ *
+ * @throws URISyntaxException incorrect resource path
+ * @throws IOException unable to read from file
+ */
+ @Test
+ public void testParseEk() throws URISyntaxException, IOException {
+ Path ekPath = Paths.get(Objects.requireNonNull(getClass().getResource(EK_PUBLIC_PATH)).toURI());
+
+ byte[] ekFile = Files.readAllBytes(ekPath);
+
+ RSAPublicKey ek = ProvisionUtils.parseRSAKeyFromPublicDataSegment(ekFile);
+ final int radix = 16;
+ assertEquals(new BigInteger("010001", radix), ek.getPublicExponent());
+
+ byte[] mod = ek.getModulus().toByteArray();
+ // big integer conversion is signed so it can add a 0 byte
+ if (mod[0] == 0) {
+ byte[] tmp = new byte[mod.length - 1];
+ System.arraycopy(mod, 1, tmp, 0, mod.length - 1);
+ mod = tmp;
+ }
+ String hex = HexUtils.byteArrayToHexString(mod);
+ String realMod = EK_MODULUS_HEX.replaceAll("\\s+", "");
+ assertEquals(realMod, hex);
+ }
+
+ /**
+ * Tests parsing the AK public key from the TPM2 output file.
+ *
+ * @throws URISyntaxException incorrect resource path
+ * @throws IOException unable to read from file
+ */
+ @Test
+ public void testParseAk() throws URISyntaxException, IOException {
+ Path akPath = Paths.get(Objects.requireNonNull(getClass().getResource(AK_PUBLIC_PATH)).toURI());
+
+ byte[] akFile = Files.readAllBytes(akPath);
+
+ RSAPublicKey ak = ProvisionUtils.parseRSAKeyFromPublicDataSegment(akFile);
+ final int radix = 16;
+ assertEquals(new BigInteger("010001", radix), ak.getPublicExponent());
+
+ byte[] mod = ak.getModulus().toByteArray();
+ // big integer conversion is signed so it can add a 0 byte
+ if (mod[0] == 0) {
+ byte[] tmp = new byte[mod.length - 1];
+ System.arraycopy(mod, 1, tmp, 0, mod.length - 1);
+ mod = tmp;
+ }
+ String hex = HexUtils.byteArrayToHexString(mod);
+ String realMod = AK_MODULUS_HEX.replaceAll("\\s+", "");
+ assertEquals(realMod, hex);
+ }
+
+ /**
+ * Tests {@link AttestationCertificateAuthorityService#
+ * AttestationCertificateAuthority(SupplyChainValidationService, PrivateKey,
+ * X509Certificate, StructConverter, CertificateManager, DeviceRegister, int,
+ * DeviceManager, DBManager)}.
+ *
+ * @throws Exception during subject alternative name checking if cert formatting is bad
+ */
+ @Test
+ public void testGenerateCredential() throws Exception {
+ // test variables
+ final String identityProofLabelString = "label";
+ byte[] identityProofLabel = identityProofLabelString.getBytes(StandardCharsets.UTF_8);
+ byte[] modulus = ((RSAPublicKey) keyPair.getPublic()).getModulus().toByteArray();
+ int validDays = 1;
+
+ // create mocks for testing
+ IdentityProof identityProof = mock(IdentityProof.class);
+ AsymmetricPublicKey asymmetricPublicKey = mock(AsymmetricPublicKey.class);
+ StorePubKey storePubKey = mock(StorePubKey.class);
+ X509Certificate acaCertificate = createSelfSignedCertificate(keyPair);
+
+ // assign ACA fields
+ ReflectionTestUtils.setField(attestationCertificateAuthorityService, "validDays", validDays);
+ ReflectionTestUtils.setField(attestationCertificateAuthorityService, "acaCertificate", acaCertificate);
+
+ // prepare identity proof interactions
+ when(identityProof.getLabel()).thenReturn(identityProofLabel);
+
+ // perform the test
+ X509Certificate certificate = abstractProcessor.accessGenerateCredential(keyPair.getPublic(),
+ null,
+ new LinkedList<>(),
+ "exampleIdLabel",
+ acaCertificate);
+
+ // grab the modulus from the generate certificate
+ byte[] resultMod = ((RSAPublicKey) certificate.getPublicKey()).getModulus().toByteArray();
+
+ // today and tomorrow, when the certificate should be valid for
+ Calendar today = Calendar.getInstance();
+ Calendar tomorrow = Calendar.getInstance();
+ tomorrow.add(Calendar.DATE, 1);
+
+ // validate the certificate
+ assertTrue(certificate.getIssuerX500Principal().toString().contains("CN=TEST"));
+ assertTrue(certificate.getIssuerX500Principal().toString().contains("OU=TEST"));
+ assertTrue(certificate.getIssuerX500Principal().toString().contains("O=TEST"));
+ assertTrue(certificate.getIssuerX500Principal().toString().contains("C=TEST"));
+
+ // validate the format of the subject and subject alternative name
+ assertEquals("", certificate.getSubjectX500Principal().getName());
+ assertEquals("exampleIdLabel",
+ ((X500Name) GeneralNames.fromExtensions(((TBSCertificate.getInstance(
+ certificate.getTBSCertificate()).getExtensions())), Extension.
+ subjectAlternativeName).getNames()[0].getName()).getRDNs(
+ IssuedCertificateAttributeHelper.TCPA_AT_TPM_ID_LABEL)[0].getFirst()
+ .getValue().toString());
+
+ assertArrayEquals(modulus, resultMod);
+
+ // obtain the expiration dates from the certificate
+ Calendar beforeDate = Calendar.getInstance();
+ Calendar afterDate = Calendar.getInstance();
+ beforeDate.setTime(certificate.getNotBefore());
+ afterDate.setTime(certificate.getNotAfter());
+
+ // assert the dates are set correctly
+ assertEquals(today.get(Calendar.DATE), beforeDate.get(Calendar.DATE));
+ assertEquals(tomorrow.get(Calendar.DATE), afterDate.get(Calendar.DATE));
+
+ // validate mock interactions
+ verifyNoMoreInteractions(identityProof, asymmetricPublicKey, storePubKey);
+ }
+
+ /**
+ * Creates a self-signed X.509 public-key certificate.
+ *
+ * @param pair KeyPair to create the cert for
+ * @return self-signed X509Certificate
+ */
+ private X509Certificate createSelfSignedCertificate(final KeyPair pair) {
+ Security.addProvider(new BouncyCastleProvider());
+ final int timeRange = 10000;
+ X509Certificate cert = null;
+ try {
+ X500Name issuerName = new X500Name("CN=TEST2, OU=TEST2, O=TEST2, C=TEST2");
+ X500Name subjectName = new X500Name("CN=TEST, OU=TEST, O=TEST, C=TEST");
+ BigInteger serialNumber = BigInteger.ONE;
+ Date notBefore = new Date(System.currentTimeMillis() - timeRange);
+ Date notAfter = new Date(System.currentTimeMillis() + timeRange);
+ X509v3CertificateBuilder builder =
+ new JcaX509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter,
+ subjectName, pair.getPublic());
+ ContentSigner signer =
+ new JcaContentSignerBuilder("SHA256WithRSA").setProvider("BC").build(
+ pair.getPrivate());
+ return new JcaX509CertificateConverter().setProvider("BC").getCertificate(
+ builder.build(signer));
+ } catch (Exception e) {
+ fail("Exception occurred while creating a cert", e);
+ }
+ return cert;
+ }
+
+
+ /**
+ * This internal class handles setup for testing the function
+ * generateCredential() from class AbstractProcessor. Because the
+ * function is Protected and in a different package than the test,
+ * it cannot be accessed directly.
+ */
+ @Nested
+ public class AccessAbstractProcessor extends AbstractProcessor {
+
+ /**
+ * Constructor.
+ *
+ * @param privateKey the private key of the ACA
+ * @param validDays int for the time in which a certificate is valid.
+ */
+ public AccessAbstractProcessor(final PrivateKey privateKey,
+ final int validDays) {
+ super(privateKey, validDays);
+ }
+
+ /**
+ * Public wrapper for the protected function generateCredential(), to access for testing.
+ *
+ * @param publicKey cannot be null
+ * @param endorsementCredential the endorsement credential
+ * @param platformCredentials the set of platform credentials
+ * @param deviceName The host name used in the subject alternative name
+ * @param acaCertificate the aca certificate
+ * @return the generated X509 certificate
+ */
+ public X509Certificate accessGenerateCredential(final PublicKey publicKey,
+ final EndorsementCredential endorsementCredential,
+ final List platformCredentials,
+ final String deviceName,
+ final X509Certificate acaCertificate) {
+
+ return generateCredential(publicKey,
+ endorsementCredential,
+ platformCredentials,
+ deviceName,
+ acaCertificate);
+ }
+ }
+
+}
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java
deleted file mode 100644
index 8bebef547..000000000
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java
+++ /dev/null
@@ -1,795 +0,0 @@
-package hirs.attestationca.persist;
-
-import com.google.protobuf.ByteString;
-import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
-import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
-import hirs.attestationca.persist.provision.AbstractProcessor;
-import hirs.attestationca.persist.provision.helper.IssuedCertificateAttributeHelper;
-import hirs.attestationca.persist.provision.helper.ProvisionUtils;
-import hirs.structs.elements.aca.SymmetricAttestation;
-import hirs.structs.elements.tpm.AsymmetricPublicKey;
-import hirs.structs.elements.tpm.EncryptionScheme;
-import hirs.structs.elements.tpm.IdentityProof;
-import hirs.structs.elements.tpm.StorePubKey;
-import hirs.structs.elements.tpm.SymmetricKey;
-import hirs.utils.HexUtils;
-import org.apache.commons.codec.binary.Hex;
-import org.apache.commons.lang3.ArrayUtils;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.GeneralNames;
-import org.bouncycastle.asn1.x509.TBSCertificate;
-import org.bouncycastle.cert.X509v3CertificateBuilder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
-import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.operator.ContentSigner;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-import org.springframework.test.util.ReflectionTestUtils;
-
-import javax.crypto.Cipher;
-import javax.crypto.KeyGenerator;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.OAEPParameterSpec;
-import javax.crypto.spec.PSource;
-import javax.crypto.spec.SecretKeySpec;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Security;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.MGF1ParameterSpec;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import java.util.Random;
-
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-/**
- * Test suite for {@link AttestationCertificateAuthorityServiceImpl}.
- */
-@TestInstance(TestInstance.Lifecycle.PER_CLASS) // needed to use non-static BeforeAll
-public class AttestationCertificateAuthorityTest {
-
- // length of IV used in PKI
- private static final int ENCRYPTION_IV_LEN = 16;
- // length of secret key used in PKI
- private static final int SECRETKEY_LEN = 128;
- private static final String EK_PUBLIC_PATH = "/tpm2/ek.pub";
- private static final String AK_PUBLIC_PATH = "/tpm2/ak.pub";
- private static final String AK_NAME_PATH = "/tpm2/ak.name";
- private static final String TEST_NONCE_BLOB_PATH = "test/nonce.blob";
- private static final String EK_MODULUS_HEX = "a3 b5 c2 1c 57 be 40 c4 3c 78 90 0d 00 81 01 78"
- + "13 ca 02 ec b6 75 89 60 ca 60 9b 10 b6 b4 d0 0b"
- + "4d e4 68 ad 01 a6 91 e2 56 20 5e cf 16 fe 77 ae"
- + "1f 13 d7 ac a1 91 0b 68 f6 07 cf c2 4b 5e c1 2c"
- + "4c fe 3a c9 62 7e 10 02 5b 33 c8 c2 1a cd 2e 7f"
- + "dd 7c 43 ac a9 5f b1 d6 07 56 4f 72 9b 0a 00 6c"
- + "f6 8d 23 a1 84 ca c1 7f 5a 8b ef 0e 23 11 90 00"
- + "30 f2 99 e9 94 59 c6 b0 fe b2 5c 0c c7 b4 76 69"
- + "6c f1 b7 d8 e5 60 d6 61 9f ab 7c 17 ce a4 74 6d"
- + "8c cd e6 9e 6e bb 64 52 a7 c3 bf ac 07 e8 5e 3e"
- + "ae eb dc c5 95 37 26 6a 5d a6 a2 12 52 fa 03 43"
- + "b2 62 2d 87 8c a7 06 8f d6 3f 63 b6 2d 73 c4 9d"
- + "9d d6 55 0e bb db b1 eb dd c5 4b 8f c3 17 cb 3b"
- + "c3 bf f6 7f 13 44 de 8e d7 b9 f1 a7 15 56 8f 6c"
- + "cd f2 4c 86 99 39 19 88 d3 4a 2f 38 c4 c4 37 39"
- + "85 6f 41 98 19 14 a4 1f 95 bc 04 ef 74 c2 0d f3";
- private static final String AK_MODULUS_HEX = "d7 c9 f0 e3 ac 1b 4a 1e 3c 9d 2d 57 02 e9 2a 93"
- + "b0 c0 e1 50 af e4 61 11 31 73 a1 96 b8 d6 d2 1c"
- + "40 40 c8 a6 46 a4 10 4b d1 06 74 32 f6 e3 8a 55"
- + "1e 03 c0 3e cc 75 04 c6 44 88 b6 ad 18 c9 45 65"
- + "0d be c5 45 22 bd 24 ad 32 8c be 83 a8 9b 1b d9"
- + "e0 c8 d9 ec 14 67 55 1b fe 68 dd c7 f7 33 e4 cd"
- + "87 bd ba 9a 07 e7 74 eb 57 ef 80 9c 6d ee f9 35"
- + "52 67 36 e2 53 98 46 a5 4e 8f 17 41 8d ff eb bb"
- + "9c d2 b4 df 57 f8 7f 31 ef 2e 2d 6e 06 7f 05 ed"
- + "3f e9 6f aa b4 b7 5a f9 6d ba ff 2b 5e f7 c1 05"
- + "90 68 1f b6 4b 38 67 f7 92 d8 73 51 6e 08 19 ad"
- + "ca 35 48 a7 c1 fb cb 01 9a 28 03 c9 fe bb 49 2f"
- + "88 3f a1 e7 a8 69 f0 f8 e8 78 db d3 6d c5 80 8d"
- + "c2 e4 8a af 4b c2 ac 48 2a 44 63 6e 39 b0 8f dd"
- + "e4 b3 a3 f9 2a b1 c8 d9 3d 6b c4 08 b0 16 c4 e7"
- + "c7 2f f5 94 c6 43 3e ee 9b 8a da e7 31 d1 54 dd";
- private static final String AK_NAME_HEX = "00 0b 6e 8f 79 1c 7e 16 96 1b 11 71 65 9c e0 cd"
- + "ae 0d 4d aa c5 41 be 58 89 74 67 55 96 c2 5e 38"
- + "e2 94";
- private final Random random = new Random();
- // object in test
- private AttestationCertificateAuthorityServiceImpl aca;
- private AccessAbstractProcessor abstractProcessor;
- // test key pair
- private KeyPair keyPair;
-
- /**
- * Creates a self-signed X.509 public-key certificate.
- *
- * @param pair KeyPair to create the cert for
- * @return self-signed X509Certificate
- */
- private static X509Certificate createSelfSignedCertificate(final KeyPair pair) {
- Security.addProvider(new BouncyCastleProvider());
- final int timeRange = 10000;
- X509Certificate cert = null;
- try {
-
- X500Name issuerName = new X500Name("CN=TEST2, OU=TEST2, O=TEST2, C=TEST2");
- X500Name subjectName = new X500Name("CN=TEST, OU=TEST, O=TEST, C=TEST");
- BigInteger serialNumber = BigInteger.ONE;
- Date notBefore = new Date(System.currentTimeMillis() - timeRange);
- Date notAfter = new Date(System.currentTimeMillis() + timeRange);
- X509v3CertificateBuilder builder =
- new JcaX509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter,
- subjectName, pair.getPublic());
- ContentSigner signer =
- new JcaContentSignerBuilder("SHA256WithRSA").setProvider("BC").build(
- pair.getPrivate());
- return new JcaX509CertificateConverter().setProvider("BC").getCertificate(
- builder.build(signer));
- } catch (Exception e) {
- fail("Exception occurred while creating a cert", e);
- }
- return cert;
- }
-
- /**
- * Registers bouncy castle as a security provider. Normally the JEE container will handle this,
- * but since the tests are not instantiating a container, have the unit test runner set up the
- * provider.
- */
- @BeforeAll
- public void setupTests() throws Exception {
-
- //BeforeSuite
- final int keySize = 2048;
- KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
- keyPairGenerator.initialize(keySize);
- keyPair = keyPairGenerator.generateKeyPair();
-
- //BeforeTest
- aca = new AttestationCertificateAuthorityServiceImpl(null,
- null) {
- };
- abstractProcessor = new AccessAbstractProcessor(keyPair.getPrivate(), 1);
-
- Security.addProvider(new BouncyCastleProvider());
- }
-
- /**
- * Tests {@link AttestationCertificateAuthorityServiceImpl#processIdentityClaimTpm2(byte[])}
- * where the byte array is null. Expects an illegal argument exception to be thrown.
- */
- @Test
- public void testProcessIdentityClaimTpm2NullRequest() {
- assertThrows(IllegalArgumentException.class, () ->
- aca.processIdentityClaimTpm2(null));
- }
-
- /**
- * Tests {@link AttestationCertificateAuthorityServiceImpl#getLeafACACertPublicKey()}.
- */
- @Test
- public void testGetPublicKey() {
-
- // encoded byte array to be returned by public key
- byte[] encoded = new byte[]{0, 1, 0, 1, 0};
-
- // create mocks for testing
- X509Certificate acaCertificate = mock(X509Certificate.class);
- PublicKey publicKey = mock(PublicKey.class);
-
- // assign the aca certificate to the aca
- ReflectionTestUtils.setField(aca, "acaCertificate", acaCertificate);
-
- // return a mocked public key
- when(acaCertificate.getPublicKey()).thenReturn(publicKey);
-
- // return test byte array
- when(publicKey.getEncoded()).thenReturn(encoded);
-
- // assert what the ACA returns is as expected
- assertArrayEquals(encoded, aca.getLeafACACertPublicKey());
-
- // verify mock interactions
- verify(acaCertificate).getPublicKey();
- verify(publicKey).getEncoded();
-
- // verify no other interactions with mocks
- verifyNoMoreInteractions(acaCertificate, publicKey);
- }
-
- /**
- * Tests {@link ProvisionUtils#decryptAsymmetricBlob(byte[],
- * EncryptionScheme, PrivateKey)}.
- *
- * @throws Exception during aca processing
- */
- @Test
- public void testDecryptAsymmetricBlob() throws Exception {
-
- // test encryption transformation
- EncryptionScheme encryptionScheme = EncryptionScheme.PKCS1;
-
- // test variables
- byte[] expected = "test".getBytes(StandardCharsets.UTF_8);
-
- // encrypt the expected value using same algorithm as the ACA.
- byte[] encrypted = encryptBlob(expected, encryptionScheme.toString());
-
- // perform the decryption and assert that the decrypted bytes equal the expected bytes
- assertArrayEquals(expected, ProvisionUtils.decryptAsymmetricBlob(
- encrypted, encryptionScheme, keyPair.getPrivate()));
- }
-
- /**
- * Tests {@link ProvisionUtils#decryptSymmetricBlob(
- *byte[], byte[], byte[], String)}.
- *
- * @throws Exception during aca processing
- */
- @Test
- public void testDecryptSymmetricBlob() throws Exception {
- // test encryption transformation
- String transformation = "AES/CBC/PKCS5Padding";
-
- // test variables
- byte[] expected = "test".getBytes(StandardCharsets.UTF_8);
-
- // create a key generator to generate a "shared" secret
- KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
- keyGenerator.init(SECRETKEY_LEN);
-
- // use some random bytes as the IV to encrypt and subsequently decrypt with
- byte[] randomBytes = new byte[ENCRYPTION_IV_LEN];
-
- // generate the random bytes
- random.nextBytes(randomBytes);
-
- // the shared secret
- byte[] secretKey = keyGenerator.generateKey().getEncoded();
-
- // encrypt the expected value with the private key being the shared secret
- byte[] encrypted = encryptBlob(expected, secretKey, randomBytes, transformation);
-
- // perform the decryption using the generated shared secret, random bytes as an IV, and the
- // AES CBC transformation for the cipher. then assert the decrypted results are the same
- // as our expected value.
- assertArrayEquals(expected,
- ProvisionUtils.decryptSymmetricBlob(encrypted, secretKey, randomBytes, transformation));
- }
-
- /**
- * Tests {@link ProvisionUtils#generateSymmetricKey()}.
- */
- @Test
- public void testGenerateSymmetricKey() {
- // perform the test
- SymmetricKey symmetricKey = ProvisionUtils.generateSymmetricKey();
-
- // assert the symmetric algorithm, scheme, and key size are all set appropriately
- final int expectedAlgorithmId = 6;
- final int expectedEncryptionScheme = 255;
-
- assertTrue(symmetricKey.getAlgorithmId() == expectedAlgorithmId);
- assertTrue(symmetricKey.getEncryptionScheme() == expectedEncryptionScheme);
- assertTrue(symmetricKey.getKeySize() == symmetricKey.getKey().length);
- }
-
- private void assertTrue(final boolean b) {
- }
-
- /**
- * Tests {@link ProvisionUtils#generateAsymmetricContents(
- *byte[], byte[], PublicKey)}.
- *
- * @throws Exception during aca processing
- */
- @Test
- public void testGenerateAsymmetricContents() throws Exception {
-
- // "encoded" identity proof (returned by struct converter)
- byte[] identityProofEncoded = new byte[]{0, 0, 1, 1};
-
- // generate a random session key to be used for encryption and decryption
- byte[] sessionKey = new byte[ENCRYPTION_IV_LEN];
-
- random.nextBytes(sessionKey);
- // perform the test
- byte[] result = ProvisionUtils.generateAsymmetricContents(identityProofEncoded,
- sessionKey, keyPair.getPublic());
-
- // decrypt the result
- byte[] decryptedResult = decryptBlob(result);
-
- // create a SHA1 digest of the identity key
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- md.update(identityProofEncoded);
-
- // generate the digest
- byte[] identityDigest = md.digest();
-
- // the decrypted asymmetric contents should be the session key and a SHA-1 hash of the
- // encoded identity proof.
- byte[] expected = ArrayUtils.addAll(sessionKey, identityDigest);
-
- // compare the two byte arrays
- assertArrayEquals(expected, decryptedResult);
- }
-
- /**
- * Tests {@link ProvisionUtils#generateAttestation(X509Certificate,
- * SymmetricKey)}.
- *
- * @throws Exception during aca processing
- */
- @Test
- public void testGenerateAttestation() throws Exception {
-
- // create some mocks for the unit tests
- X509Certificate certificate = mock(X509Certificate.class);
- SymmetricKey symmetricKey = mock(SymmetricKey.class);
-
- // create a key generator to generate a secret key
- KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
- keyGenerator.init(SECRETKEY_LEN);
-
- // obtain the key from the generator
- byte[] secretKey = keyGenerator.generateKey().getEncoded();
-
- // use our public key for encryption
- when(symmetricKey.getKey()).thenReturn(secretKey);
-
- // just use the existing public key for the credential
- when(certificate.getEncoded()).thenReturn(keyPair.getPublic().getEncoded());
-
- // perform the actual test
- SymmetricAttestation attestation = ProvisionUtils.generateAttestation(certificate, symmetricKey);
-
- // validate that the attestation is not null
- assertNotNull(attestation);
-
- // validate the attestation algorithm
- final int expectedAlgorithmId = 6;
- assertNotNull(attestation.getAlgorithm());
- assertTrue(attestation.getAlgorithm().getAlgorithmId() == expectedAlgorithmId);
- assertTrue(attestation.getAlgorithm().getEncryptionScheme() == 0x1);
- assertTrue(attestation.getAlgorithm().getSignatureScheme() == 0);
- assertTrue(attestation.getAlgorithm().getParamsSize() == 0);
-
- // validate the attestation credential
- assertNotNull(attestation.getCredential());
-
- // validate that the credential size is the size of the actual credential block
- assertTrue(attestation.getCredential().length == attestation.getCredentialSize());
-
- // create containers for the 2 parts of the credential
- byte[] iv = new byte[ENCRYPTION_IV_LEN];
- byte[] credential = new byte[attestation.getCredential().length - iv.length];
-
- // siphon off the first 16 bytes for the IV
- System.arraycopy(attestation.getCredential(), 0, iv, 0, iv.length);
-
- // the rest is the actual encrypted credential
- System.arraycopy(attestation.getCredential(), iv.length, credential, 0, credential.length);
-
- // decrypt the credential
- byte[] decrypted = decryptBlob(credential, secretKey, iv, "AES/CBC/PKCS5Padding");
-
- // assert that the decrypted credential is our public key
- assertArrayEquals(keyPair.getPublic().getEncoded(), decrypted);
-
- // verify that the mocks were interacted with appropriately
- verify(symmetricKey).getKey();
- verify(certificate).getEncoded();
- verifyNoMoreInteractions(certificate, symmetricKey);
- }
-
- /**
- * Tests {@link AttestationCertificateAuthorityServiceImpl#
- * AttestationCertificateAuthority(SupplyChainValidationService, PrivateKey,
- * X509Certificate, StructConverter, CertificateManager, DeviceRegister, int,
- * DeviceManager, DBManager)}.
- *
- * @throws Exception during subject alternative name checking if cert formatting is bad
- */
- @Test
- public void testGenerateCredential() throws Exception {
- // test variables
- final String identityProofLabelString = "label";
- byte[] identityProofLabel = identityProofLabelString.getBytes(StandardCharsets.UTF_8);
- byte[] modulus = ((RSAPublicKey) keyPair.getPublic()).getModulus().toByteArray();
- int validDays = 1;
-
- // create mocks for testing
- IdentityProof identityProof = mock(IdentityProof.class);
- AsymmetricPublicKey asymmetricPublicKey = mock(AsymmetricPublicKey.class);
- StorePubKey storePubKey = mock(StorePubKey.class);
- X509Certificate acaCertificate = createSelfSignedCertificate(keyPair);
-
- // assign ACA fields
- ReflectionTestUtils.setField(aca, "validDays", validDays);
- ReflectionTestUtils.setField(aca, "acaCertificate", acaCertificate);
-
- // prepare identity proof interactions
- when(identityProof.getLabel()).thenReturn(identityProofLabel);
-
- // perform the test
- X509Certificate certificate = abstractProcessor.accessGenerateCredential(keyPair.getPublic(),
- null,
- new LinkedList(),
- "exampleIdLabel",
- acaCertificate);
-
- // grab the modulus from the generate certificate
- byte[] resultMod = ((RSAPublicKey) certificate.getPublicKey()).getModulus().toByteArray();
-
- // today and tomorrow, when the certificate should be valid for
- Calendar today = Calendar.getInstance();
- Calendar tomorrow = Calendar.getInstance();
- tomorrow.add(Calendar.DATE, 1);
-
- // validate the certificate
- assertTrue(certificate.getIssuerX500Principal().toString().contains("CN=TEST"));
- assertTrue(certificate.getIssuerX500Principal().toString().contains("OU=TEST"));
- assertTrue(certificate.getIssuerX500Principal().toString().contains("O=TEST"));
- assertTrue(certificate.getIssuerX500Principal().toString().contains("C=TEST"));
-
- // validate the format of the subject and subject alternative name
- assertEquals("", certificate.getSubjectX500Principal().getName());
- assertEquals("exampleIdLabel",
- ((X500Name) GeneralNames.fromExtensions(((TBSCertificate.getInstance(
- certificate.getTBSCertificate()).getExtensions())), Extension.
- subjectAlternativeName).getNames()[0].getName()).getRDNs(
- IssuedCertificateAttributeHelper.TCPA_AT_TPM_ID_LABEL)[0].getFirst()
- .getValue().toString());
-
- assertArrayEquals(modulus, resultMod);
-
- // obtain the expiration dates from the certificate
- Calendar beforeDate = Calendar.getInstance();
- Calendar afterDate = Calendar.getInstance();
- beforeDate.setTime(certificate.getNotBefore());
- afterDate.setTime(certificate.getNotAfter());
-
- // assert the dates are set correctly
- assertEquals(today.get(Calendar.DATE), beforeDate.get(Calendar.DATE));
- assertEquals(tomorrow.get(Calendar.DATE), afterDate.get(Calendar.DATE));
-
- // validate mock interactions
- verifyNoMoreInteractions(identityProof, asymmetricPublicKey, storePubKey);
- }
-
- /**
- * Tests {@link ProvisionUtils#assembleRSAPublicKey(byte[])}.
- */
- @Test
- public void testAssemblePublicKeyUsingByteArray() {
- // obtain the expected modulus from the existing public key
- final BigInteger modulus = ((RSAPublicKey) keyPair.getPublic()).getModulus();
-
- // perform test
- RSAPublicKey publicKey = (RSAPublicKey) ProvisionUtils.assembleRSAPublicKey(modulus.toByteArray());
-
- // assert that the exponent and the modulus are the same. the exponents should be the well
- // known prime, 101
- final int radix = 16;
- assertTrue(publicKey.getPublicExponent().equals(new BigInteger("010001", radix)));
- assertTrue(publicKey.getModulus().equals(modulus));
- }
-
- /**
- * Tests {@link ProvisionUtils#assembleRSAPublicKey(String)}.
- */
- @Test
- public void testAssemblePublicKeyUsingHexEncodedString() {
- // obtain the expected modulus from the existing public key
- final BigInteger modulus = ((RSAPublicKey) keyPair.getPublic()).getModulus();
-
- // encode our existing public key into hex
- final String modulusString = Hex.encodeHexString(
- ((RSAPublicKey) keyPair.getPublic()).getModulus().toByteArray());
-
- // perform test
- RSAPublicKey publicKey = (RSAPublicKey) ProvisionUtils.assembleRSAPublicKey(modulusString);
-
- // assert that the exponent and the modulus are the same. the exponents should be the well
- // known prime, 101.
- final int radix = 16;
- assertTrue(publicKey.getPublicExponent().equals(new BigInteger("010001", radix)));
- assertTrue(publicKey.getModulus().equals(modulus));
- }
-
- /**
- * Tests parsing the EK from the TPM2 output file.
- *
- * @throws URISyntaxException incorrect resource path
- * @throws IOException unable to read from file
- */
- @Test
- public void testParseEk() throws URISyntaxException, IOException {
- Path ekPath = Paths.get(getClass().getResource(
- EK_PUBLIC_PATH).toURI());
-
- byte[] ekFile = Files.readAllBytes(ekPath);
-
- RSAPublicKey ek = ProvisionUtils.parseRSAKeyFromPublicDataSegment(ekFile);
- final int radix = 16;
- assertTrue(ek.getPublicExponent().equals(new BigInteger("010001", radix)));
-
- byte[] mod = ek.getModulus().toByteArray();
- // big integer conversion is signed so it can add a 0 byte
- if (mod[0] == 0) {
- byte[] tmp = new byte[mod.length - 1];
- System.arraycopy(mod, 1, tmp, 0, mod.length - 1);
- mod = tmp;
- }
- String hex = HexUtils.byteArrayToHexString(mod);
- String realMod = EK_MODULUS_HEX.replaceAll("\\s+", "");
- assertEquals(realMod, hex);
- }
-
- /**
- * Tests parsing the AK public key from the TPM2 output file.
- *
- * @throws URISyntaxException incorrect resource path
- * @throws IOException unable to read from file
- */
- @Test
- public void testParseAk() throws URISyntaxException, IOException {
- Path akPath = Paths.get(getClass().getResource(
- AK_PUBLIC_PATH).toURI());
-
- byte[] akFile = Files.readAllBytes(akPath);
-
- RSAPublicKey ak = ProvisionUtils.parseRSAKeyFromPublicDataSegment(akFile);
- final int radix = 16;
- assertTrue(ak.getPublicExponent().equals(new BigInteger("010001", radix)));
-
- byte[] mod = ak.getModulus().toByteArray();
- // big integer conversion is signed so it can add a 0 byte
- if (mod[0] == 0) {
- byte[] tmp = new byte[mod.length - 1];
- System.arraycopy(mod, 1, tmp, 0, mod.length - 1);
- mod = tmp;
- }
- String hex = HexUtils.byteArrayToHexString(mod);
- String realMod = AK_MODULUS_HEX.replaceAll("\\s+", "");
- assertEquals(realMod, hex);
- }
-
- /**
- * Tests parsing the AK name from the TPM2 output file.
- *
- * @throws URISyntaxException incorrect resource path
- * @throws IOException unable to read from file
- * @throws NoSuchAlgorithmException inavlid algorithm
- */
- @Test
- public void testGenerateAkName() throws URISyntaxException, IOException,
- NoSuchAlgorithmException {
- Path akNamePath = Paths.get(getClass().getResource(
- AK_NAME_PATH).toURI());
-
- byte[] akNameFileBytes = Files.readAllBytes(akNamePath);
- String realHex = HexUtils.byteArrayToHexString(akNameFileBytes);
-
- String realMod = AK_MODULUS_HEX.replaceAll("\\s+", "");
- byte[] akName = ProvisionUtils.generateAkName(HexUtils.hexStringToByteArray(realMod));
-
- String hex = HexUtils.byteArrayToHexString(akName);
- String realName = AK_NAME_HEX.replaceAll("\\s+", "");
- assertEquals(hex, realName);
- assertEquals(hex, realHex);
- }
-
- /**
- * Method to generate a make credential output file for use in manual testing. Feed to
- * a TPM 2.0 or emulator using the activate credential command to ensure proper parsing.
- * Must be performed manually. To use, copy the TPM's ek and ak into
- * HIRS_AttestationCA/src/test/resources/tpm2/test/ and ensure the variables akPubPath
- * and ekPubPath are correct. Your output file will be
- * HIRS_AttestationCA/src/test/resources/tpm2/test/make.blob and the nonce used will be
- * output as HIRS_AttestationCA/src/test/resources/tpm2/test/secret.blob
- *
- * @throws URISyntaxException invalid file path
- * @throws IOException unable to read file
- */
- @Disabled
- @Test
- public void testMakeCredential() throws URISyntaxException, IOException {
- Path akPubPath = Paths.get(getClass().getResource(
- AK_PUBLIC_PATH).toURI());
- Path ekPubPath = Paths.get(getClass().getResource(
- EK_PUBLIC_PATH).toURI());
-
- byte[] ekPubFile = Files.readAllBytes(ekPubPath);
- byte[] akPubFile = Files.readAllBytes(akPubPath);
-
- RSAPublicKey ekPub = ProvisionUtils.parseRSAKeyFromPublicDataSegment(ekPubFile);
- RSAPublicKey akPub = ProvisionUtils.parseRSAKeyFromPublicDataSegment(akPubFile);
-
- // prepare the nonce and wrap it with keys
- final byte[] nonce = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
- ByteString blob = ProvisionUtils.tpm20MakeCredential(ekPub, akPub, nonce);
-
- Path resources = Objects.requireNonNull(Paths.get(Objects.requireNonNull(this.getClass().getResource(
- "/").toURI()))
- .getParent().getParent().getParent().getParent());
- Path makeBlob = resources.resolve("src/test/resources/tpm2/test/make.blob");
- Files.write(makeBlob, blob.toByteArray());
-
- Path secretPath = resources.resolve("src/test/resources/tpm2/test/secret.blob");
- Files.write(secretPath, nonce);
- }
-
- /**
- * Test helper method that encrypts a blob using the specified transformation and the test key
- * pair public key.
- *
- * @param blob to be encrypted
- * @param transformation used by a cipher to encrypt
- * @return encrypted blob
- * @throws Exception during the encryption process
- */
- private byte[] encryptBlob(final byte[] blob, final String transformation) throws Exception {
- // initialize a cipher using the specified transformation
- Cipher cipher = Cipher.getInstance(transformation);
-
- // use our generated public key to encrypt
- cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
-
- // return the cipher text
- return cipher.doFinal(blob);
- }
-
- /**
- * Test helper method that encrypts a blob using a shared key and IV using the specified
- * transformation.
- *
- * @param blob blob to be encrypted
- * @param key shared key
- * @param iv to encrypt with
- * @param transformation of the encryption cipher
- * @return encrypted blob
- * @throws Exception if there are any issues while encrypting the blob
- */
- private byte[] encryptBlob(final byte[] blob, final byte[] key, final byte[] iv,
- final String transformation) throws Exception {
- // initialize a cipher using the specified transformation
- Cipher cipher = Cipher.getInstance(transformation);
-
- // generate a secret key specification using the key and AES.
- SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
-
- // create IV parameter for key specification
- IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
-
- // encrypt using the key specification with the generated IV
- cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec);
-
- // return the cipher text
- return cipher.doFinal(blob);
- }
-
- /**
- * Test helper method to decrypt blobs.
- *
- * @param blob blob to be decrypted
- * @return decrypted blob
- * @throws Exception if there are any issues while decrypting the blob
- */
- private byte[] decryptBlob(final byte[] blob) throws Exception {
- // initialize a cipher using the specified transformation
- Cipher cipher = Cipher.getInstance(EncryptionScheme.OAEP.toString());
-
- OAEPParameterSpec spec = new OAEPParameterSpec("Sha1", "MGF1",
- MGF1ParameterSpec.SHA1, new PSource.PSpecified("TCPA".getBytes(StandardCharsets.UTF_8)));
-
- // use our generated public key to encrypt
- cipher.init(Cipher.PRIVATE_KEY, keyPair.getPrivate(), spec);
-
- // return the cipher text
- return cipher.doFinal(blob);
- }
-
- /**
- * Test helper method that decrypts a blob using a shared key and IV using the specified.
- * transformation.
- *
- * @param blob blob to be decrypted
- * @param key shared key
- * @param iv to decrypt with
- * @param transformation of the decryption cipher
- * @return decrypted blob
- * @throws Exception if there are any issues while decrypting the blob
- */
- private byte[] decryptBlob(final byte[] blob, final byte[] key, final byte[] iv,
- final String transformation) throws Exception {
- // initialize a cipher using the specified transformation
- Cipher cipher = Cipher.getInstance(transformation);
-
- // generate a secret key specification using the key and AES
- SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
-
- // create IV parameter for key specification
- IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
-
- // encrypt using the key specification with the generated IV
- cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
-
- // return the cipher text
- return cipher.doFinal(blob);
- }
-
- /**
- * This internal class handles setup for testing the function
- * generateCredential() from class AbstractProcessor. Because the
- * function is Protected and in a different package than the test,
- * it cannot be accessed directly.
- */
- @Nested
- public class AccessAbstractProcessor extends AbstractProcessor {
-
- /**
- * Constructor.
- *
- * @param privateKey the private key of the ACA
- * @param validDays int for the time in which a certificate is valid.
- */
- public AccessAbstractProcessor(final PrivateKey privateKey,
- final int validDays) {
- super(privateKey, validDays);
- }
-
- /**
- * Public wrapper for the protected function generateCredential(), to access for testing.
- *
- * @param publicKey cannot be null
- * @param endorsementCredential the endorsement credential
- * @param platformCredentials the set of platform credentials
- * @param deviceName The host name used in the subject alternative name
- * @param acaCertificate the aca certificate
- * @return the generated X509 certificate
- */
- public X509Certificate accessGenerateCredential(final PublicKey publicKey,
- final EndorsementCredential endorsementCredential,
- final List platformCredentials,
- final String deviceName,
- final X509Certificate acaCertificate) {
-
- return generateCredential(publicKey,
- endorsementCredential,
- platformCredentials,
- deviceName,
- acaCertificate);
- }
- }
-}
From 6527bc0e948c06a756facf7bb639d155caa5d581 Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Wed, 25 Feb 2026 17:55:43 -0500
Subject: [PATCH 06/25] v3.1_issue_1090: SLowly but surely making progress.
---
.../persist/enums/PublicKeyAlgorithm.java | 22 +-
.../provision/helper/ProvisionUtils.java | 56 ++-
...tationCertificateAuthorityServiceTest.java | 346 ++++++------------
.../resources/{tpm2 => public_keys}/ak.name | Bin
.../resources/{tpm2 => public_keys}/ak.pub | Bin
.../resources/{tpm2 => public_keys}/ek.pub | Bin
6 files changed, 183 insertions(+), 241 deletions(-)
rename HIRS_AttestationCA/src/test/resources/{tpm2 => public_keys}/ak.name (100%)
rename HIRS_AttestationCA/src/test/resources/{tpm2 => public_keys}/ak.pub (100%)
rename HIRS_AttestationCA/src/test/resources/{tpm2 => public_keys}/ek.pub (100%)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
index a4a8c85ad..c2eef2772 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
@@ -24,11 +24,31 @@
@AllArgsConstructor
@ToString
public enum PublicKeyAlgorithm {
+ /**
+ * RSA Public Key Algorithm.
+ */
RSA("RSA", RSAPublicKey.class),
- ECC("ECC", ECPublicKey.class),
+
+ /**
+ * ECC Public Key Algorithm.
+ */
+ ECC("EC", ECPublicKey.class),
+
+ /**
+ * Represents an unknown public key algorithm.
+ * This is used when the application encounters a public key algorithm that is not recognized or supported.
+ * It may occur if the algorithm is unsupported or not implemented in the current version of the application.
+ */
UNKNOWN("UNKNOWN", null);
+ /**
+ * The name of the cryptographic algorithm.
+ */
private final String algorithmName;
+
+ /**
+ * The Java Security class corresponding to the public key type used by the algorithm.
+ */
private final Class extends PublicKey> keyClass;
/**
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index 65cf49d6c..89e0e0e49 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -37,7 +37,10 @@
import java.security.cert.X509Certificate;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
import java.security.spec.ECPublicKeySpec;
+import java.security.spec.EllipticCurve;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.RSAPublicKeySpec;
@@ -177,18 +180,20 @@ public static PublicKey parsePublicKeyFromPublicDataSegment(final PublicKeyAlgor
/**
* Parses the RSA public key from public data segment generated by TPM 2.0.
*
- * @param publicArea the public area segment to parse
+ * @param publicAreaSegment the public area segment to parse
* @return the RSA public key of the supplied public data
*/
- public static RSAPublicKey parseRSAKeyFromPublicDataSegment(final byte[] publicArea) {
- final int pubLen = publicArea.length;
+ public static RSAPublicKey parseRSAKeyFromPublicDataSegment(final byte[] publicAreaSegment) {
+ final int publicAreaLen = publicAreaSegment.length;
- if (pubLen < DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES) {
+ if (publicAreaLen < DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES) {
throw new IllegalArgumentException("EK or AK public data segment is not long enough");
}
// public data ends with 256 byte modulus
- byte[] modulus = HexUtils.subarray(publicArea, pubLen - DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES, pubLen - 1);
+ byte[] modulus =
+ HexUtils.subarray(publicAreaSegment, publicAreaLen - DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES,
+ publicAreaLen - 1);
return (RSAPublicKey) assembleRSAPublicKey(modulus);
}
@@ -233,21 +238,48 @@ public static PublicKey assembleRSAPublicKey(final BigInteger modulus) {
}
/**
+ * todo
* Parses the ECC public key from public data segment generated by TPM 2.0.
*
- * @param publicArea the public area segment to parse
+ * @param publicAreaSegment the public area segment to parse
* @return the ECC public key of the supplied public data
*/
- public static ECPublicKey parseECCKeyFromPublicDataSegment(final byte[] publicArea) {
- final int pubLen = publicArea.length;
+ public static ECPublicKey parseECCKeyFromPublicDataSegment(final byte[] publicAreaSegment) {
+ //final int pubLen = publicArea.length;
- return (ECPublicKey) assembleECCPublicKey();
+ final BigInteger x = new BigInteger("0");
+ final BigInteger y = new BigInteger("0");
+
+ return assembleECCPublicKey(new ECPoint(x, y));
}
- public static PublicKey assembleECCPublicKey() {
- ECPublicKeySpec ecPublicKeySpec = null;
+ /**
+ * todo
+ *
+ * @param ecPoint
+ * @return
+ */
+ public static ECPublicKey assembleECCPublicKey(final ECPoint ecPoint) {
+ BigInteger a = new BigInteger("0");
+ BigInteger b = new BigInteger("0");
+
+ EllipticCurve ellipticCurve = new EllipticCurve(null, a, b);
+ ECParameterSpec ecParameterSpec = null;
- // create the RSA public key
+ return (ECPublicKey) assembleECCPublicKey(ecPoint, ecParameterSpec);
+ }
+
+ /**
+ * todo
+ *
+ * @param ecpoint
+ * @param ecParameterSpec
+ * @return
+ */
+ public static PublicKey assembleECCPublicKey(final ECPoint ecpoint, final ECParameterSpec ecParameterSpec) {
+ final ECPublicKeySpec ecPublicKeySpec = new ECPublicKeySpec(ecpoint, ecParameterSpec);
+
+ // create the ECC public key
try {
KeyFactory keyFactory = KeyFactory.getInstance(PublicKeyAlgorithm.ECC.getAlgorithmName());
return keyFactory.generatePublic(ecPublicKeySpec);
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
index e138eddd3..e9cf33945 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
@@ -1,39 +1,20 @@
package hirs.attestationca.persist;
-import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
-import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
-import hirs.attestationca.persist.provision.AbstractProcessor;
+import hirs.attestationca.persist.exceptions.CertificateProcessingException;
import hirs.attestationca.persist.provision.CertificateRequestProcessor;
import hirs.attestationca.persist.provision.IdentityClaimProcessor;
-import hirs.attestationca.persist.provision.helper.IssuedCertificateAttributeHelper;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
-import hirs.structs.elements.tpm.AsymmetricPublicKey;
-import hirs.structs.elements.tpm.IdentityProof;
-import hirs.structs.elements.tpm.StorePubKey;
import hirs.utils.HexUtils;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.GeneralNames;
-import org.bouncycastle.asn1.x509.TBSCertificate;
-import org.bouncycastle.cert.X509v3CertificateBuilder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
-import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.operator.ContentSigner;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.springframework.test.util.ReflectionTestUtils;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -41,35 +22,26 @@
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
import java.security.PublicKey;
-import java.security.Security;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
/**
- *
+ * Tests the {@link AttestationCertificateAuthorityServiceImpl} service class.
*/
public class AttestationCertificateAuthorityServiceTest {
- private static final String EK_PUBLIC_PATH = "/tpm2/ek.pub";
+ private static final String EK_PUBLIC_KEY_PATH = "/public_keys/ek.pub";
- private static final String AK_PUBLIC_PATH = "/tpm2/ak.pub";
+ private static final String AK_PUBLIC_KEY_PATH = "/public_keys/ak.pub";
- private static final String AK_NAME_PATH = "/tpm2/ak.name";
+ private static final String AK_NAME_PATH = "/public_keys/ak.name";
private static final String EK_MODULUS_HEX = "a3 b5 c2 1c 57 be 40 c4 3c 78 90 0d 00 81 01 78"
+ "13 ca 02 ec b6 75 89 60 ca 60 9b 10 b6 b4 d0 0b"
@@ -116,14 +88,17 @@ public class AttestationCertificateAuthorityServiceTest {
@InjectMocks
private AttestationCertificateAuthorityServiceImpl attestationCertificateAuthorityService;
- private AccessAbstractProcessor abstractProcessor;
-
@Mock
private CertificateRequestProcessor certificateRequestProcessor;
@Mock
private IdentityClaimProcessor identityClaimProcessor;
+ /**
+ * Setups configuration prior to each test method.
+ *
+ * @throws NoSuchAlgorithmException if issues arise while generating keypair.
+ */
@BeforeEach
public void setupTests() throws NoSuchAlgorithmException {
// Initializes mocks before each test
@@ -135,6 +110,11 @@ public void setupTests() throws NoSuchAlgorithmException {
keyPair = keyPairGenerator.generateKeyPair();
}
+ /**
+ * Closes mocks after the completion of each test method.
+ *
+ * @throws Exception if any issues arise while closing mocks.
+ */
@AfterEach
public void afterEach() throws Exception {
if (mocks != null) {
@@ -144,84 +124,142 @@ public void afterEach() throws Exception {
/**
* Tests {@link AttestationCertificateAuthorityService#processIdentityClaimTpm2(byte[])}
- * where the byte array is null or empty. Expects an illegal argument exception to be thrown.
- *
- * @throws GeneralSecurityException if any issues arise while processing the identity claim request
+ * where the byte array is null or empty. Expects an {@link IllegalArgumentException} to be thrown.
*/
@Test
- public void testProcessIdentityClaimTpm2NullOrEmptyRequest() throws GeneralSecurityException {
+ public void testProcessIdentityClaimTpm2NullOrEmptyRequest() {
+ final String expectedExceptionMsg = "The IdentityClaim sent by the client cannot be null or empty.";
+
// test 1: test null identity claim
- when(attestationCertificateAuthorityService.processIdentityClaimTpm2(null)).thenThrow(
- new IllegalArgumentException("The IdentityClaim sent by the client cannot be null or empty."));
+ when(identityClaimProcessor.processIdentityClaimTpm2(null)).thenThrow(
+ new IllegalArgumentException(expectedExceptionMsg));
// Act & Assert: Verify that the exception is thrown
- IllegalArgumentException illegalArgumentException = assertThrows(IllegalArgumentException.class,
- () -> attestationCertificateAuthorityService.processIdentityClaimTpm2(null));
+ String actualExceptionMsg = assertThrows(IllegalArgumentException.class,
+ () -> attestationCertificateAuthorityService.processIdentityClaimTpm2(null)).getMessage();
- assertEquals("The IdentityClaim sent by the client cannot be null or empty.",
- illegalArgumentException.getMessage());
+ assertEquals(expectedExceptionMsg, actualExceptionMsg);
// test 2: test empty identity claim
// initialize an empty byte array
final byte[] emptyArr = {};
- when(attestationCertificateAuthorityService.processIdentityClaimTpm2(emptyArr)).thenThrow(
- new IllegalArgumentException("The IdentityClaim sent by the client cannot be null or empty."));
+ when(identityClaimProcessor.processIdentityClaimTpm2(emptyArr)).thenThrow(
+ new IllegalArgumentException(expectedExceptionMsg));
// Act & Assert: Verify that the exception is thrown
- illegalArgumentException = assertThrows(IllegalArgumentException.class,
- () -> attestationCertificateAuthorityService.processIdentityClaimTpm2(emptyArr));
+ actualExceptionMsg = assertThrows(IllegalArgumentException.class,
+ () -> attestationCertificateAuthorityService.processIdentityClaimTpm2(emptyArr)).getMessage();
- assertEquals("The IdentityClaim sent by the client cannot be null or empty.",
- illegalArgumentException.getMessage());
+ assertEquals(expectedExceptionMsg, actualExceptionMsg);
+ }
+
+ /**
+ * Tests {@link AttestationCertificateAuthorityService#processIdentityClaimTpm2(byte[])}.
+ */
+ @Test
+ public void testProcessIdentityClaimTpm2() {
+ final byte[] identityClaim = {0, 1, 0, 1, 2, 2, 2};
+
+ final byte[] expectedIdentityClaimResponse = {1, 1, 1, 1, 2, 2, 2, 2};
+
+ when(identityClaimProcessor.processIdentityClaimTpm2(identityClaim)).thenReturn(
+ expectedIdentityClaimResponse);
+
+ final byte[] actualCertificateResponse =
+ identityClaimProcessor.processIdentityClaimTpm2(identityClaim);
+
+ // Assert that the byte arrays match
+ assertArrayEquals(expectedIdentityClaimResponse, actualCertificateResponse);
}
/**
* Tests {@link AttestationCertificateAuthorityService#processCertificateRequest(byte[])}
- * where the byte array is null or empty. Expects an illegal argument exception to be thrown.
+ * where the byte array is null or empty. Expects an {@link IllegalArgumentException} to be thrown.
*
* @throws GeneralSecurityException if any issues arise while processing the certificate request
*/
@Test
public void testProcessCertificateRequestNullOrEmptyRequest() throws GeneralSecurityException {
- // test 1: test null certificate request
+ final String expectedExceptionMsg = "The CertificateRequest sent by the client cannot be null or empty.";
- when(attestationCertificateAuthorityService.processCertificateRequest(null)).thenThrow(
- new IllegalArgumentException("The CertificateRequest sent by the client cannot be null or empty."));
+ // test 1: test null certificate request
+ when(certificateRequestProcessor.processCertificateRequest(null)).thenThrow(
+ new IllegalArgumentException(expectedExceptionMsg));
// Act & Assert: Verify that the exception is thrown
- IllegalArgumentException illegalArgumentException = assertThrows(IllegalArgumentException.class,
- () -> attestationCertificateAuthorityService.processCertificateRequest(null));
+ String actualExceptionMsg = assertThrows(IllegalArgumentException.class,
+ () -> attestationCertificateAuthorityService.processCertificateRequest(null)).getMessage();
- assertEquals("The CertificateRequest sent by the client cannot be null or empty.",
- illegalArgumentException.getMessage());
+ assertEquals(expectedExceptionMsg, actualExceptionMsg);
// test 2: test empty certificate request
// initialize an empty byte array
final byte[] emptyArr = {};
- when(attestationCertificateAuthorityService.processCertificateRequest(emptyArr)).thenThrow(
- new IllegalArgumentException("The CertificateRequest sent by the client cannot be null or empty."));
+ when(certificateRequestProcessor.processCertificateRequest(emptyArr)).thenThrow(
+ new IllegalArgumentException(expectedExceptionMsg));
- illegalArgumentException = assertThrows(IllegalArgumentException.class,
- () -> attestationCertificateAuthorityService.processCertificateRequest(emptyArr));
+ // Act & Assert: Verify that the exception is thrown
+ actualExceptionMsg = assertThrows(IllegalArgumentException.class,
+ () -> attestationCertificateAuthorityService.processCertificateRequest(emptyArr)).getMessage();
- assertEquals("The CertificateRequest sent by the client cannot be null or empty.",
- illegalArgumentException.getMessage());
+ assertEquals(expectedExceptionMsg, actualExceptionMsg);
}
/**
- * Tests {@link AttestationCertificateAuthorityService#getLeafACACertPublicKey()}.
+ * Tests {@link AttestationCertificateAuthorityService#processCertificateRequest(byte[])}
+ * where the byte array is invalid. Expects a {@link CertificateProcessingException} to be thrown.
+ *
+ * @throws GeneralSecurityException if any issues arise while processing the certificate request
*/
@Test
- public void testGetPublicKey() {
+ public void testProcessCertificateRequestProcessorDeserializationError() throws GeneralSecurityException {
+ final String expectedExceptionMsg = "Could not deserialize Protobuf Certificate Request object";
+
+ final byte[] badCertificateRequest = {0, 0, 0, 0, 0, 1, 0, 0};
+
+ when(certificateRequestProcessor.processCertificateRequest(badCertificateRequest)).thenThrow(
+ new CertificateProcessingException(expectedExceptionMsg));
+
+ // Act & Assert: Verify that the exception is thrown
+ String actualExceptionMsg = assertThrows(CertificateProcessingException.class,
+ () -> attestationCertificateAuthorityService.processCertificateRequest(
+ badCertificateRequest)).getMessage();
+
+ assertEquals(expectedExceptionMsg, actualExceptionMsg);
+ }
+
+ /**
+ * Tests {@link AttestationCertificateAuthorityService#processCertificateRequest(byte[])}.
+ *
+ * @throws GeneralSecurityException if any issues arise while processing the certificate request
+ */
+ @Test
+ public void testProcessCertificateRequest() throws GeneralSecurityException {
+ final byte[] certificateRequest = {0, 1, 0, 1};
+
+ final byte[] expectedCertificateResponse = {1, 1, 1, 1};
+
+ when(certificateRequestProcessor.processCertificateRequest(certificateRequest)).thenReturn(
+ expectedCertificateResponse);
+
+ final byte[] actualCertificateResponse =
+ attestationCertificateAuthorityService.processCertificateRequest(certificateRequest);
- // setup
+ // Assert that the byte arrays match
+ assertArrayEquals(expectedCertificateResponse, actualCertificateResponse);
+ }
+ /**
+ * Tests {@link AttestationCertificateAuthorityService#getLeafACACertPublicKey()}.
+ */
+ @Test
+ public void testGetPublicKey() {
// encoded byte array to be returned by public key
- final byte[] desiredByteArray = new byte[]{0, 1, 0, 1, 0};
+ final byte[] expectedByteArray = new byte[]{0, 1, 0, 1, 0};
// create mocks for testing
X509Certificate mockCertificate = mock(X509Certificate.class);
@@ -229,23 +267,26 @@ public void testGetPublicKey() {
// Mock the behavior of getPublicKey().getEncoded() to return the desired byte array
when(mockCertificate.getPublicKey()).thenReturn(mockPublicKey);
- when(mockPublicKey.getEncoded()).thenReturn(desiredByteArray);
+ when(mockPublicKey.getEncoded()).thenReturn(expectedByteArray);
+
+ // grab the public key encoding
+ byte[] mockedByteArrayResult = mockPublicKey.getEncoded();
- when(attestationCertificateAuthorityService.getLeafACACertPublicKey()).thenReturn(
- mockCertificate.getPublicKey().getEncoded());
+ // Mock the behavior of retrieving the public key from the service class
+ when(attestationCertificateAuthorityService.getLeafACACertPublicKey()).thenReturn(mockedByteArrayResult);
// Test: Call the service method and assert the return value
byte[] actualByteArray = attestationCertificateAuthorityService.getLeafACACertPublicKey();
- // Assert that the byte arrays match
- assertArrayEquals(desiredByteArray, actualByteArray);
+ // Assert that the mocked and actual byte arrays match
+ assertArrayEquals(expectedByteArray, actualByteArray);
}
/**
* Tests {@link ProvisionUtils#assembleRSAPublicKey(byte[])}.
*/
@Test
- public void testAssemblePublicKeyUsingByteArray() {
+ public void testAssembleRSAPublicKeyUsingByteArray() {
// obtain the expected modulus from the existing public key
final BigInteger modulus = ((RSAPublicKey) keyPair.getPublic()).getModulus();
@@ -267,7 +308,7 @@ public void testAssemblePublicKeyUsingByteArray() {
*/
@Test
public void testParseEk() throws URISyntaxException, IOException {
- Path ekPath = Paths.get(Objects.requireNonNull(getClass().getResource(EK_PUBLIC_PATH)).toURI());
+ Path ekPath = Paths.get(Objects.requireNonNull(getClass().getResource(EK_PUBLIC_KEY_PATH)).toURI());
byte[] ekFile = Files.readAllBytes(ekPath);
@@ -295,7 +336,7 @@ public void testParseEk() throws URISyntaxException, IOException {
*/
@Test
public void testParseAk() throws URISyntaxException, IOException {
- Path akPath = Paths.get(Objects.requireNonNull(getClass().getResource(AK_PUBLIC_PATH)).toURI());
+ Path akPath = Paths.get(Objects.requireNonNull(getClass().getResource(AK_PUBLIC_KEY_PATH)).toURI());
byte[] akFile = Files.readAllBytes(akPath);
@@ -314,155 +355,4 @@ public void testParseAk() throws URISyntaxException, IOException {
String realMod = AK_MODULUS_HEX.replaceAll("\\s+", "");
assertEquals(realMod, hex);
}
-
- /**
- * Tests {@link AttestationCertificateAuthorityService#
- * AttestationCertificateAuthority(SupplyChainValidationService, PrivateKey,
- * X509Certificate, StructConverter, CertificateManager, DeviceRegister, int,
- * DeviceManager, DBManager)}.
- *
- * @throws Exception during subject alternative name checking if cert formatting is bad
- */
- @Test
- public void testGenerateCredential() throws Exception {
- // test variables
- final String identityProofLabelString = "label";
- byte[] identityProofLabel = identityProofLabelString.getBytes(StandardCharsets.UTF_8);
- byte[] modulus = ((RSAPublicKey) keyPair.getPublic()).getModulus().toByteArray();
- int validDays = 1;
-
- // create mocks for testing
- IdentityProof identityProof = mock(IdentityProof.class);
- AsymmetricPublicKey asymmetricPublicKey = mock(AsymmetricPublicKey.class);
- StorePubKey storePubKey = mock(StorePubKey.class);
- X509Certificate acaCertificate = createSelfSignedCertificate(keyPair);
-
- // assign ACA fields
- ReflectionTestUtils.setField(attestationCertificateAuthorityService, "validDays", validDays);
- ReflectionTestUtils.setField(attestationCertificateAuthorityService, "acaCertificate", acaCertificate);
-
- // prepare identity proof interactions
- when(identityProof.getLabel()).thenReturn(identityProofLabel);
-
- // perform the test
- X509Certificate certificate = abstractProcessor.accessGenerateCredential(keyPair.getPublic(),
- null,
- new LinkedList<>(),
- "exampleIdLabel",
- acaCertificate);
-
- // grab the modulus from the generate certificate
- byte[] resultMod = ((RSAPublicKey) certificate.getPublicKey()).getModulus().toByteArray();
-
- // today and tomorrow, when the certificate should be valid for
- Calendar today = Calendar.getInstance();
- Calendar tomorrow = Calendar.getInstance();
- tomorrow.add(Calendar.DATE, 1);
-
- // validate the certificate
- assertTrue(certificate.getIssuerX500Principal().toString().contains("CN=TEST"));
- assertTrue(certificate.getIssuerX500Principal().toString().contains("OU=TEST"));
- assertTrue(certificate.getIssuerX500Principal().toString().contains("O=TEST"));
- assertTrue(certificate.getIssuerX500Principal().toString().contains("C=TEST"));
-
- // validate the format of the subject and subject alternative name
- assertEquals("", certificate.getSubjectX500Principal().getName());
- assertEquals("exampleIdLabel",
- ((X500Name) GeneralNames.fromExtensions(((TBSCertificate.getInstance(
- certificate.getTBSCertificate()).getExtensions())), Extension.
- subjectAlternativeName).getNames()[0].getName()).getRDNs(
- IssuedCertificateAttributeHelper.TCPA_AT_TPM_ID_LABEL)[0].getFirst()
- .getValue().toString());
-
- assertArrayEquals(modulus, resultMod);
-
- // obtain the expiration dates from the certificate
- Calendar beforeDate = Calendar.getInstance();
- Calendar afterDate = Calendar.getInstance();
- beforeDate.setTime(certificate.getNotBefore());
- afterDate.setTime(certificate.getNotAfter());
-
- // assert the dates are set correctly
- assertEquals(today.get(Calendar.DATE), beforeDate.get(Calendar.DATE));
- assertEquals(tomorrow.get(Calendar.DATE), afterDate.get(Calendar.DATE));
-
- // validate mock interactions
- verifyNoMoreInteractions(identityProof, asymmetricPublicKey, storePubKey);
- }
-
- /**
- * Creates a self-signed X.509 public-key certificate.
- *
- * @param pair KeyPair to create the cert for
- * @return self-signed X509Certificate
- */
- private X509Certificate createSelfSignedCertificate(final KeyPair pair) {
- Security.addProvider(new BouncyCastleProvider());
- final int timeRange = 10000;
- X509Certificate cert = null;
- try {
- X500Name issuerName = new X500Name("CN=TEST2, OU=TEST2, O=TEST2, C=TEST2");
- X500Name subjectName = new X500Name("CN=TEST, OU=TEST, O=TEST, C=TEST");
- BigInteger serialNumber = BigInteger.ONE;
- Date notBefore = new Date(System.currentTimeMillis() - timeRange);
- Date notAfter = new Date(System.currentTimeMillis() + timeRange);
- X509v3CertificateBuilder builder =
- new JcaX509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter,
- subjectName, pair.getPublic());
- ContentSigner signer =
- new JcaContentSignerBuilder("SHA256WithRSA").setProvider("BC").build(
- pair.getPrivate());
- return new JcaX509CertificateConverter().setProvider("BC").getCertificate(
- builder.build(signer));
- } catch (Exception e) {
- fail("Exception occurred while creating a cert", e);
- }
- return cert;
- }
-
-
- /**
- * This internal class handles setup for testing the function
- * generateCredential() from class AbstractProcessor. Because the
- * function is Protected and in a different package than the test,
- * it cannot be accessed directly.
- */
- @Nested
- public class AccessAbstractProcessor extends AbstractProcessor {
-
- /**
- * Constructor.
- *
- * @param privateKey the private key of the ACA
- * @param validDays int for the time in which a certificate is valid.
- */
- public AccessAbstractProcessor(final PrivateKey privateKey,
- final int validDays) {
- super(privateKey, validDays);
- }
-
- /**
- * Public wrapper for the protected function generateCredential(), to access for testing.
- *
- * @param publicKey cannot be null
- * @param endorsementCredential the endorsement credential
- * @param platformCredentials the set of platform credentials
- * @param deviceName The host name used in the subject alternative name
- * @param acaCertificate the aca certificate
- * @return the generated X509 certificate
- */
- public X509Certificate accessGenerateCredential(final PublicKey publicKey,
- final EndorsementCredential endorsementCredential,
- final List platformCredentials,
- final String deviceName,
- final X509Certificate acaCertificate) {
-
- return generateCredential(publicKey,
- endorsementCredential,
- platformCredentials,
- deviceName,
- acaCertificate);
- }
- }
-
}
diff --git a/HIRS_AttestationCA/src/test/resources/tpm2/ak.name b/HIRS_AttestationCA/src/test/resources/public_keys/ak.name
similarity index 100%
rename from HIRS_AttestationCA/src/test/resources/tpm2/ak.name
rename to HIRS_AttestationCA/src/test/resources/public_keys/ak.name
diff --git a/HIRS_AttestationCA/src/test/resources/tpm2/ak.pub b/HIRS_AttestationCA/src/test/resources/public_keys/ak.pub
similarity index 100%
rename from HIRS_AttestationCA/src/test/resources/tpm2/ak.pub
rename to HIRS_AttestationCA/src/test/resources/public_keys/ak.pub
diff --git a/HIRS_AttestationCA/src/test/resources/tpm2/ek.pub b/HIRS_AttestationCA/src/test/resources/public_keys/ek.pub
similarity index 100%
rename from HIRS_AttestationCA/src/test/resources/tpm2/ek.pub
rename to HIRS_AttestationCA/src/test/resources/public_keys/ek.pub
From ac90e40bb503c19b16d2a7fef1815809d5757511 Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Thu, 26 Feb 2026 17:47:16 -0500
Subject: [PATCH 07/25] v3.1_issue_1090: Going to have to complete a function
that makes credential using ecc. Fixed the enum class. Removed throws
exception decorator from methods. Made abstract processor abstract. Might
consider ditching the abstract processor and placing them in a utils class.
This might be a bit more complicated than we imagined.
---
...ionCertificateAuthorityRestController.java | 4 +-
.../persist/enums/PublicKeyAlgorithm.java | 15 +-
.../persist/provision/AbstractProcessor.java | 6 +-
.../provision/IdentityClaimProcessor.java | 14 +-
.../provision/helper/ProvisionUtils.java | 214 +++++++++++-------
...tationCertificateAuthorityServiceTest.java | 2 +-
6 files changed, 143 insertions(+), 112 deletions(-)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
index 5e5f78f92..d7e7130d2 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
@@ -10,8 +10,6 @@
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
-import java.security.GeneralSecurityException;
-
/**
* REST Controller for the ACA that communicates with the Provisioner during the provisioning process.
*/
@@ -41,7 +39,7 @@ public AttestationCertificateAuthorityRestController(
*/
@ResponseBody
@PostMapping(value = "/identity-claim-tpm2/process", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
- public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim) throws GeneralSecurityException {
+ public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim) {
return this.attestationCertificateAuthorityService.processIdentityClaimTpm2(identityClaim);
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
index 06bf362be..8f1eeeb62 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
@@ -4,10 +4,6 @@
import lombok.Getter;
import lombok.ToString;
-import java.security.PublicKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPublicKey;
-
/**
* Enum representing public key algorithms for asymmetric cryptography.
*
@@ -27,30 +23,25 @@ public enum PublicKeyAlgorithm {
/**
* RSA Public Key Algorithm.
*/
- RSA("RSA", RSAPublicKey.class),
+ RSA("RSA"),
/**
* ECC Public Key Algorithm.
*/
- ECC("ECC", ECPublicKey.class),
+ ECC("ECC"),
/**
* Represents an unknown public key algorithm.
* This is used when the application encounters a public key algorithm that is not recognized or supported.
* It may occur if the algorithm is unsupported or not implemented in the current version of the application.
*/
- UNKNOWN("UNKNOWN", null);
+ UNKNOWN("UNKNOWN");
/**
* The name of the cryptographic algorithm.
*/
private final String algorithmName;
- /**
- * The Java Security class corresponding to the public key type used by the algorithm.
- */
- private final Class extends PublicKey> keyClass;
-
/**
* Converts the provided string public key algorithm into an ENUM.
*
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java
index 7d981da83..6b1ac7f3d 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java
@@ -45,7 +45,7 @@
@Getter
@Log4j2
@NoArgsConstructor
-public class AbstractProcessor {
+public abstract class AbstractProcessor {
private int validDays;
@@ -299,10 +299,10 @@ public boolean saveAttestationCertificate(final CertificateRepository certificat
if (issuedAc != null && !issuedAc.isEmpty()
&& (ldevID ? policySettings.isGenerateDevIdCertificateOnExpiration()
: policySettings.isGenerateAttestationCertificateOnExpiration())) {
- if (issuedAc.get(0).getEndValidity().after(currentDate)) {
+ if (issuedAc.getFirst().getEndValidity().after(currentDate)) {
// so the issued AC is not expired
// however are we within the threshold
- days = ProvisionUtils.daysBetween(currentDate, issuedAc.get(0).getEndValidity());
+ days = ProvisionUtils.daysBetween(currentDate, issuedAc.getFirst().getEndValidity());
generateCertificate =
days < (ldevID ? policySettings.getDevIdReissueThreshold()
: policySettings.getReissueThreshold());
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
index 3dcaa6c46..fae13b497 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
@@ -61,7 +61,6 @@
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.cert.CertificateException;
-import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
@@ -164,11 +163,14 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
// parse the EK Public key from the IdentityClaim once for use in supply chain validation
// and later tpm20MakeCredential function
- RSAPublicKey ekPub = ProvisionUtils.parseRSAKeyFromPublicDataSegment(claim.getEkPublicArea().toByteArray());
+ PublicKey endorsementCredentialPublicKey =
+ ProvisionUtils.parsePublicKeyFromPublicDataSegment(publicKeyAlgorithm,
+ claim.getEkPublicArea().toByteArray());
+
AppraisalStatus.Status validationResult = AppraisalStatus.Status.FAIL;
try {
- validationResult = doSupplyChainValidation(claim, ekPub);
+ validationResult = doSupplyChainValidation(claim, endorsementCredentialPublicKey);
} catch (Exception ex) {
log.error(ex.getMessage());
}
@@ -176,9 +178,11 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
ByteString blobStr = ByteString.copyFrom(new byte[]{});
if (validationResult == AppraisalStatus.Status.PASS) {
- RSAPublicKey akPub = ProvisionUtils.parseRSAKeyFromPublicDataSegment(claim.getAkPublicArea().toByteArray());
+ PublicKey akPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(publicKeyAlgorithm,
+ claim.getAkPublicArea().toByteArray());
byte[] nonce = ProvisionUtils.generateRandomBytes(NONCE_LENGTH);
- blobStr = ProvisionUtils.tpm20MakeCredential(ekPub, akPub, nonce);
+ blobStr = ProvisionUtils.tpm20MakeCredential(publicKeyAlgorithm, endorsementCredentialPublicKey, akPub,
+ nonce);
String pcrQuoteMask = PCR_QUOTE_MASK;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index 7ecda93ac..d80e0c013 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -36,10 +36,10 @@
import java.security.cert.X509Certificate;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
-import java.security.spec.ECPoint;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.RSAPublicKeySpec;
+import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
@Log4j2
@@ -85,7 +85,7 @@ public final class ProvisionUtils {
private static final int DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES = 256;
- private static final int DEFAULT_ECC_CURVE_LENGTH_IN_BYTES = 32;
+ private static final int DEFAULT_ECC_KEY_LENGTH_IN_BYTES = 32;
// Constants used to parse out the ak name from the ak public data. Used in generateAkName
private static final String AK_NAME_PREFIX = "000b";
@@ -156,18 +156,18 @@ public static String getPemEncodedCertificate(final X509Certificate certificate)
}
/**
- * Parses a public key from a byte array and returns it as a generic PublicKey.
- * Currently supports RSA and ECC.
+ * Parses a public key from a byte array using one of the two supported public key
+ * algorithm and returns it as a generic PublicKey.
*
* @param publicKeyAlgorithm public key algorithm
- * @param keyBytes the DER-encoded public key bytes
+ * @param publicAreaSegment public area segment generated by TPM 2.0
* @return the parsed PublicKey instance
*/
public static PublicKey parsePublicKeyFromPublicDataSegment(final PublicKeyAlgorithm publicKeyAlgorithm,
- final byte[] keyBytes) {
+ final byte[] publicAreaSegment) {
return switch (publicKeyAlgorithm) {
- case RSA -> parseRSAKeyFromPublicDataSegment(keyBytes);
- case ECC -> parseECCKeyFromPublicDataSegment(keyBytes);
+ case RSA -> parseRSAKeyFromPublicDataSegment(publicAreaSegment);
+ case ECC -> parseECCKeyFromPublicDataSegment(publicAreaSegment);
default -> throw new UnsupportedOperationException("Unsupported or invalid public key algorithm");
};
}
@@ -191,7 +191,7 @@ public static RSAPublicKey parseRSAKeyFromPublicDataSegment(final byte[] publicA
byte[] modulus =
HexUtils.subarray(publicAreaSegment, publicAreaSegmentLen - DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES,
publicAreaSegmentLen - 1);
- return (RSAPublicKey) assembleRSAPublicKey(modulus);
+ return assembleRSAPublicKey(modulus);
}
/**
@@ -200,7 +200,7 @@ public static RSAPublicKey parseRSAKeyFromPublicDataSegment(final byte[] publicA
* @param modulus in byte array form
* @return RSA public key using specific modulus and the well known exponent
*/
- public static PublicKey assembleRSAPublicKey(final byte[] modulus) {
+ public static RSAPublicKey assembleRSAPublicKey(final byte[] modulus) {
final String modulusHexString = Hex.encodeHexString(modulus);
return assembleRSAPublicKey(new BigInteger(modulusHexString, DEFAULT_IV_SIZE));
}
@@ -211,14 +211,14 @@ public static PublicKey assembleRSAPublicKey(final byte[] modulus) {
* @param modulus modulus
* @return RSA public key using the provided integer modulus
*/
- public static PublicKey assembleRSAPublicKey(final BigInteger modulus) {
+ public static RSAPublicKey assembleRSAPublicKey(final BigInteger modulus) {
// generate an RSA key spec using mod and exp
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, EXPONENT);
// create the RSA public key
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
- return keyFactory.generatePublic(keySpec);
+ return (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
throw new UnexpectedServerException(
"Encountered unexpected error creating RSA public key: " + e.getMessage(), e);
@@ -235,112 +235,106 @@ public static PublicKey assembleRSAPublicKey(final BigInteger modulus) {
public static ECPublicKey parseECCKeyFromPublicDataSegment(final byte[] publicAreaSegment) {
final int publicAreaSegmentLen = publicAreaSegment.length;
- if (publicAreaSegmentLen > DEFAULT_ECC_CURVE_LENGTH_IN_BYTES) {
+ if (publicAreaSegmentLen < DEFAULT_ECC_KEY_LENGTH_IN_BYTES) {
final String errorMsg = "Could not parse ECC Public Key due to public data segment not being long enough.";
log.error(errorMsg);
throw new IllegalArgumentException(errorMsg);
}
-// final BigInteger x = new BigInteger("0");
-// final BigInteger y = new BigInteger("0");
+ byte[] eccKeySection =
+ HexUtils.subarray(publicAreaSegment, publicAreaSegmentLen - DEFAULT_ECC_KEY_LENGTH_IN_BYTES,
+ publicAreaSegmentLen - 1);
- return new ECPublicKey() {
- @Override
- public ECPoint getW() {
- return null;
- }
+ return assembleECCPublicKey(eccKeySection);
+ }
- @Override
- public String getAlgorithm() {
- return "";
- }
+ /**
+ * todo
+ */
+ public static ECPublicKey assembleECCPublicKey(final byte[] eccKeySection) {
+ // create the ECC public key
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance("EC");
- @Override
- public String getFormat() {
- return "";
- }
+ // Create an X509EncodedKeySpec object with the byte array
+ X509EncodedKeySpec spec = new X509EncodedKeySpec(eccKeySection);
- @Override
- public byte[] getEncoded() {
- return new byte[0];
- }
- };
+ // Generate the ECC public key from the byte array
+ return (ECPublicKey) keyFactory.generatePublic(spec);
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+ throw new UnexpectedServerException(
+ "Encountered unexpected error creating ECC public key: " + e.getMessage(), e);
+ }
}
-// /**
-// * todo
-// *
-// * @param ecPoint
-// * @return
-// */
-// public static ECPublicKey assembleECCPublicKey(final ECPoint ecPoint) {
-// BigInteger a = new BigInteger("0");
-// BigInteger b = new BigInteger("0");
-//
-// EllipticCurve ellipticCurve = new EllipticCurve(null, a, b);
-// ECParameterSpec ecParameterSpec = null;
-//
-// return (ECPublicKey) assembleECCPublicKey(ecPoint, ecParameterSpec);
-// }
-//
-// /**
-// * todo
-// *
-// * @param ecpoint
-// * @param ecParameterSpec
-// * @return
-// */
-// public static PublicKey assembleECCPublicKey(final ECPoint ecpoint, final ECParameterSpec ecParameterSpec) {
-// final ECPublicKeySpec ecPublicKeySpec = new ECPublicKeySpec(ecpoint, ecParameterSpec);
-//
-// // create the ECC public key
-// try {
-// KeyFactory keyFactory = KeyFactory.getInstance(PublicKeyAlgorithm.ECC.getAlgorithmName());
-// return keyFactory.generatePublic(ecPublicKeySpec);
-// } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
-// throw new UnexpectedServerException(
-// "Encountered unexpected error creating ECC public key: " + e.getMessage(), e);
-// }
-// }
-
/**
- * Performs the first step of the TPM 2.0 identity claim process. Takes an ek, ak, and secret
- * and then generates a seed that is used to generate AES and HMAC keys. Parses the ak name.
- * Encrypts the seed with the public ek. Uses the AES key to encrypt the secret. Uses the HMAC
- * key to generate an HMAC to cover the encrypted secret and the ak name. The output is an
- * encrypted blob that acts as the first part of a challenge-response authentication mechanism
- * to validate an identity claim.
- *
- * Equivalent to calling tpm2_makecredential using tpm2_tools.
- *
- * @param ek endorsement key in the identity claim
- * @param ak attestation key in the identity claim
- * @param secret a nonce
+ * @param publicKeyAlgorithm public key algorithm
+ * @param endorsementPublicKey endorsement key in the identity claim
+ * @param attestationPublicKey attestation key in the identity claim
+ * @param secret a nonce
* @return the encrypted blob forming the identity claim challenge
*/
- public static ByteString tpm20MakeCredential(final RSAPublicKey ek, final RSAPublicKey ak,
- final byte[] secret) {
+ public static ByteString tpm20MakeCredential(
+ final PublicKeyAlgorithm publicKeyAlgorithm,
+ final PublicKey endorsementPublicKey,
+ final PublicKey attestationPublicKey,
+ final byte[] secret) {
// check size of the secret
if (secret.length > MAX_SECRET_LENGTH) {
throw new IllegalArgumentException("Secret must be " + MAX_SECRET_LENGTH
+ " bytes or smaller.");
}
+ return switch (publicKeyAlgorithm) {
+ case RSA -> tpm20MakeCredentialUsingRSA(
+ (RSAPublicKey) endorsementPublicKey,
+ (RSAPublicKey) attestationPublicKey, secret);
+ case ECC -> tpm20MakeCredentialUsingECC(
+ (ECPublicKey) endorsementPublicKey,
+ (ECPublicKey) attestationPublicKey, secret);
+ default -> throw new UnsupportedOperationException("Unsupported or invalid public key algorithm");
+ };
+ }
+
+ /**
+ * Performs the first step of the TPM 2.0 identity claim process using the RSA public key algorithm:
+ *
+ * - Takes an ek, ak, and secret and generates a seed that is used to generate AES and HMAC keys.
+ * - Parses the ak name.
+ * - Encrypts the seed with the public ek.
+ * - Uses the AES key to encrypt the secret.
+ * - Uses the HMAC key to generate an HMAC to cover the encrypted secret and the ak name.
+ *
+ *
+ *
+ * The output is an encrypted blob that acts as the first part of a challenge-response authentication mechanism
+ * to validate an identity claim.
+ *
+ * Equivalent to calling tpm2_makecredential using tpm2_tools.
+ *
+ * @param endorsementRSAKey endorsement key in the identity claim
+ * @param attestationRSAKey attestation key in the identity claim
+ * @param secret a nonce
+ * @return the encrypted blob forming the identity claim challenge
+ */
+ public static ByteString tpm20MakeCredentialUsingRSA(final RSAPublicKey endorsementRSAKey,
+ final RSAPublicKey attestationRSAKey,
+ final byte[] secret) {
// generate a random 32 byte seed
byte[] seed = generateRandomBytes(SEED_LENGTH);
try {
- // encrypt seed with pubEk
+ // encrypt seed with endorsement RSA Public Key
Cipher asymCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
OAEPParameterSpec oaepSpec = new OAEPParameterSpec("SHA-256", "MGF1",
MGF1ParameterSpec.SHA256,
new PSource.PSpecified("IDENTITY\0".getBytes(StandardCharsets.UTF_8)));
- asymCipher.init(Cipher.PUBLIC_KEY, ek, oaepSpec);
+ asymCipher.init(Cipher.PUBLIC_KEY, endorsementRSAKey, oaepSpec);
asymCipher.update(seed);
byte[] encSeed = asymCipher.doFinal();
// generate ak name from akMod
- byte[] akModTemp = ak.getModulus().toByteArray();
+ byte[] akModTemp = attestationRSAKey.getModulus().toByteArray();
byte[] akMod = new byte[DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES];
int startpos = 0;
// BigIntegers are signed, so a modulus that has a first bit of 1
@@ -392,11 +386,54 @@ public static ByteString tpm20MakeCredential(final RSAPublicKey ek, final RSAPub
| InvalidKeyException | InvalidAlgorithmParameterException
| NoSuchPaddingException e) {
throw new IdentityProcessingException(
- "Encountered error while making the identity claim challenge: "
+ "Encountered error while making the identity claim challenge for the provided RSA public keys: "
+ e.getMessage(), e);
}
}
+ /**
+ * Performs the first step of the TPM 2.0 identity claim process using the ECC public key algorithm:
+ *
+ * - Takes an ek, ak, and secret and generates a seed that is used to generate AES and HMAC keys.
+ * - Parses the ak name.
+ * - Encrypts the seed with the public ek.
+ * - Uses the AES key to encrypt the secret.
+ * - Uses the HMAC key to generate an HMAC to cover the encrypted secret and the ak name.
+ *
+ *
+ *
+ * The output is an encrypted blob that acts as the first part of a challenge-response authentication mechanism
+ * to validate an identity claim.
+ *
+ * Equivalent to calling tpm2_makecredential using tpm2_tools.
+ *
+ * @param endorsementECCKey endorsement key in the identity claim
+ * @param attestationECCKey attestation key in the identity claim
+ * @param secret a nonce
+ * @return the encrypted blob forming the identity claim challenge
+ */
+ public static ByteString tpm20MakeCredentialUsingECC(final ECPublicKey endorsementECCKey,
+ final ECPublicKey attestationECCKey,
+ final byte[] secret) {
+
+ // generate a random 32 byte seed
+ byte[] seed = generateRandomBytes(SEED_LENGTH);
+
+ try {
+ // encrypt seed with endorsement ECC Public Key
+ Cipher asymCipher = Cipher.getInstance("");
+
+ } catch (Exception e) {
+ throw new IdentityProcessingException(
+ "Encountered error while making the identity claim challenge for the " +
+ "provided ECC public keys: "
+ + e.getMessage(), e);
+ }
+
+ //todo
+ return ByteString.copyFrom(new byte[]{});
+ }
+
/**
* Assembles a credential blob.
*
@@ -406,7 +443,8 @@ public static ByteString tpm20MakeCredential(final RSAPublicKey ek, final RSAPub
* @param encryptedSeed byte array representation of the encrypted seed
* @return byte array representation of a credential blob
*/
- public static byte[] assembleCredential(final byte[] topSize, final byte[] integrityHmac,
+ public static byte[] assembleCredential(final byte[] topSize,
+ final byte[] integrityHmac,
final byte[] encryptedSecret,
final byte[] encryptedSeed) {
/*
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
index 8862c3797..0ceca17a4 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
@@ -284,7 +284,7 @@ public void testAssembleRSAPublicKeyUsingByteArray() {
final BigInteger modulus = ((RSAPublicKey) keyPair.getPublic()).getModulus();
// perform test
- RSAPublicKey publicKey = (RSAPublicKey) ProvisionUtils.assembleRSAPublicKey(modulus.toByteArray());
+ RSAPublicKey publicKey = ProvisionUtils.assembleRSAPublicKey(modulus.toByteArray());
// assert that the exponent and the modulus are the same. the exponents should be the well
// known prime, 101
From b3b02595b9e35e0049a5133ea3fc4c344c28f70a Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Thu, 26 Feb 2026 17:52:39 -0500
Subject: [PATCH 08/25] v3.1_issue_1090: Just to quiet spotbug error.
---
.../persist/provision/helper/ProvisionUtils.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index d80e0c013..c6bc14e25 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -417,11 +417,11 @@ public static ByteString tpm20MakeCredentialUsingECC(final ECPublicKey endorseme
final byte[] secret) {
// generate a random 32 byte seed
- byte[] seed = generateRandomBytes(SEED_LENGTH);
+ //byte[] seed = generateRandomBytes(SEED_LENGTH);
try {
// encrypt seed with endorsement ECC Public Key
- Cipher asymCipher = Cipher.getInstance("");
+ // Cipher asymCipher = Cipher.getInstance("");
} catch (Exception e) {
throw new IdentityProcessingException(
From ad14f4897d5764b3c4c8a2a08f1176069418ac68 Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Fri, 27 Feb 2026 14:45:01 -0500
Subject: [PATCH 09/25] v3.1_issue_1090: Changed variable names in the
provisionutils parser methods, moved the restconrtoller, service and service
impl to a package that makes sense for these classes, deleted abstract
processor, moved methods that pertain to each procressor to their respective
processor and moved any common utilities to a util function. Might need to
change the way we extract the public key algorithm for this to work properly.
---
.../persist/provision/AbstractProcessor.java | 347 ------------------
...ionCertificateAuthorityRestController.java | 2 +-
...ttestationCertificateAuthorityService.java | 2 +-
...tationCertificateAuthorityServiceImpl.java | 4 +-
.../CertificateRequestProcessor.java | 181 ++++++++-
.../provision/IdentityClaimProcessor.java | 11 +-
.../helper/CredentialManagementHelper.java | 143 ++++++++
.../provision/helper/ProvisionUtils.java | 24 +-
...tationCertificateAuthorityServiceTest.java | 2 +
package/linux/aca/aca_bootRun.sh | 8 +-
package/linux/aca/aca_setup.sh | 4 +-
11 files changed, 347 insertions(+), 381 deletions(-)
delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/{ => provision}/AttestationCertificateAuthorityRestController.java (98%)
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/{ => provision}/AttestationCertificateAuthorityService.java (95%)
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/{ => provision}/AttestationCertificateAuthorityServiceImpl.java (92%)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java
deleted file mode 100644
index 6b1ac7f3d..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java
+++ /dev/null
@@ -1,347 +0,0 @@
-package hirs.attestationca.persist.provision;
-
-import com.google.protobuf.ByteString;
-import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
-import hirs.attestationca.persist.entity.manager.CertificateRepository;
-import hirs.attestationca.persist.entity.manager.PolicyRepository;
-import hirs.attestationca.persist.entity.userdefined.Certificate;
-import hirs.attestationca.persist.entity.userdefined.Device;
-import hirs.attestationca.persist.entity.userdefined.PolicySettings;
-import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
-import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate;
-import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
-import hirs.attestationca.persist.exceptions.CertificateProcessingException;
-import hirs.attestationca.persist.provision.helper.CredentialManagementHelper;
-import hirs.attestationca.persist.provision.helper.IssuedCertificateAttributeHelper;
-import hirs.attestationca.persist.provision.helper.ProvisionUtils;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-import lombok.extern.log4j.Log4j2;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.BasicConstraints;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.KeyUsage;
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.X509v3CertificateBuilder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
-import org.bouncycastle.operator.ContentSigner;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
-import org.springframework.data.domain.Sort;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-
-@Getter
-@Log4j2
-@NoArgsConstructor
-public abstract class AbstractProcessor {
-
- private int validDays;
-
- private PrivateKey privateKey;
-
- @Setter
- private PolicyRepository policyRepository;
-
- /**
- * Default constructor that sets main class fields.
- *
- * @param privateKey private key used for communication authentication
- * @param validDays property value to set for issued certificates
- */
- public AbstractProcessor(final PrivateKey privateKey,
- final int validDays) {
- this.privateKey = privateKey;
- this.validDays = validDays;
- }
-
- /**
- * Generates a credential using the specified public key.
- *
- * @param publicKey cannot be null
- * @param endorsementCredential the endorsement credential
- * @param platformCredentials the set of platform credentials
- * @param deviceName The host name used in the subject alternative name
- * @param acaCertificate object used to create credential
- * @return identity credential
- */
- protected X509Certificate generateCredential(final PublicKey publicKey,
- final EndorsementCredential endorsementCredential,
- final List platformCredentials,
- final String deviceName,
- final X509Certificate acaCertificate) {
- try {
- // have the certificate expire in the configured number of days
- Calendar expiry = Calendar.getInstance();
- expiry.add(Calendar.DAY_OF_YEAR, getValidDays());
-
- X500Name issuer =
- new X509CertificateHolder(acaCertificate.getEncoded()).getSubject();
- Date notBefore = new Date();
- Date notAfter = expiry.getTime();
- BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
-
- SubjectPublicKeyInfo subjectPublicKeyInfo =
- SubjectPublicKeyInfo.getInstance(publicKey.getEncoded());
-
- // The subject should be left blank, per spec
- X509v3CertificateBuilder builder =
- new X509v3CertificateBuilder(issuer, serialNumber,
- notBefore, notAfter, null /* subjectName */, subjectPublicKeyInfo);
-
- Extension subjectAlternativeName =
- IssuedCertificateAttributeHelper.buildSubjectAlternativeNameFromCerts(
- endorsementCredential, platformCredentials, deviceName);
-
- Extension authKeyIdentifier = IssuedCertificateAttributeHelper
- .buildAuthorityKeyIdentifier(acaCertificate);
-
- builder.addExtension(subjectAlternativeName);
- if (authKeyIdentifier != null) {
- builder.addExtension(authKeyIdentifier);
- }
- // identify cert as an AIK with this extension
- if (IssuedCertificateAttributeHelper.EXTENDED_KEY_USAGE_EXTENSION != null) {
- builder.addExtension(IssuedCertificateAttributeHelper.EXTENDED_KEY_USAGE_EXTENSION);
- } else {
- log.warn("Failed to build extended key usage extension and add to AIK");
- throw new IllegalStateException("Extended Key Usage attribute unavailable. "
- + "Unable to issue certificates");
- }
-
- // Add signing extension
- builder.addExtension(
- Extension.keyUsage,
- true,
- new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment)
- );
-
- // Basic constraints
- builder.addExtension(
- Extension.basicConstraints,
- true,
- new BasicConstraints(false)
- );
-
- ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA")
- .setProvider("BC").build(getPrivateKey());
- X509CertificateHolder holder = builder.build(signer);
- return new JcaX509CertificateConverter()
- .setProvider("BC").getCertificate(holder);
- } catch (IOException | OperatorCreationException | CertificateException exception) {
- throw new CertificateProcessingException("Encountered error while generating "
- + "identity credential: " + exception.getMessage(), exception);
- }
- }
-
- /**
- * Helper method to parse an Endorsement Credential from a Protobuf generated
- * IdentityClaim. Will also check if the Endorsement Credential was already uploaded.
- * Persists the Endorsement Credential if it does not already exist.
- *
- * @param identityClaim a Protobuf generated Identity Claim object
- * @param ekPub the endorsement public key from the Identity Claim object
- * @param certificateRepository db connector from certificates
- * @return the Endorsement Credential, if one exists, null otherwise
- */
- protected EndorsementCredential parseEcFromIdentityClaim(
- final ProvisionerTpm2.IdentityClaim identityClaim,
- final PublicKey ekPub, final CertificateRepository certificateRepository) {
- EndorsementCredential endorsementCredential = null;
-
- if (identityClaim.hasEndorsementCredential()) {
- endorsementCredential = CredentialManagementHelper.storeEndorsementCredential(
- certificateRepository,
- identityClaim.getEndorsementCredential().toByteArray(),
- identityClaim.getDv().getNw().getHostname());
- } else if (ekPub != null) {
- log.warn("Endorsement Cred was not in the identity claim from the client."
- + " Checking for uploads.");
- endorsementCredential = getEndorsementCredential(ekPub, certificateRepository);
- } else {
- log.warn("No endorsement credential was received in identity claim and no EK Public"
- + " Key was provided to check for uploaded certificates.");
- }
-
- return endorsementCredential;
- }
-
- /**
- * Helper method to parse a set of Platform Credentials from a Protobuf generated
- * IdentityClaim and Endorsement Credential. Persists the Platform Credentials if they
- * do not already exist.
- *
- * @param identityClaim a Protobuf generated Identity Claim object
- * @param endorsementCredential an endorsement credential to check if platform credentials
- * exist
- * @param certificateRepository db connector from certificates
- * @return the List of Platform Credentials, if they exist, an empty set otherwise
- */
- protected List parsePcsFromIdentityClaim(
- final ProvisionerTpm2.IdentityClaim identityClaim,
- final EndorsementCredential endorsementCredential,
- final CertificateRepository certificateRepository) {
- List platformCredentials = new LinkedList<>();
-
- if (identityClaim.getPlatformCredentialCount() > 0) {
-
- List platformCredentialList = identityClaim.getPlatformCredentialList();
-
- for (ByteString platformCredential : platformCredentialList) {
- if (!platformCredential.isEmpty()) {
- PlatformCredential storedPlatformCredential =
- CredentialManagementHelper.storePlatformCredential(
- certificateRepository, platformCredential.toByteArray(),
- identityClaim.getDv().getNw().getHostname());
-
- if (storedPlatformCredential != null) {
- platformCredentials.add(storedPlatformCredential);
- }
- }
- }
- } else if (endorsementCredential != null) {
- // if none in the identity claim, look for uploaded platform credentials
- log.warn("PC was not in the identity claim from the client. Checking for uploads.");
- platformCredentials.addAll(getPlatformCredentials(certificateRepository, endorsementCredential));
- } else {
- log.warn("No platform credential received in identity claim.");
- }
-
- return platformCredentials;
- }
-
- /**
- * Gets the Endorsement Credential from the DB given the EK public key.
- *
- * @param ekPublicKey the EK public key
- * @param certificateRepository db store manager for certificates
- * @return the Endorsement credential, if found, otherwise null
- */
- private EndorsementCredential getEndorsementCredential(
- final PublicKey ekPublicKey,
- final CertificateRepository certificateRepository) {
- log.debug("Searching for endorsement credential based on public key: {}", ekPublicKey);
-
- if (ekPublicKey == null) {
- throw new IllegalArgumentException("Cannot look up an EC given a null public key");
- }
-
- EndorsementCredential credential = null;
-
- try {
- credential = certificateRepository.findByPublicKeyModulusHexValue(
- Certificate.getPublicKeyModulus(ekPublicKey)
- .toString(Certificate.HEX_BASE));
- } catch (IOException e) {
- log.error("Could not extract public key modulus", e);
- }
-
- if (credential == null) {
- log.warn("Unable to find endorsement credential for public key.");
- } else {
- log.debug("Endorsement credential found.");
- }
-
- return credential;
- }
-
- /**
- * Helper method to create an {@link IssuedAttestationCertificate} object, set its
- * corresponding device and persist it.
- *
- * @param certificateRepository db store manager for certificates
- * @param derEncodedAttestationCertificate the byte array representing the Attestation
- * certificate
- * @param endorsementCredential the endorsement credential used to generate the AC
- * @param platformCredentials the platform credentials used to generate the AC
- * @param device the device to which the attestation certificate is tied
- * @param ldevID whether the certificate is a ldevid
- * @return whether the certificate was saved successfully
- */
- public boolean saveAttestationCertificate(final CertificateRepository certificateRepository,
- final byte[] derEncodedAttestationCertificate,
- final EndorsementCredential endorsementCredential,
- final List platformCredentials,
- final Device device,
- final boolean ldevID) {
- List issuedAc;
- boolean generateCertificate = true;
- PolicyRepository scp = getPolicyRepository();
- PolicySettings policySettings;
- Date currentDate = new Date();
- int days;
- try {
- // save issued certificate
- IssuedAttestationCertificate attCert = new IssuedAttestationCertificate(
- derEncodedAttestationCertificate, endorsementCredential, platformCredentials, ldevID);
-
- if (scp != null) {
- policySettings = scp.findByName("Default");
-
- Sort sortCriteria = Sort.by(Sort.Direction.DESC, "endValidity");
- issuedAc = certificateRepository.findByDeviceIdAndLdevID(device.getId(), ldevID,
- sortCriteria);
-
- generateCertificate = ldevID ? policySettings.isIssueDevIdCertificateEnabled()
- : policySettings.isIssueAttestationCertificateEnabled();
-
- if (issuedAc != null && !issuedAc.isEmpty()
- && (ldevID ? policySettings.isGenerateDevIdCertificateOnExpiration()
- : policySettings.isGenerateAttestationCertificateOnExpiration())) {
- if (issuedAc.getFirst().getEndValidity().after(currentDate)) {
- // so the issued AC is not expired
- // however are we within the threshold
- days = ProvisionUtils.daysBetween(currentDate, issuedAc.getFirst().getEndValidity());
- generateCertificate =
- days < (ldevID ? policySettings.getDevIdReissueThreshold()
- : policySettings.getReissueThreshold());
- }
- }
- }
-
- if (generateCertificate) {
- attCert.setDeviceId(device.getId());
- attCert.setDeviceName(device.getName());
- certificateRepository.save(attCert);
- }
- } catch (Exception e) {
- log.error("Error saving generated Attestation Certificate to database.", e);
- throw new CertificateProcessingException(
- "Encountered error while storing Attestation Certificate: "
- + e.getMessage(), e);
- }
-
- return generateCertificate;
- }
-
- private List getPlatformCredentials(final CertificateRepository certificateRepository,
- final EndorsementCredential ec) {
- List credentials = null;
-
- if (ec == null) {
- log.warn("Cannot look for platform credential(s). Endorsement credential was null.");
- } else {
- log.debug("Searching for platform credential(s) based on holder serial number: {}",
- ec.getSerialNumber());
- credentials = certificateRepository.getByHolderSerialNumber(ec.getSerialNumber());
- if (credentials == null || credentials.isEmpty()) {
- log.warn("No platform credential(s) found");
- } else {
- log.debug("Platform Credential(s) found: {}", credentials.size());
- }
- }
-
- return credentials;
- }
-}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java
similarity index 98%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java
index d7e7130d2..d61680f78 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityRestController.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java
@@ -1,4 +1,4 @@
-package hirs.attestationca.persist;
+package hirs.attestationca.persist.provision;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityService.java
similarity index 95%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityService.java
index cdb9f7081..e1658f29c 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityService.java
@@ -1,4 +1,4 @@
-package hirs.attestationca.persist;
+package hirs.attestationca.persist.provision;
/**
* Interface that defines the responsibilities of the Attestation Certificate Authority service.
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityServiceImpl.java
similarity index 92%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceImpl.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityServiceImpl.java
index 3f89ff106..7b404e7ae 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceImpl.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityServiceImpl.java
@@ -1,7 +1,5 @@
-package hirs.attestationca.persist;
+package hirs.attestationca.persist.provision;
-import hirs.attestationca.persist.provision.CertificateRequestProcessor;
-import hirs.attestationca.persist.provision.IdentityClaimProcessor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
index 46898e34e..a6bcc0d79 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
@@ -12,36 +12,59 @@
import hirs.attestationca.persist.entity.userdefined.PolicySettings;
import hirs.attestationca.persist.entity.userdefined.SupplyChainValidationSummary;
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
+import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import hirs.attestationca.persist.entity.userdefined.info.TPMInfo;
import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
import hirs.attestationca.persist.enums.AppraisalStatus;
import hirs.attestationca.persist.enums.PublicKeyAlgorithm;
import hirs.attestationca.persist.exceptions.CertificateProcessingException;
+import hirs.attestationca.persist.provision.helper.CredentialManagementHelper;
+import hirs.attestationca.persist.provision.helper.IssuedCertificateAttributeHelper;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
import hirs.attestationca.persist.service.SupplyChainValidationService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ArrayUtils;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.KeyUsage;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
+import java.io.IOException;
+import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.PublicKey;
+import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.util.Calendar;
+import java.util.Date;
import java.util.List;
@Service
@Log4j2
-public class CertificateRequestProcessor extends AbstractProcessor {
+public class CertificateRequestProcessor {
private final SupplyChainValidationService supplyChainValidationService;
private final CertificateRepository certificateRepository;
private final DeviceRepository deviceRepository;
private final X509Certificate acaCertificate;
private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
+ private final PolicyRepository policyRepository;
private final PublicKeyAlgorithm publicKeyAlgorithm;
+ private final int certificateValidityInDays;
+ private final PrivateKey privateKey;
/**
* Constructor.
@@ -65,14 +88,15 @@ public CertificateRequestProcessor(final SupplyChainValidationService supplyChai
@Value("${aca.certificates.validity}") final int certificateValidityInDays,
final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
final PolicyRepository policyRepository) {
- super(privateKey, certificateValidityInDays);
+ this.certificateValidityInDays = certificateValidityInDays;
this.supplyChainValidationService = supplyChainValidationService;
this.certificateRepository = certificateRepository;
this.deviceRepository = deviceRepository;
this.acaCertificate = acaCertificate;
this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
this.publicKeyAlgorithm = PublicKeyAlgorithm.fromString(publicKeyAlgorithmStr);
- setPolicyRepository(policyRepository);
+ this.policyRepository = policyRepository;
+ this.privateKey = privateKey;
}
/**
@@ -102,7 +126,6 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
throw new IllegalArgumentException(errorMsg);
}
- final PolicyRepository policyRepository = this.getPolicyRepository();
final PolicySettings policySettings = policyRepository.findByName("Default");
// attempt to deserialize Protobuf CertificateRequest
@@ -139,10 +162,11 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
claim.getAkPublicArea().toByteArray());
// Get Endorsement Credential if it exists or was uploaded
- EndorsementCredential endorsementCredential = parseEcFromIdentityClaim(claim, ekPub, certificateRepository);
+ EndorsementCredential endorsementCredential =
+ CredentialManagementHelper.parseEcFromIdentityClaim(claim, ekPub, certificateRepository);
// Get Platform Credentials if they exist or were uploaded
- List platformCredentials = parsePcsFromIdentityClaim(claim,
+ List platformCredentials = CredentialManagementHelper.parsePcsFromIdentityClaim(claim,
endorsementCredential, certificateRepository);
// Get LDevID public key if it exists
@@ -409,4 +433,149 @@ private AppraisalStatus.Status doQuoteValidation(final Device device) {
return validationResult;
}
+
+ /**
+ * Generates a credential using the specified public key.
+ *
+ * @param publicKey cannot be null
+ * @param endorsementCredential the endorsement credential
+ * @param platformCredentials the set of platform credentials
+ * @param deviceName The host name used in the subject alternative name
+ * @param acaCertificate object used to create credential
+ * @return identity credential
+ */
+ private X509Certificate generateCredential(final PublicKey publicKey,
+ final EndorsementCredential endorsementCredential,
+ final List platformCredentials,
+ final String deviceName,
+ final X509Certificate acaCertificate) {
+ try {
+ // have the certificate expire in the configured number of days
+ Calendar expiry = Calendar.getInstance();
+ expiry.add(Calendar.DAY_OF_YEAR, certificateValidityInDays);
+
+ X500Name issuer =
+ new X509CertificateHolder(acaCertificate.getEncoded()).getSubject();
+ Date notBefore = new Date();
+ Date notAfter = expiry.getTime();
+ BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
+
+ SubjectPublicKeyInfo subjectPublicKeyInfo =
+ SubjectPublicKeyInfo.getInstance(publicKey.getEncoded());
+
+ // The subject should be left blank, per spec
+ X509v3CertificateBuilder builder =
+ new X509v3CertificateBuilder(issuer, serialNumber,
+ notBefore, notAfter, null /* subjectName */, subjectPublicKeyInfo);
+
+ Extension subjectAlternativeName =
+ IssuedCertificateAttributeHelper.buildSubjectAlternativeNameFromCerts(
+ endorsementCredential, platformCredentials, deviceName);
+
+ Extension authKeyIdentifier = IssuedCertificateAttributeHelper
+ .buildAuthorityKeyIdentifier(acaCertificate);
+
+ builder.addExtension(subjectAlternativeName);
+ if (authKeyIdentifier != null) {
+ builder.addExtension(authKeyIdentifier);
+ }
+ // identify cert as an AIK with this extension
+ if (IssuedCertificateAttributeHelper.EXTENDED_KEY_USAGE_EXTENSION != null) {
+ builder.addExtension(IssuedCertificateAttributeHelper.EXTENDED_KEY_USAGE_EXTENSION);
+ } else {
+ log.warn("Failed to build extended key usage extension and add to AIK");
+ throw new IllegalStateException("Extended Key Usage attribute unavailable. "
+ + "Unable to issue certificates");
+ }
+
+ // Add signing extension
+ builder.addExtension(
+ Extension.keyUsage,
+ true,
+ new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment)
+ );
+
+ // Basic constraints
+ builder.addExtension(
+ Extension.basicConstraints,
+ true,
+ new BasicConstraints(false)
+ );
+
+ ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA")
+ .setProvider("BC").build(privateKey);
+ X509CertificateHolder holder = builder.build(signer);
+ return new JcaX509CertificateConverter()
+ .setProvider("BC").getCertificate(holder);
+ } catch (IOException | OperatorCreationException | CertificateException exception) {
+ throw new CertificateProcessingException("Encountered error while generating "
+ + "identity credential: " + exception.getMessage(), exception);
+ }
+ }
+
+ /**
+ * Helper method to create an {@link IssuedAttestationCertificate} object, set its
+ * corresponding device and persist it.
+ *
+ * @param certificateRepository db store manager for certificates
+ * @param derEncodedAttestationCertificate the byte array representing the Attestation
+ * certificate
+ * @param endorsementCredential the endorsement credential used to generate the AC
+ * @param platformCredentials the platform credentials used to generate the AC
+ * @param device the device to which the attestation certificate is tied
+ * @param ldevID whether the certificate is a ldevid
+ * @return whether the certificate was saved successfully
+ */
+ public boolean saveAttestationCertificate(final CertificateRepository certificateRepository,
+ final byte[] derEncodedAttestationCertificate,
+ final EndorsementCredential endorsementCredential,
+ final List platformCredentials,
+ final Device device,
+ final boolean ldevID) {
+ List issuedAc;
+ boolean generateCertificate = true;
+ PolicySettings policySettings;
+ Date currentDate = new Date();
+ int days;
+ try {
+ // save issued certificate
+ IssuedAttestationCertificate attCert = new IssuedAttestationCertificate(
+ derEncodedAttestationCertificate, endorsementCredential, platformCredentials, ldevID);
+
+ policySettings = policyRepository.findByName("Default");
+
+ Sort sortCriteria = Sort.by(Sort.Direction.DESC, "endValidity");
+ issuedAc = certificateRepository.findByDeviceIdAndLdevID(device.getId(), ldevID,
+ sortCriteria);
+
+ generateCertificate = ldevID ? policySettings.isIssueDevIdCertificateEnabled()
+ : policySettings.isIssueAttestationCertificateEnabled();
+
+ if (issuedAc != null && !issuedAc.isEmpty()
+ && (ldevID ? policySettings.isGenerateDevIdCertificateOnExpiration()
+ : policySettings.isGenerateAttestationCertificateOnExpiration())) {
+ if (issuedAc.getFirst().getEndValidity().after(currentDate)) {
+ // so the issued AC is not expired
+ // however are we within the threshold
+ days = ProvisionUtils.daysBetween(currentDate, issuedAc.getFirst().getEndValidity());
+ generateCertificate =
+ days < (ldevID ? policySettings.getDevIdReissueThreshold()
+ : policySettings.getReissueThreshold());
+ }
+ }
+
+ if (generateCertificate) {
+ attCert.setDeviceId(device.getId());
+ attCert.setDeviceName(device.getName());
+ certificateRepository.save(attCert);
+ }
+ } catch (Exception e) {
+ log.error("Error saving generated Attestation Certificate to database.", e);
+ throw new CertificateProcessingException(
+ "Encountered error while storing Attestation Certificate: "
+ + e.getMessage(), e);
+ }
+
+ return generateCertificate;
+ }
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
index fae13b497..d1ce6dc1d 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
@@ -37,6 +37,7 @@
import hirs.attestationca.persist.enums.AppraisalStatus;
import hirs.attestationca.persist.enums.PublicKeyAlgorithm;
import hirs.attestationca.persist.exceptions.IdentityProcessingException;
+import hirs.attestationca.persist.provision.helper.CredentialManagementHelper;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
import hirs.attestationca.persist.service.SupplyChainValidationService;
import hirs.attestationca.persist.validation.SupplyChainCredentialValidator;
@@ -74,7 +75,7 @@
@Service
@Log4j2
-public class IdentityClaimProcessor extends AbstractProcessor {
+public class IdentityClaimProcessor {
/**
* Number of bytes to include in the TPM2.0 nonce.
*/
@@ -90,6 +91,7 @@ public class IdentityClaimProcessor extends AbstractProcessor {
private final ReferenceManifestRepository referenceManifestRepository;
private final ReferenceDigestValueRepository referenceDigestValueRepository;
private final DeviceRepository deviceRepository;
+ private final PolicyRepository policyRepository;
private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
private final PublicKeyAlgorithm publicKeyAlgorithm;
@@ -127,7 +129,7 @@ public IdentityClaimProcessor(
this.deviceRepository = deviceRepository;
this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
this.publicKeyAlgorithm = PublicKeyAlgorithm.fromString(publicKeyAlgorithmStr);
- setPolicyRepository(policyRepository);
+ this.policyRepository = policyRepository;
}
/**
@@ -148,7 +150,6 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
throw new IllegalArgumentException(errorMsg);
}
- final PolicyRepository policyRepository = this.getPolicyRepository();
final PolicySettings policySettings = policyRepository.findByName("Default");
// attempt to deserialize Protobuf IdentityClaim
@@ -283,10 +284,10 @@ private AppraisalStatus.Status doSupplyChainValidation(
// attempt to find an endorsement credential to validate
EndorsementCredential endorsementCredential =
- parseEcFromIdentityClaim(claim, ekPub, certificateRepository);
+ CredentialManagementHelper.parseEcFromIdentityClaim(claim, ekPub, certificateRepository);
// attempt to find platform credentials to validate
- List platformCredentials = parsePcsFromIdentityClaim(claim,
+ List platformCredentials = CredentialManagementHelper.parsePcsFromIdentityClaim(claim,
endorsementCredential, certificateRepository);
// Parse and save device info
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java
index 86a8ea5f2..98c4369be 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java
@@ -1,11 +1,17 @@
package hirs.attestationca.persist.provision.helper;
+import com.google.protobuf.ByteString;
+import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
import hirs.attestationca.persist.DBManagerException;
import hirs.attestationca.persist.entity.manager.CertificateRepository;
+import hirs.attestationca.persist.entity.userdefined.Certificate;
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import lombok.extern.log4j.Log4j2;
+import java.io.IOException;
+import java.security.PublicKey;
+import java.util.LinkedList;
import java.util.List;
@@ -162,4 +168,141 @@ public static PlatformCredential storePlatformCredential(
+ "this method will return a null platform certificate.");
return null;
}
+
+ /**
+ * Helper method to parse an Endorsement Credential from a Protobuf generated
+ * IdentityClaim. Will also check if the Endorsement Credential was already uploaded.
+ * Persists the Endorsement Credential if it does not already exist.
+ *
+ * @param identityClaim a Protobuf generated Identity Claim object
+ * @param ekPub the endorsement public key from the Identity Claim object
+ * @param certificateRepository db connector from certificates
+ * @return the Endorsement Credential, if one exists, null otherwise
+ */
+ public static EndorsementCredential parseEcFromIdentityClaim(
+ final ProvisionerTpm2.IdentityClaim identityClaim,
+ final PublicKey ekPub, final CertificateRepository certificateRepository) {
+ EndorsementCredential endorsementCredential = null;
+
+ if (identityClaim.hasEndorsementCredential()) {
+ endorsementCredential = CredentialManagementHelper.storeEndorsementCredential(
+ certificateRepository,
+ identityClaim.getEndorsementCredential().toByteArray(),
+ identityClaim.getDv().getNw().getHostname());
+ } else if (ekPub != null) {
+ log.warn("Endorsement Cred was not in the identity claim from the client."
+ + " Checking for uploads.");
+ endorsementCredential = getEndorsementCredential(ekPub, certificateRepository);
+ } else {
+ log.warn("No endorsement credential was received in identity claim and no EK Public"
+ + " Key was provided to check for uploaded certificates.");
+ }
+
+ return endorsementCredential;
+ }
+
+ /**
+ * Helper method to parse a set of Platform Credentials from a Protobuf generated
+ * IdentityClaim and Endorsement Credential. Persists the Platform Credentials if they
+ * do not already exist.
+ *
+ * @param identityClaim a Protobuf generated Identity Claim object
+ * @param endorsementCredential an endorsement credential to check if platform credentials
+ * exist
+ * @param certificateRepository db connector from certificates
+ * @return the List of Platform Credentials, if they exist, an empty set otherwise
+ */
+ public static List parsePcsFromIdentityClaim(
+ final ProvisionerTpm2.IdentityClaim identityClaim,
+ final EndorsementCredential endorsementCredential,
+ final CertificateRepository certificateRepository) {
+ List platformCredentials = new LinkedList<>();
+
+ if (identityClaim.getPlatformCredentialCount() > 0) {
+
+ List platformCredentialList = identityClaim.getPlatformCredentialList();
+
+ for (ByteString platformCredential : platformCredentialList) {
+ if (!platformCredential.isEmpty()) {
+ PlatformCredential storedPlatformCredential =
+ CredentialManagementHelper.storePlatformCredential(
+ certificateRepository, platformCredential.toByteArray(),
+ identityClaim.getDv().getNw().getHostname());
+
+ if (storedPlatformCredential != null) {
+ platformCredentials.add(storedPlatformCredential);
+ }
+ }
+ }
+ } else if (endorsementCredential != null) {
+ // if none in the identity claim, look for uploaded platform credentials
+ log.warn("PC was not in the identity claim from the client. Checking for uploads.");
+ platformCredentials.addAll(getPlatformCredentials(certificateRepository, endorsementCredential));
+ } else {
+ log.warn("No platform credential received in identity claim.");
+ }
+
+ return platformCredentials;
+ }
+
+ /**
+ * Gets the Endorsement Credential from the DB given the EK public key.
+ *
+ * @param ekPublicKey the EK public key
+ * @param certificateRepository db store manager for certificates
+ * @return the Endorsement credential, if found, otherwise null
+ */
+ private static EndorsementCredential getEndorsementCredential(
+ final PublicKey ekPublicKey,
+ final CertificateRepository certificateRepository) {
+ log.debug("Searching for endorsement credential based on public key: {}", ekPublicKey);
+
+ if (ekPublicKey == null) {
+ throw new IllegalArgumentException("Cannot look up an EC given a null public key");
+ }
+
+ EndorsementCredential credential = null;
+
+ try {
+ credential = certificateRepository.findByPublicKeyModulusHexValue(
+ Certificate.getPublicKeyModulus(ekPublicKey).toString(Certificate.HEX_BASE));
+ } catch (IOException e) {
+ log.error("Could not extract public key modulus", e);
+ }
+
+ if (credential == null) {
+ log.warn("Unable to find endorsement credential for public key.");
+ } else {
+ log.debug("Endorsement credential found.");
+ }
+
+ return credential;
+ }
+
+ /**
+ * Helper method that retrieves all the platform credentials associated with the provided Endorsement Credential.
+ *
+ * @param certificateRepository certificateRepository
+ * @param ec endorsement credential
+ * @return list of platform credentials
+ */
+ private static List getPlatformCredentials(final CertificateRepository certificateRepository,
+ final EndorsementCredential ec) {
+ List credentials = null;
+
+ if (ec == null) {
+ log.warn("Cannot look for platform credential(s). Endorsement credential was null.");
+ } else {
+ log.debug("Searching for platform credential(s) based on holder serial number: {}",
+ ec.getSerialNumber());
+ credentials = certificateRepository.getByHolderSerialNumber(ec.getSerialNumber());
+ if (credentials == null || credentials.isEmpty()) {
+ log.warn("No platform credential(s) found");
+ } else {
+ log.debug("Platform Credential(s) found: {}", credentials.size());
+ }
+ }
+
+ return credentials;
+ }
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index c6bc14e25..b17eb5651 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -175,13 +175,13 @@ public static PublicKey parsePublicKeyFromPublicDataSegment(final PublicKeyAlgor
/**
* Parses the RSA public key from public data segment generated by TPM 2.0.
*
- * @param publicAreaSegment the public area segment to parse
+ * @param publicDataSegment the public area segment to parse
* @return the RSA public key of the supplied public data
*/
- public static RSAPublicKey parseRSAKeyFromPublicDataSegment(final byte[] publicAreaSegment) {
- final int publicAreaSegmentLen = publicAreaSegment.length;
+ public static RSAPublicKey parseRSAKeyFromPublicDataSegment(final byte[] publicDataSegment) {
+ final int publicDataSegmentLen = publicDataSegment.length;
- if (publicAreaSegmentLen < DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES) {
+ if (publicDataSegmentLen < DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES) {
final String errorMsg = "Could not parse RSA Public Key due to public data segment not being long enough.";
log.error(errorMsg);
throw new IllegalArgumentException(errorMsg);
@@ -189,8 +189,8 @@ public static RSAPublicKey parseRSAKeyFromPublicDataSegment(final byte[] publicA
// public data ends with 256 byte modulus
byte[] modulus =
- HexUtils.subarray(publicAreaSegment, publicAreaSegmentLen - DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES,
- publicAreaSegmentLen - 1);
+ HexUtils.subarray(publicDataSegment, publicDataSegmentLen - DEFAULT_RSA_MODULUS_LENGTH_IN_BYTES,
+ publicDataSegmentLen - 1);
return assembleRSAPublicKey(modulus);
}
@@ -229,21 +229,21 @@ public static RSAPublicKey assembleRSAPublicKey(final BigInteger modulus) {
* todo
* Parses the ECC public key from public data segment generated by TPM 2.0.
*
- * @param publicAreaSegment the public area segment to parse
+ * @param publicDataSegment the public area segment to parse
* @return the ECC public key of the supplied public data
*/
- public static ECPublicKey parseECCKeyFromPublicDataSegment(final byte[] publicAreaSegment) {
- final int publicAreaSegmentLen = publicAreaSegment.length;
+ public static ECPublicKey parseECCKeyFromPublicDataSegment(final byte[] publicDataSegment) {
+ final int publicDataSegmentLen = publicDataSegment.length;
- if (publicAreaSegmentLen < DEFAULT_ECC_KEY_LENGTH_IN_BYTES) {
+ if (publicDataSegmentLen < DEFAULT_ECC_KEY_LENGTH_IN_BYTES) {
final String errorMsg = "Could not parse ECC Public Key due to public data segment not being long enough.";
log.error(errorMsg);
throw new IllegalArgumentException(errorMsg);
}
byte[] eccKeySection =
- HexUtils.subarray(publicAreaSegment, publicAreaSegmentLen - DEFAULT_ECC_KEY_LENGTH_IN_BYTES,
- publicAreaSegmentLen - 1);
+ HexUtils.subarray(publicDataSegment, publicDataSegmentLen - DEFAULT_ECC_KEY_LENGTH_IN_BYTES,
+ publicDataSegmentLen - 1);
return assembleECCPublicKey(eccKeySection);
}
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
index 0ceca17a4..f85de7d7c 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
@@ -1,6 +1,8 @@
package hirs.attestationca.persist;
import hirs.attestationca.persist.exceptions.CertificateProcessingException;
+import hirs.attestationca.persist.provision.AttestationCertificateAuthorityService;
+import hirs.attestationca.persist.provision.AttestationCertificateAuthorityServiceImpl;
import hirs.attestationca.persist.provision.CertificateRequestProcessor;
import hirs.attestationca.persist.provision.IdentityClaimProcessor;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
diff --git a/package/linux/aca/aca_bootRun.sh b/package/linux/aca/aca_bootRun.sh
index b469b0894..d1228d2c1 100755
--- a/package/linux/aca/aca_bootRun.sh
+++ b/package/linux/aca/aca_bootRun.sh
@@ -112,10 +112,10 @@ echo "Starting HIRS ACA on https://localhost:8443/HIRS_AttestationCAPortal/porta
source /etc/hirs/aca/aca.properties;
-# Run the embedded tomcat server with Web TLS enabled and database client TLS enabled by overrding critical parameters
+# Run the embedded tomcat server with Web TLS enabled and database client TLS enabled by overriding critical parameters
# Note "&" is a sub parameter continuation, space represents a new parameter. Spaces and quotes matter.
-# hibernate.connection.url is used fo r the DB connector which established DB TLS connectivity
-# server.ssl arguments support the embeded tomcats use of TLS for the ACA Portal
+# hibernate.connection.url is used for the DB connector which established DB TLS connectivity
+# server.ssl arguments support the embedded tomcats use of TLS for the ACA Portal
CONNECTOR_PARAMS="--hibernate.connection.url=jdbc:mariadb://localhost:3306/hirs_db?autoReconnect=true&\
user=$hirs_db_username&\
password=$hirs_db_password&\
@@ -123,7 +123,7 @@ sslMode=VERIFY_CA&\
serverSslCert=$CERT_CHAIN&\
keyStoreType=PKCS12&\
keyStorePassword=$hirs_pki_password&\
-keyStore="$CLIENT_DB_P12" "
+keyStore=$CLIENT_DB_P12 "
WEB_TLS_PARAMS="--server.ssl.key-store-password=$hirs_pki_password \
--server.ssl.trust-store-password=$hirs_pki_password"
diff --git a/package/linux/aca/aca_setup.sh b/package/linux/aca/aca_setup.sh
index 91b75a49d..054a1d5e2 100755
--- a/package/linux/aca/aca_setup.sh
+++ b/package/linux/aca/aca_setup.sh
@@ -144,7 +144,7 @@ fi
mkdir -p $HIRS_CONF_DIR $LOG_DIR $HIRS_JSON_DIR $ACA_OPT_DIR
touch "$LOG_FILE"
-pushd "$SCRIPT_DIR" &>/dev/null
+pushd "$SCRIPT_DIR" &>/dev/null || echo "Unable to push directory to stack"
# Check if build environment is being used and set up property files
if [ -f $PROP_FILE ]; then
cp -n $PROP_FILE $HIRS_CONF_DIR/
@@ -242,4 +242,4 @@ fi
echo "ACA setup complete" | tee -a "$LOG_FILE"
-popd &>/dev/null
+popd &>/dev/null || echo "Unable to pop directory from the stack"
From a0a49b4d9896babbffbe4b8e13ce44bafdc1961e Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Tue, 3 Mar 2026 16:12:46 -0500
Subject: [PATCH 10/25] v3.1_issue_1090: Converted helper class to service,
started creating services to reduce the lines of code in some of the bigger
processors (and to separate responsibilities). Removed public key algorithm
property in app.properties. Can now extract algo from the alg id inside of a
byte array. Added a new property to Public Key Algorithm enum.
---
.../persist/enums/PublicKeyAlgorithm.java | 34 +-
...ionCertificateAuthorityRestController.java | 1 +
.../provision/IdentityClaimProcessor.java | 896 ------------------
.../provision/helper/ProvisionUtils.java | 37 +-
...ttestationCertificateAuthorityService.java | 2 +-
...tationCertificateAuthorityServiceImpl.java | 2 +-
.../CertificateRequestProcessor.java | 133 +--
.../CredentialManagementService.java} | 259 +++--
.../service/DeviceManagementService.java | 579 +++++++++++
.../service/IdentityClaimProcessor.java | 374 ++++++++
.../service/SupplyChainValidationService.java | 3 +-
...tationCertificateAuthorityServiceTest.java | 19 +-
...a => CredentialManagementServiceTest.java} | 53 +-
.../src/main/resources/application.properties | 1 -
.../main/resources/application.win.properties | 1 -
package/linux/aca/aca_setup.sh | 3 -
16 files changed, 1235 insertions(+), 1162 deletions(-)
delete mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/{ => service}/AttestationCertificateAuthorityService.java (94%)
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/{ => service}/AttestationCertificateAuthorityServiceImpl.java (97%)
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/{ => service}/CertificateRequestProcessor.java (81%)
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/{helper/CredentialManagementHelper.java => service/CredentialManagementService.java} (61%)
create mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceManagementService.java
create mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessor.java
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/{ => provision}/service/SupplyChainValidationService.java (99%)
rename HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/{CredentialManagementHelperTest.java => CredentialManagementServiceTest.java} (60%)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
index 8f1eeeb62..243e56fe2 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
@@ -13,8 +13,9 @@
* {@link #ECC} – Elliptic Curve (EC) public-key algorithm, commonly referred to as ECC.
*
*
- * Each enum constant also holds its corresponding JCA (Java Cryptography Architecture)
- * standard name, which can be used when creating KeyFactory or Cipher instances.
+ * Each enum constant holds the public key algorithm name and id. The ID is listed on the
+ *
+ * TCG Algorithm Registry Version PDF.
*/
@Getter
@AllArgsConstructor
@@ -23,22 +24,26 @@ public enum PublicKeyAlgorithm {
/**
* RSA Public Key Algorithm.
*/
- RSA("RSA"),
+ RSA(0x0001, "RSA"),
/**
* ECC Public Key Algorithm.
*/
- ECC("ECC"),
+ ECC(0x0023, "ECC"),
/**
* Represents an unknown public key algorithm.
* This is used when the application encounters a public key algorithm that is not recognized or supported.
- * It may occur if the algorithm is unsupported or not implemented in the current version of the application.
*/
- UNKNOWN("UNKNOWN");
+ UNKNOWN(0xFFFF, "UNKNOWN");
/**
- * The name of the cryptographic algorithm.
+ * The hexadecimal representation of the algorithm ID.
+ */
+ private final int algorithmId;
+
+ /**
+ * The name of the algorithm.
*/
private final String algorithmName;
@@ -56,5 +61,20 @@ public static PublicKeyAlgorithm fromString(final String algorithmAsString) {
}
return UNKNOWN; // Return UNKNOWN if no match is found
}
+
+ /**
+ * Retrieves the enum by the algorithm ID.
+ *
+ * @param algorithmId algorithm ID
+ * @return ENUM representation of the public key algorithm
+ */
+ public static PublicKeyAlgorithm fromId(final int algorithmId) {
+ for (PublicKeyAlgorithm algo : values()) {
+ if (algo.getAlgorithmId() == algorithmId) {
+ return algo;
+ }
+ }
+ return UNKNOWN; // If no match found, return UNKNOWN
+ }
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java
index d61680f78..0c0e728e1 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java
@@ -1,5 +1,6 @@
package hirs.attestationca.persist.provision;
+import hirs.attestationca.persist.provision.service.AttestationCertificateAuthorityService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
deleted file mode 100644
index d1ce6dc1d..000000000
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java
+++ /dev/null
@@ -1,896 +0,0 @@
-package hirs.attestationca.persist.provision;
-
-import com.google.protobuf.ByteString;
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.util.JsonFormat;
-import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
-import hirs.attestationca.persist.entity.manager.CertificateRepository;
-import hirs.attestationca.persist.entity.manager.ComponentInfoRepository;
-import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
-import hirs.attestationca.persist.entity.manager.DeviceRepository;
-import hirs.attestationca.persist.entity.manager.PolicyRepository;
-import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository;
-import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository;
-import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository;
-import hirs.attestationca.persist.entity.tpm.TPM2ProvisionerState;
-import hirs.attestationca.persist.entity.userdefined.Certificate;
-import hirs.attestationca.persist.entity.userdefined.Device;
-import hirs.attestationca.persist.entity.userdefined.PolicySettings;
-import hirs.attestationca.persist.entity.userdefined.ReferenceManifest;
-import hirs.attestationca.persist.entity.userdefined.SupplyChainValidationSummary;
-import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult;
-import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
-import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
-import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
-import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
-import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
-import hirs.attestationca.persist.entity.userdefined.info.FirmwareInfo;
-import hirs.attestationca.persist.entity.userdefined.info.HardwareInfo;
-import hirs.attestationca.persist.entity.userdefined.info.NetworkInfo;
-import hirs.attestationca.persist.entity.userdefined.info.OSInfo;
-import hirs.attestationca.persist.entity.userdefined.info.TPMInfo;
-import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
-import hirs.attestationca.persist.entity.userdefined.rim.BaseReferenceManifest;
-import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements;
-import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue;
-import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest;
-import hirs.attestationca.persist.enums.AppraisalStatus;
-import hirs.attestationca.persist.enums.PublicKeyAlgorithm;
-import hirs.attestationca.persist.exceptions.IdentityProcessingException;
-import hirs.attestationca.persist.provision.helper.CredentialManagementHelper;
-import hirs.attestationca.persist.provision.helper.ProvisionUtils;
-import hirs.attestationca.persist.service.SupplyChainValidationService;
-import hirs.attestationca.persist.validation.SupplyChainCredentialValidator;
-import hirs.utils.HexUtils;
-import hirs.utils.SwidResource;
-import hirs.utils.enums.DeviceInfoEnums;
-import hirs.utils.tpm.eventlog.TCGEventLog;
-import hirs.utils.tpm.eventlog.TpmPcrEvent;
-import jakarta.xml.bind.UnmarshalException;
-import lombok.extern.log4j.Log4j2;
-import org.apache.commons.codec.binary.Hex;
-import org.apache.commons.lang3.ArrayUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.cert.CertificateException;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-@Service
-@Log4j2
-public class IdentityClaimProcessor {
- /**
- * Number of bytes to include in the TPM2.0 nonce.
- */
- public static final int NONCE_LENGTH = 20;
- private static final String PCR_QUOTE_MASK = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23";
- private static final int NUM_OF_VARIABLES = 5;
- private static final int MAC_BYTES = 6;
-
- private final SupplyChainValidationService supplyChainValidationService;
- private final CertificateRepository certificateRepository;
- private final ComponentResultRepository componentResultRepository;
- private final ComponentInfoRepository componentInfoRepository;
- private final ReferenceManifestRepository referenceManifestRepository;
- private final ReferenceDigestValueRepository referenceDigestValueRepository;
- private final DeviceRepository deviceRepository;
- private final PolicyRepository policyRepository;
- private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
- private final PublicKeyAlgorithm publicKeyAlgorithm;
-
- /**
- * Constructor.
- *
- * @param supplyChainValidationService supply chain validation service
- * @param certificateRepository certificate repository
- * @param componentResultRepository component result repository
- * @param componentInfoRepository component info repository
- * @param referenceManifestRepository reference manifest repository
- * @param referenceDigestValueRepository reference digest value repository
- * @param deviceRepository device repository
- * @param tpm2ProvisionerStateRepository tpm2 provisioner state repository
- * @param policyRepository policy repository
- */
- @Autowired
- public IdentityClaimProcessor(
- @Value("${aca.current.public.key.algorithm}") final String publicKeyAlgorithmStr,
- final SupplyChainValidationService supplyChainValidationService,
- final CertificateRepository certificateRepository,
- final ComponentResultRepository componentResultRepository,
- final ComponentInfoRepository componentInfoRepository,
- final ReferenceManifestRepository referenceManifestRepository,
- final ReferenceDigestValueRepository referenceDigestValueRepository,
- final DeviceRepository deviceRepository,
- final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
- final PolicyRepository policyRepository) {
- this.supplyChainValidationService = supplyChainValidationService;
- this.certificateRepository = certificateRepository;
- this.componentResultRepository = componentResultRepository;
- this.componentInfoRepository = componentInfoRepository;
- this.referenceManifestRepository = referenceManifestRepository;
- this.referenceDigestValueRepository = referenceDigestValueRepository;
- this.deviceRepository = deviceRepository;
- this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
- this.publicKeyAlgorithm = PublicKeyAlgorithm.fromString(publicKeyAlgorithmStr);
- this.policyRepository = policyRepository;
- }
-
- /**
- * Basic implementation of the ACA processIdentityClaimTpm2 method. Parses the claim,
- * stores the device info, performs supply chain validation, generates a nonce,
- * and wraps that nonce with the make credential process before returning it to the client.
- * attCert.setPcrValues(pcrValues);
- *
- * @param identityClaim the request to process, cannot be null
- * @return an identity claim response for the specified request containing a wrapped blob
- */
- public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
- log.info("Identity Claim has been received and is ready to be processed");
-
- if (ArrayUtils.isEmpty(identityClaim)) {
- final String errorMsg = "The IdentityClaim sent by the client cannot be null or empty.";
- log.error(errorMsg);
- throw new IllegalArgumentException(errorMsg);
- }
-
- final PolicySettings policySettings = policyRepository.findByName("Default");
-
- // attempt to deserialize Protobuf IdentityClaim
- ProvisionerTpm2.IdentityClaim claim = ProvisionUtils.parseIdentityClaim(identityClaim);
-
- String identityClaimJsonString = "";
- try {
- identityClaimJsonString = JsonFormat.printer().print(claim);
- } catch (InvalidProtocolBufferException exception) {
- log.error("Identity claim could not be parsed properly into a json string");
- }
-
- // parse the EK Public key from the IdentityClaim once for use in supply chain validation
- // and later tpm20MakeCredential function
- PublicKey endorsementCredentialPublicKey =
- ProvisionUtils.parsePublicKeyFromPublicDataSegment(publicKeyAlgorithm,
- claim.getEkPublicArea().toByteArray());
-
- AppraisalStatus.Status validationResult = AppraisalStatus.Status.FAIL;
-
- try {
- validationResult = doSupplyChainValidation(claim, endorsementCredentialPublicKey);
- } catch (Exception ex) {
- log.error(ex.getMessage());
- }
-
- ByteString blobStr = ByteString.copyFrom(new byte[]{});
-
- if (validationResult == AppraisalStatus.Status.PASS) {
- PublicKey akPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(publicKeyAlgorithm,
- claim.getAkPublicArea().toByteArray());
- byte[] nonce = ProvisionUtils.generateRandomBytes(NONCE_LENGTH);
- blobStr = ProvisionUtils.tpm20MakeCredential(publicKeyAlgorithm, endorsementCredentialPublicKey, akPub,
- nonce);
-
- String pcrQuoteMask = PCR_QUOTE_MASK;
-
- String strNonce = HexUtils.byteArrayToHexString(nonce);
- log.info("Sending nonce: {}", strNonce);
- log.info("Persisting identity claim of length: {}", identityClaim.length);
-
- tpm2ProvisionerStateRepository.save(new TPM2ProvisionerState(nonce, identityClaim));
-
- if (policySettings.isIgnoreImaEnabled()) {
- pcrQuoteMask = PCR_QUOTE_MASK.replace("10,", "");
- }
-
- // Package response
- ProvisionerTpm2.IdentityClaimResponse identityClaimResponse
- = ProvisionerTpm2.IdentityClaimResponse.newBuilder()
- .setCredentialBlob(blobStr).setPcrMask(pcrQuoteMask)
- .setStatus(ProvisionerTpm2.ResponseStatus.PASS)
- .build();
-
- String identityClaimResponseJsonStringAfterSuccess = "";
- try {
- identityClaimResponseJsonStringAfterSuccess =
- JsonFormat.printer().print(identityClaimResponse);
- } catch (InvalidProtocolBufferException exception) {
- log.error("Identity claim response after a successful validation "
- + "could not be parsed properly into a json string");
- }
-
- if (!policySettings.isSaveProtobufToLogNeverEnabled()
- && policySettings.isSaveProtobufToLogAlwaysEnabled()) {
-
- log.info("----------------- Start Of Protobuf Logging Of Identity Claim/Response "
- + " After Successful Validation -----------------");
-
- log.info("Identity Claim object received after a "
- + "successful validation: {}", identityClaimJsonString.isEmpty()
- ? claim : identityClaimJsonString);
-
- log.info("Identity Claim Response object after a "
- + "successful validation: {}", identityClaimResponseJsonStringAfterSuccess.isEmpty()
- ? identityClaimResponse : identityClaimResponseJsonStringAfterSuccess);
-
- log.info("----------------- End Of Protobuf Logging Of Identity Claim/Response "
- + " After Successful Validation -----------------");
- }
-
- return identityClaimResponse.toByteArray();
- } else {
- log.error("Supply chain validation did not succeed. Result is: {}", validationResult);
- // empty response
- ProvisionerTpm2.IdentityClaimResponse identityClaimResponse
- = ProvisionerTpm2.IdentityClaimResponse.newBuilder()
- .setCredentialBlob(blobStr)
- .setStatus(ProvisionerTpm2.ResponseStatus.FAIL)
- .build();
-
- String identityClaimResponseJsonStringAfterFailure = "";
- try {
- identityClaimResponseJsonStringAfterFailure =
- JsonFormat.printer().print(identityClaimResponse);
- } catch (InvalidProtocolBufferException exception) {
- log.error("Identity claim response after a failed validation "
- + "could not be parsed properly into a json string");
- }
-
- if (!policySettings.isSaveProtobufToLogNeverEnabled()
- && (policySettings.isSaveProtobufToLogAlwaysEnabled()
- || policySettings.isSaveProtobufToLogOnFailedValEnabled())) {
- log.info("----------------- Start Of Protobuf Logging Of Identity Claim/Response "
- + " After Failed Validation -----------------");
-
- log.info("Identity Claim object received after a "
- + "failed validation: {}", identityClaimJsonString.isEmpty()
- ? claim : identityClaimJsonString);
-
- log.info("Identity Claim Response object after a "
- + "failed validation: {}", identityClaimResponseJsonStringAfterFailure.isEmpty()
- ? identityClaimResponse : identityClaimResponseJsonStringAfterFailure);
-
- log.info("----------------- End Of Protobuf Logging Of Identity Claim/Response "
- + " After Failed Validation -----------------");
- }
-
- return identityClaimResponse.toByteArray();
- }
- }
-
- /**
- * Performs supply chain validation.
- *
- * @param claim the identity claim
- * @param ekPub the public endorsement key
- * @return the {@link AppraisalStatus} of the supply chain validation
- */
- private AppraisalStatus.Status doSupplyChainValidation(
- final ProvisionerTpm2.IdentityClaim claim, final PublicKey ekPub) throws IOException {
-
- // attempt to find an endorsement credential to validate
- EndorsementCredential endorsementCredential =
- CredentialManagementHelper.parseEcFromIdentityClaim(claim, ekPub, certificateRepository);
-
- // attempt to find platform credentials to validate
- List platformCredentials = CredentialManagementHelper.parsePcsFromIdentityClaim(claim,
- endorsementCredential, certificateRepository);
-
- // Parse and save device info
- Device device = processDeviceInfo(claim);
-
-// device.getDeviceInfo().setPaccorOutputString(claim.getPaccorOutput());
- handleDeviceComponents(device.getDeviceInfo().getNetworkInfo().getHostname(),
- claim.getPaccorOutput());
-
- // There are situations in which the claim is sent with no PCs
- // or a PC from the tpm which will be deprecated
- // this is to check what is in the platform object and pull
- // additional information from the DB if information exists
- if (platformCredentials.size() == 1) {
- List tempList = new LinkedList<>();
- for (PlatformCredential pc : platformCredentials) {
- if (pc != null && pc.getPlatformSerial() != null) {
- tempList.addAll(certificateRepository
- .byBoardSerialNumber(pc.getPlatformSerial()));
- }
- }
-
- platformCredentials.addAll(tempList);
- }
-
- // store component results objects
- for (PlatformCredential platformCredential : platformCredentials) {
- List componentResults = componentResultRepository
- .findByCertificateSerialNumberAndBoardSerialNumber(
- platformCredential.getSerialNumber().toString(),
- platformCredential.getPlatformSerial());
-
- if (componentResults.isEmpty()) {
- savePlatformComponents(platformCredential);
- } else {
- componentResults.forEach((componentResult) -> {
- componentResult.restore();
- componentResult.resetCreateTime();
- componentResultRepository.save(componentResult);
- });
- }
- }
-
- // perform supply chain validation
- SupplyChainValidationSummary summary = supplyChainValidationService.validateSupplyChain(
- endorsementCredential, platformCredentials, device,
- componentInfoRepository.findByDeviceName(device.getName()));
- device.setSummaryId(summary.getId().toString());
-
- // update the validation result in the device
- AppraisalStatus.Status validationResult = summary.getOverallValidationResult();
- device.setSupplyChainValidationStatus(validationResult);
- this.deviceRepository.save(device);
-
- return validationResult;
- }
-
- /**
- * Helper method that utilizes the identity claim to produce a device info report.
- *
- * @param claim identity claim
- * @return device info
- */
- private Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) {
- DeviceInfoReport deviceInfoReport = null;
-
- try {
- deviceInfoReport = parseDeviceInfo(claim);
- } catch (NoSuchAlgorithmException noSaEx) {
- log.error(noSaEx);
- }
-
- if (deviceInfoReport == null) {
- log.error("Failed to deserialize Device Info Report");
- throw new IdentityProcessingException("Device Info Report failed to deserialize "
- + "from Identity Claim");
- }
-
- log.info("Processing Device Info Report");
-
- // store device and device info report.
- Device device = null;
-
- if (deviceInfoReport.getNetworkInfo() != null
- && deviceInfoReport.getNetworkInfo().getHostname() != null
- && !deviceInfoReport.getNetworkInfo().getHostname().isEmpty()) {
- device = this.deviceRepository.findByName(deviceInfoReport.getNetworkInfo().getHostname());
- }
-
- if (device == null) {
- device = new Device(deviceInfoReport);
- }
- device.setDeviceInfo(deviceInfoReport);
- return this.deviceRepository.save(device);
- }
-
- /**
- * Converts a protobuf DeviceInfo object to a HIRS Utils DeviceInfoReport object.
- *
- * @param claim the protobuf serialized identity claim containing the device info
- * @return a HIRS Utils DeviceInfoReport representation of device info
- */
- private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim claim)
- throws NoSuchAlgorithmException {
- ProvisionerTpm2.DeviceInfo dv = claim.getDv();
- String pcrValues = "";
-
- // Get network info
- ProvisionerTpm2.NetworkInfo nwProto = dv.getNw();
-
- InetAddress ip = null;
- try {
- ip = InetAddress.getByName(nwProto.getIpAddress());
- } catch (UnknownHostException uhEx) {
- log.error("Unable to parse IP address: ", uhEx);
- }
- String[] macAddressParts = nwProto.getMacAddress().split(":");
-
- // convert mac hex string to byte values
- byte[] macAddressBytes = new byte[MAC_BYTES];
- Integer hex;
- if (macAddressParts.length == MAC_BYTES) {
- for (int i = 0; i < MAC_BYTES; i++) {
- hex = HexUtils.hexToInt(macAddressParts[i]);
- macAddressBytes[i] = hex.byteValue();
- }
- }
-
- NetworkInfo nw = new NetworkInfo(nwProto.getHostname(), ip, macAddressBytes);
-
- // Get firmware info
- ProvisionerTpm2.FirmwareInfo fwProto = dv.getFw();
- FirmwareInfo fw = new FirmwareInfo(fwProto.getBiosVendor(), fwProto.getBiosVersion(),
- fwProto.getBiosReleaseDate());
-
- // Get OS info
- ProvisionerTpm2.OsInfo osProto = dv.getOs();
- OSInfo os = new OSInfo(osProto.getOsName(), osProto.getOsVersion(), osProto.getOsArch(),
- osProto.getDistribution(), osProto.getDistributionRelease());
-
- // Get hardware info
- ProvisionerTpm2.HardwareInfo hwProto = dv.getHw();
-
- // Make sure chassis info has at least one chassis
- String firstChassisSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
- if (hwProto.getChassisInfoCount() > 0) {
- firstChassisSerialNumber = hwProto.getChassisInfo(0).getSerialNumber();
- }
-
- // Make sure baseboard info has at least one baseboard
- String firstBaseboardSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
- if (hwProto.getBaseboardInfoCount() > 0) {
- firstBaseboardSerialNumber = hwProto.getBaseboardInfo(0).getSerialNumber();
- }
-
- HardwareInfo hw = new HardwareInfo(hwProto.getManufacturer(), hwProto.getProductName(),
- hwProto.getProductVersion(), hwProto.getSystemSerialNumber(),
- firstChassisSerialNumber, firstBaseboardSerialNumber);
-
- if (dv.hasPcrslist()) {
- pcrValues = dv.getPcrslist().toStringUtf8();
- }
-
- // check for RIM Base and Support files, if they don't exist in the database, load them
- String defaultClientName = String.format("%s_%s",
- dv.getHw().getManufacturer(),
- dv.getHw().getProductName());
- BaseReferenceManifest baseRim = null;
- SupportReferenceManifest supportRim = null;
- EventLogMeasurements integrityMeasurements;
- boolean isReplacement = false;
- String replacementRimId = "";
- String tagId = "";
- String fileName = "";
- Pattern pattern = Pattern.compile("([^\\s]+(\\.(?i)(rimpcr|rimel|bin|log))$)");
- Matcher matcher;
- MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
-
- if (dv.getSwidfileCount() > 0) {
- for (ByteString swidFile : dv.getSwidfileList()) {
- try {
- baseRim = (BaseReferenceManifest) referenceManifestRepository
- .findByBase64Hash(Base64.getEncoder()
- .encodeToString(messageDigest
- .digest(swidFile.toByteArray())));
- if (baseRim == null) {
- /*
- Either the swidFile does not have a corresponding base RIM in the backend
- or it was deleted. Check if there is a replacement by comparing tagId against
- all other base RIMs, and then set the corresponding support rim's deviceName.
- */
- baseRim = new BaseReferenceManifest(
- String.format("%s.swidtag",
- defaultClientName),
- swidFile.toByteArray());
- List baseRims = referenceManifestRepository.findAllBaseRims();
- for (BaseReferenceManifest bRim : baseRims) {
- if (bRim.getTagId().equals(baseRim.getTagId())) {
- baseRim = bRim;
- replacementRimId = baseRim.getAssociatedRim().toString();
- isReplacement = true;
- break;
- }
- }
- baseRim.setDeviceName(dv.getNw().getHostname());
- this.referenceManifestRepository.save(baseRim);
- } else if (baseRim.isArchived()) {
- /*
- This block accounts for RIMs that may have been soft-deleted (archived)
- in an older version of the ACA.
- */
- List rims = referenceManifestRepository.findByArchiveFlag(false);
- for (ReferenceManifest rim : rims) {
- if (rim.isBase() && rim.getTagId().equals(baseRim.getTagId())
- && rim.getCreateTime().after(baseRim.getCreateTime())) {
- baseRim.setDeviceName(null);
- baseRim = (BaseReferenceManifest) rim;
- baseRim.setDeviceName(dv.getNw().getHostname());
- }
- }
- if (baseRim.isArchived()) {
- throw new Exception("Unable to locate an unarchived base RIM.");
- } else {
- this.referenceManifestRepository.save(baseRim);
- }
- } else {
- baseRim.setDeviceName(dv.getNw().getHostname());
- this.referenceManifestRepository.save(baseRim);
- }
- tagId = baseRim.getTagId();
- } catch (UnmarshalException e) {
- log.error(e);
- } catch (Exception ex) {
- log.error("Failed to load base rim: {}", ex.getMessage());
- }
- }
- } else {
- log.warn("{} did not send swid tag file...", dv.getNw().getHostname());
- }
-
- if (dv.getLogfileCount() > 0) {
- for (ByteString logFile : dv.getLogfileList()) {
- try {
- supportRim =
- (SupportReferenceManifest) referenceManifestRepository.findByHexDecHashAndRimType(
- Hex.encodeHexString(messageDigest.digest(logFile.toByteArray())),
- ReferenceManifest.SUPPORT_RIM);
- if (supportRim == null) {
- /*
- Either the logFile does not have a corresponding support RIM in the backend
- or it was deleted. The support RIM for a replacement base RIM is handled
- in the previous loop block.
- */
- if (isReplacement) {
- Optional replacementRim =
- referenceManifestRepository.findById(UUID.fromString(replacementRimId));
- if (replacementRim.isPresent()) {
- supportRim = (SupportReferenceManifest) replacementRim.get();
- supportRim.setDeviceName(dv.getNw().getHostname());
- } else {
- throw new Exception("Unable to locate support RIM " + replacementRimId);
- }
- } else {
- supportRim = new SupportReferenceManifest(
- String.format("%s.rimel",
- defaultClientName),
- logFile.toByteArray());
- // this is a validity check
- new TCGEventLog(supportRim.getRimBytes());
- // no issues, continue
- supportRim.setPlatformManufacturer(dv.getHw().getManufacturer());
- supportRim.setPlatformModel(dv.getHw().getProductName());
- supportRim.setFileName(String.format("%s_[%s].rimel", defaultClientName,
- supportRim.getHexDecHash().substring(
- supportRim.getHexDecHash().length() - NUM_OF_VARIABLES)));
- }
- supportRim.setDeviceName(dv.getNw().getHostname());
- this.referenceManifestRepository.save(supportRim);
- } else if (supportRim.isArchived()) {
- /*
- This block accounts for RIMs that may have been soft-deleted (archived)
- in an older version of the ACA.
- */
- List rims = referenceManifestRepository.findByArchiveFlag(false);
- for (ReferenceManifest rim : rims) {
- if (rim.isSupport()
- && rim.getTagId().equals(supportRim.getTagId())
- && rim.getCreateTime().after(supportRim.getCreateTime())) {
- supportRim.setDeviceName(null);
- supportRim = (SupportReferenceManifest) rim;
- supportRim.setDeviceName(dv.getNw().getHostname());
- }
- }
- if (supportRim.isArchived()) {
- throw new Exception("Unable to locate an unarchived support RIM.");
- } else {
- this.referenceManifestRepository.save(supportRim);
- }
- } else {
- supportRim.setDeviceName(dv.getNw().getHostname());
- this.referenceManifestRepository.save(supportRim);
- }
- } catch (IOException ioEx) {
- log.error(ioEx);
- } catch (Exception ex) {
- log.error("Failed to load support rim: {}", ex.getMessage());
- }
- }
- } else {
- log.warn("{} did not send support RIM file...", dv.getNw().getHostname());
- }
-
- //update Support RIMs and Base RIMs.
- for (ByteString swidFile : dv.getSwidfileList()) {
- baseRim = (BaseReferenceManifest) referenceManifestRepository
- .findByBase64Hash(Base64.getEncoder().encodeToString(messageDigest.digest(
- swidFile.toByteArray())));
- if (baseRim != null) {
- // get file name to use
- for (SwidResource swid : baseRim.getFileResources()) {
- matcher = pattern.matcher(swid.getName());
- if (matcher.matches()) {
- //found the file name
- int dotIndex = swid.getName().lastIndexOf(".");
- fileName = swid.getName().substring(0, dotIndex);
- baseRim.setFileName(String.format("%s.swidtag",
- fileName));
- }
-
- // now update support rim
- SupportReferenceManifest dbSupport =
- (SupportReferenceManifest) referenceManifestRepository
- .findByHexDecHashAndRimType(swid.getHashValue(),
- ReferenceManifest.SUPPORT_RIM);
- if (dbSupport != null) {
- dbSupport.setFileName(swid.getName());
- dbSupport.setSwidTagVersion(baseRim.getSwidTagVersion());
- dbSupport.setTagId(baseRim.getTagId());
- dbSupport.setSwidTagVersion(baseRim.getSwidTagVersion());
- dbSupport.setSwidVersion(baseRim.getSwidVersion());
- dbSupport.setSwidPatch(baseRim.isSwidPatch());
- dbSupport.setSwidSupplemental(baseRim.isSwidSupplemental());
- baseRim.setAssociatedRim(dbSupport.getId());
- dbSupport.setUpdated(true);
- dbSupport.setAssociatedRim(baseRim.getId());
- this.referenceManifestRepository.save(dbSupport);
- } else {
- log.warn("Could not locate support RIM with hash {}}", swid.getHashValue());
- }
- }
- this.referenceManifestRepository.save(baseRim);
- }
- }
-
- generateDigestRecords(hw.getManufacturer(), hw.getProductName());
-
- if (dv.hasLivelog()) {
- log.info("Device sent bios measurement log...");
- fileName = String.format("%s.measurement",
- dv.getNw().getHostname());
- try {
- EventLogMeasurements deviceLiveLog = new EventLogMeasurements(fileName,
- dv.getLivelog().toByteArray());
- // find previous version.
- integrityMeasurements = referenceManifestRepository
- .byMeasurementDeviceNameUnarchived(dv.getNw().getHostname());
-
- if (integrityMeasurements != null) {
- // Find previous log and archive it
- integrityMeasurements.archive();
- this.referenceManifestRepository.save(integrityMeasurements);
- }
-
- List baseRims = referenceManifestRepository
- .getBaseByManufacturerModel(dv.getHw().getManufacturer(),
- dv.getHw().getProductName());
- integrityMeasurements = deviceLiveLog;
- integrityMeasurements.setPlatformManufacturer(dv.getHw().getManufacturer());
- integrityMeasurements.setPlatformModel(dv.getHw().getProductName());
- if (tagId != null && !tagId.trim().isEmpty()) {
- integrityMeasurements.setTagId(tagId);
- }
- integrityMeasurements.setDeviceName(dv.getNw().getHostname());
-
- this.referenceManifestRepository.save(integrityMeasurements);
-
- for (BaseReferenceManifest bRim : baseRims) {
- if (bRim != null) {
- // pull the base versions of the swidtag and rimel and set the
- // event log hash for use during provision
- SupportReferenceManifest sBaseRim = referenceManifestRepository
- .getSupportRimEntityById(bRim.getAssociatedRim());
- if (sBaseRim != null) {
- bRim.setEventLogHash(deviceLiveLog.getHexDecHash());
- sBaseRim.setEventLogHash(deviceLiveLog.getHexDecHash());
- referenceManifestRepository.save(bRim);
- referenceManifestRepository.save(sBaseRim);
- } else {
- log.warn("Could not locate support RIM associated with "
- + "base RIM " + bRim.getId());
- }
- }
- }
- } catch (IOException ioEx) {
- log.error(ioEx);
- }
- } else {
- log.warn("{} did not send bios measurement log...", dv.getNw().getHostname());
- }
-
- // Get TPM info, currently unimplemented
- TPMInfo tpmInfo = new TPMInfo(DeviceInfoEnums.NOT_SPECIFIED,
- (short) 0,
- (short) 0,
- (short) 0,
- (short) 0,
- pcrValues.getBytes(StandardCharsets.UTF_8),
- null, null);
-
- // Create final report
- DeviceInfoReport dvReport = new DeviceInfoReport(nw, os, fw, hw, tpmInfo,
- claim.getClientVersion());
- dvReport.setPaccorOutputString(claim.getPaccorOutput());
-
- return dvReport;
- }
-
- /**
- * Helper method that generates digest records using the provided device's manufacturer and model
- * information.
- *
- * @param manufacturer device manufacturer
- * @param model device model
- * @return boolean that represents that status of the digest records generation
- */
- private boolean generateDigestRecords(final String manufacturer, final String model) {
- List rdValues = new LinkedList<>();
- SupportReferenceManifest baseSupportRim = null;
- List supplementalRims = new ArrayList<>();
- List patchRims = new ArrayList<>();
- List dbSupportRims = this.referenceManifestRepository
- .getSupportByManufacturerModel(manufacturer, model);
- List expectedValues = referenceDigestValueRepository
- .findByManufacturerAndModel(manufacturer, model);
-
- Map digestValueMap = new HashMap<>();
- expectedValues.forEach((rdv) -> digestValueMap.put(rdv.getDigestValue(), rdv));
-
- for (SupportReferenceManifest dbSupport : dbSupportRims) {
- if (dbSupport.isSwidPatch()) {
- patchRims.add(dbSupport);
- } else if (dbSupport.isSwidSupplemental()) {
- supplementalRims.add(dbSupport);
- } else {
- // we have a base support rim (verify this is getting set)
- baseSupportRim = dbSupport;
- }
- }
-
- if (baseSupportRim != null
- && referenceDigestValueRepository.findBySupportRimHash(baseSupportRim.getHexDecHash())
- .isEmpty()) {
- try {
- TCGEventLog eventLog = new TCGEventLog(baseSupportRim.getRimBytes());
- ReferenceDigestValue rdv;
- for (TpmPcrEvent tpe : eventLog.getEventList()) {
- rdv = new ReferenceDigestValue(baseSupportRim.getAssociatedRim(),
- baseSupportRim.getId(), manufacturer, model, tpe.getPcrIndex(),
- tpe.getEventDigestStr(), baseSupportRim.getHexDecHash(),
- tpe.getEventTypeStr(),
- false, false, true, tpe.getEventContent());
- rdValues.add(rdv);
- }
-
- // since I have the base already I don't have to care about the backward
- // linkage
- for (SupportReferenceManifest supplemental : supplementalRims) {
- eventLog = new TCGEventLog(supplemental.getRimBytes());
- for (TpmPcrEvent tpe : eventLog.getEventList()) {
- // all RDVs will have the same base rim
- rdv = new ReferenceDigestValue(baseSupportRim.getAssociatedRim(),
- supplemental.getId(), manufacturer, model, tpe.getPcrIndex(),
- tpe.getEventDigestStr(), baseSupportRim.getHexDecHash(),
- tpe.getEventTypeStr(),
- false, false, true, tpe.getEventContent());
- rdValues.add(rdv);
- }
- }
-
- // Save all supplemental values
- ReferenceDigestValue tempRdv;
- for (ReferenceDigestValue subRdv : rdValues) {
- // check if the value already exists
- if (digestValueMap.containsKey(subRdv.getDigestValue())) {
- tempRdv = digestValueMap.get(subRdv.getDigestValue());
- if (tempRdv.getPcrIndex() != subRdv.getPcrIndex()
- && !tempRdv.getEventType().equals(subRdv.getEventType())) {
- referenceDigestValueRepository.save(subRdv);
- } else {
- // will this be a problem down the line?
- referenceDigestValueRepository.save(subRdv);
- }
- } else {
- referenceDigestValueRepository.save(subRdv);
- }
- digestValueMap.put(subRdv.getDigestValue(), subRdv);
- }
-
- // if a patch value doesn't exist, error?
- ReferenceDigestValue dbRdv;
- String patchedValue;
- for (SupportReferenceManifest patch : patchRims) {
- eventLog = new TCGEventLog(patch.getRimBytes());
- for (TpmPcrEvent tpe : eventLog.getEventList()) {
- patchedValue = tpe.getEventDigestStr();
- dbRdv = digestValueMap.get(patchedValue);
-
- if (dbRdv == null) {
- log.error("Patching value does not exist ({})", patchedValue);
- } else {
- // WIP - Until we get patch examples
- dbRdv.setPatched(true);
- }
- }
- }
- } catch (CertificateException | NoSuchAlgorithmException | IOException ex) {
- log.error(ex);
- }
- }
-
- return true;
- }
-
- /**
- * Helper method that saves the provided platform certificate's components in the database.
- *
- * @param certificate certificate
- */
- private void savePlatformComponents(final Certificate certificate) throws IOException {
- PlatformCredential platformCredential;
-
- if (certificate instanceof PlatformCredential) {
- platformCredential = (PlatformCredential) certificate;
- ComponentResult componentResult;
-
- if (platformCredential.getPlatformConfigurationV1() != null) {
- List componentIdentifiers = platformCredential
- .getComponentIdentifiers();
-
- for (ComponentIdentifier componentIdentifier : componentIdentifiers) {
- componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
- platformCredential.getSerialNumber().toString(),
- platformCredential.getPlatformChainType(),
- componentIdentifier);
- componentResult.setFailedValidation(false);
- componentResult.setDelta(!platformCredential.isPlatformBase());
- componentResultRepository.save(componentResult);
- }
- } else if (platformCredential.getPlatformConfigurationV2() != null) {
- List componentIdentifiersV2 = platformCredential
- .getComponentIdentifiersV2();
-
- for (ComponentIdentifierV2 componentIdentifierV2 : componentIdentifiersV2) {
- componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
- platformCredential.getSerialNumber().toString(),
- platformCredential.getPlatformChainType(),
- componentIdentifierV2);
- componentResult.setFailedValidation(false);
- componentResult.setDelta(!platformCredential.isPlatformBase());
- componentResultRepository.save(componentResult);
- }
- }
- }
- }
-
- /**
- * Helper method that attempts to find all the provided device's components.
- *
- * @param hostName device's host name
- * @param paccorString string representation of the paccor tool output
- */
- private void handleDeviceComponents(final String hostName, final String paccorString) {
- Map componentInfoMap = new HashMap<>();
-
- try {
- List componentInfos = SupplyChainCredentialValidator
- .getComponentInfoFromPaccorOutput(hostName, paccorString);
-
- // check the DB for like component infos
- List dbComponentInfos = this.componentInfoRepository.findByDeviceName(hostName);
- dbComponentInfos.forEach((infos) -> componentInfoMap.put(infos.hashCode(), infos));
-
- for (ComponentInfo componentInfo : dbComponentInfos) {
- if (componentInfoMap.containsKey(componentInfo.hashCode())) {
- componentInfos.remove(componentInfo);
- }
- }
-
- for (ComponentInfo componentInfo : componentInfos) {
- this.componentInfoRepository.save(componentInfo);
- }
- } catch (IOException ioEx) {
- log.warn("Error parsing paccor string");
- }
- }
-}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index b17eb5651..824066124 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -159,12 +159,12 @@ public static String getPemEncodedCertificate(final X509Certificate certificate)
* Parses a public key from a byte array using one of the two supported public key
* algorithm and returns it as a generic PublicKey.
*
- * @param publicKeyAlgorithm public key algorithm
- * @param publicAreaSegment public area segment generated by TPM 2.0
+ * @param publicAreaSegment public area segment generated by TPM 2.0
* @return the parsed PublicKey instance
*/
- public static PublicKey parsePublicKeyFromPublicDataSegment(final PublicKeyAlgorithm publicKeyAlgorithm,
- final byte[] publicAreaSegment) {
+ public static PublicKey parsePublicKeyFromPublicDataSegment(final byte[] publicAreaSegment) {
+ final PublicKeyAlgorithm publicKeyAlgorithm = determinePublicKeyAlgorithm(publicAreaSegment);
+
return switch (publicKeyAlgorithm) {
case RSA -> parseRSAKeyFromPublicDataSegment(publicAreaSegment);
case ECC -> parseECCKeyFromPublicDataSegment(publicAreaSegment);
@@ -172,6 +172,30 @@ public static PublicKey parsePublicKeyFromPublicDataSegment(final PublicKeyAlgor
};
}
+ /**
+ * Extracts the public key algorithm from the first two bytes of the provided byte array.
+ *
+ * @param byteArray byte array
+ * @return public key algorithm
+ */
+ public static PublicKeyAlgorithm determinePublicKeyAlgorithm(byte[] byteArray) {
+
+ // Return UNKNOWN if there are not enough bytes for comparison
+ if (byteArray == null || byteArray.length < 2) {
+ return PublicKeyAlgorithm.UNKNOWN;
+ }
+
+ // Extract the first two bytes from the byte array and combine them into a 16-bit integer (algorithm ID).
+ // - `byteArray[0] & 0xFF` ensures the first byte is treated as unsigned (0-255 range).
+ // - `<< 8` shifts the first byte 8 bits to the left, placing it in the higher byte of the 16-bit value.
+ // - `byteArray[1] & 0xFF` ensures the second byte is treated as unsigned, then it occupies the lower byte.
+ // - The bitwise OR (`|`) combines the two parts into a single 16-bit value (int).
+ final int algorithmId = ((byteArray[0] & 0xFF) << 8) | (byteArray[1] & 0xFF);
+
+ // Compare the extracted ID with the enums
+ return PublicKeyAlgorithm.fromId(algorithmId);
+ }
+
/**
* Parses the RSA public key from public data segment generated by TPM 2.0.
*
@@ -268,17 +292,18 @@ public static ECPublicKey assembleECCPublicKey(final byte[] eccKeySection) {
}
/**
- * @param publicKeyAlgorithm public key algorithm
* @param endorsementPublicKey endorsement key in the identity claim
* @param attestationPublicKey attestation key in the identity claim
* @param secret a nonce
* @return the encrypted blob forming the identity claim challenge
*/
public static ByteString tpm20MakeCredential(
- final PublicKeyAlgorithm publicKeyAlgorithm,
final PublicKey endorsementPublicKey,
final PublicKey attestationPublicKey,
final byte[] secret) {
+
+ final PublicKeyAlgorithm publicKeyAlgorithm = PublicKeyAlgorithm.RSA;
+
// check size of the secret
if (secret.length > MAX_SECRET_LENGTH) {
throw new IllegalArgumentException("Secret must be " + MAX_SECRET_LENGTH
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityService.java
similarity index 94%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityService.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityService.java
index e1658f29c..18f46ce79 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityService.java
@@ -1,4 +1,4 @@
-package hirs.attestationca.persist.provision;
+package hirs.attestationca.persist.provision.service;
/**
* Interface that defines the responsibilities of the Attestation Certificate Authority service.
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java
similarity index 97%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityServiceImpl.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java
index 7b404e7ae..70f6b4cae 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityServiceImpl.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java
@@ -1,4 +1,4 @@
-package hirs.attestationca.persist.provision;
+package hirs.attestationca.persist.provision.service;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessor.java
similarity index 81%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessor.java
index a6bcc0d79..cd32cc0aa 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessor.java
@@ -1,9 +1,8 @@
-package hirs.attestationca.persist.provision;
+package hirs.attestationca.persist.provision.service;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
-import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.manager.DeviceRepository;
import hirs.attestationca.persist.entity.manager.PolicyRepository;
import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository;
@@ -12,17 +11,13 @@
import hirs.attestationca.persist.entity.userdefined.PolicySettings;
import hirs.attestationca.persist.entity.userdefined.SupplyChainValidationSummary;
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
-import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import hirs.attestationca.persist.entity.userdefined.info.TPMInfo;
import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
import hirs.attestationca.persist.enums.AppraisalStatus;
-import hirs.attestationca.persist.enums.PublicKeyAlgorithm;
import hirs.attestationca.persist.exceptions.CertificateProcessingException;
-import hirs.attestationca.persist.provision.helper.CredentialManagementHelper;
import hirs.attestationca.persist.provision.helper.IssuedCertificateAttributeHelper;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
-import hirs.attestationca.persist.service.SupplyChainValidationService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ArrayUtils;
import org.bouncycastle.asn1.x500.X500Name;
@@ -39,7 +34,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import java.io.IOException;
@@ -57,12 +51,11 @@
@Log4j2
public class CertificateRequestProcessor {
private final SupplyChainValidationService supplyChainValidationService;
- private final CertificateRepository certificateRepository;
+ private final CredentialManagementService credentialManagementService;
private final DeviceRepository deviceRepository;
- private final X509Certificate acaCertificate;
private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
private final PolicyRepository policyRepository;
- private final PublicKeyAlgorithm publicKeyAlgorithm;
+ private final X509Certificate acaCertificate;
private final int certificateValidityInDays;
private final PrivateKey privateKey;
@@ -70,31 +63,29 @@ public class CertificateRequestProcessor {
* Constructor.
*
* @param supplyChainValidationService object that is used to run provisioning
- * @param certificateRepository db connector for all certificates.
+ * @param credentialManagementService credential management service
* @param deviceRepository database connector for Devices.
+ * @param tpm2ProvisionerStateRepository db connector for provisioner state.
* @param privateKey private key used for communication authentication
* @param acaCertificate object used to create credential
* @param certificateValidityInDays int for the time in which a certificate is valid.
- * @param tpm2ProvisionerStateRepository db connector for provisioner state.
* @param policyRepository db connector for policies.
*/
@Autowired
public CertificateRequestProcessor(final SupplyChainValidationService supplyChainValidationService,
- final CertificateRepository certificateRepository,
+ final CredentialManagementService credentialManagementService,
final DeviceRepository deviceRepository,
+ final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
final PrivateKey privateKey,
@Qualifier("leafACACert") final X509Certificate acaCertificate,
- @Value("${aca.current.public.key.algorithm}") final String publicKeyAlgorithmStr,
@Value("${aca.certificates.validity}") final int certificateValidityInDays,
- final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
final PolicyRepository policyRepository) {
+ this.credentialManagementService = credentialManagementService;
this.certificateValidityInDays = certificateValidityInDays;
this.supplyChainValidationService = supplyChainValidationService;
- this.certificateRepository = certificateRepository;
this.deviceRepository = deviceRepository;
this.acaCertificate = acaCertificate;
this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
- this.publicKeyAlgorithm = PublicKeyAlgorithm.fromString(publicKeyAlgorithmStr);
this.policyRepository = policyRepository;
this.privateKey = privateKey;
}
@@ -154,25 +145,25 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
ProvisionerTpm2.IdentityClaim claim = ProvisionUtils.parseIdentityClaim(identityClaim);
// Get endorsement public key
- PublicKey ekPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(publicKeyAlgorithm,
+ PublicKey ekPublicKey = ProvisionUtils.parsePublicKeyFromPublicDataSegment(
claim.getEkPublicArea().toByteArray());
// Get attestation public key
- PublicKey akPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(publicKeyAlgorithm,
+ PublicKey akPublicKey = ProvisionUtils.parsePublicKeyFromPublicDataSegment(
claim.getAkPublicArea().toByteArray());
// Get Endorsement Credential if it exists or was uploaded
EndorsementCredential endorsementCredential =
- CredentialManagementHelper.parseEcFromIdentityClaim(claim, ekPub, certificateRepository);
+ credentialManagementService.parseEcFromIdentityClaim(claim, ekPublicKey);
// Get Platform Credentials if they exist or were uploaded
- List platformCredentials = CredentialManagementHelper.parsePcsFromIdentityClaim(claim,
- endorsementCredential, certificateRepository);
+ List platformCredentials = credentialManagementService.parsePcsFromIdentityClaim(claim,
+ endorsementCredential);
// Get LDevID public key if it exists
- PublicKey ldevidPub = null;
+ PublicKey ldevidPublicKey = null;
if (claim.hasLdevidPublicArea()) {
- ldevidPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(publicKeyAlgorithm,
+ ldevidPublicKey = ProvisionUtils.parsePublicKeyFromPublicDataSegment(
claim.getLdevidPublicArea().toByteArray());
}
@@ -209,11 +200,12 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
AppraisalStatus.Status validationResult = doQuoteValidation(device);
if (validationResult == AppraisalStatus.Status.PASS) {
// Create signed, attestation certificate
- X509Certificate attestationCertificate = generateCredential(akPub,
+ X509Certificate attestationCertificate = generateCredential(akPublicKey,
endorsementCredential, platformCredentials, deviceName, acaCertificate);
- if (ldevidPub != null) {
+
+ if (ldevidPublicKey != null) {
// Create signed LDevID certificate
- X509Certificate ldevidCertificate = generateCredential(ldevidPub,
+ X509Certificate ldevidCertificate = generateCredential(ldevidPublicKey,
endorsementCredential, platformCredentials, deviceName, acaCertificate);
byte[] derEncodedAttestationCertificate = ProvisionUtils.getDerEncodedCertificate(
attestationCertificate);
@@ -226,26 +218,29 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
// We validated the nonce and made use of the identity claim so state can be deleted
tpm2ProvisionerStateRepository.delete(tpm2ProvisionerState);
- boolean generateAtt = saveAttestationCertificate(certificateRepository,
- derEncodedAttestationCertificate,
- endorsementCredential, platformCredentials, device, false);
+
+ boolean generateAtt =
+ credentialManagementService.saveAttestationCertificate(derEncodedAttestationCertificate,
+ endorsementCredential, platformCredentials, device, false);
+
boolean generateLDevID =
- saveAttestationCertificate(certificateRepository, derEncodedLdevidCertificate,
+ credentialManagementService.saveAttestationCertificate(derEncodedLdevidCertificate,
endorsementCredential, platformCredentials, device, true);
ProvisionerTpm2.CertificateResponse.Builder certificateResponseBuilder =
ProvisionerTpm2.CertificateResponse.
newBuilder().setStatus(ProvisionerTpm2.ResponseStatus.PASS);
+
if (generateAtt) {
certificateResponseBuilder =
certificateResponseBuilder.setCertificate(pemEncodedAttestationCertificate);
}
+
if (generateLDevID) {
certificateResponseBuilder =
certificateResponseBuilder.setLdevidCertificate(pemEncodedLdevidCertificate);
}
- ProvisionerTpm2.CertificateResponse certificateResponse =
- certificateResponseBuilder.build();
+ ProvisionerTpm2.CertificateResponse certificateResponse = certificateResponseBuilder.build();
String certResponseJsonStringAfterSuccess = "";
try {
@@ -291,9 +286,10 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
ProvisionerTpm2.CertificateResponse.
newBuilder().setStatus(ProvisionerTpm2.ResponseStatus.PASS);
- boolean generateAtt = saveAttestationCertificate(certificateRepository,
+ boolean generateAtt = credentialManagementService.saveAttestationCertificate(
derEncodedAttestationCertificate,
endorsementCredential, platformCredentials, device, false);
+
if (generateAtt) {
certificateResponseBuilder =
certificateResponseBuilder.setCertificate(pemEncodedAttestationCertificate);
@@ -377,8 +373,7 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
log.info("------------- Start Of Protobuf Log Of Certificate Request After Failed "
+ "Validation (Invalid Nonce) -------------");
- log.error("Could not process credential request."
- + " Invalid nonce provided: {}",
+ log.error("Could not process credential request. Invalid nonce provided: {}",
certificateRequestJsonString.isEmpty() ? request : certificateRequestJsonString);
log.info("------------- End Of Protobuf Log Of Certificate Request After Failed "
@@ -512,70 +507,4 @@ private X509Certificate generateCredential(final PublicKey publicKey,
+ "identity credential: " + exception.getMessage(), exception);
}
}
-
- /**
- * Helper method to create an {@link IssuedAttestationCertificate} object, set its
- * corresponding device and persist it.
- *
- * @param certificateRepository db store manager for certificates
- * @param derEncodedAttestationCertificate the byte array representing the Attestation
- * certificate
- * @param endorsementCredential the endorsement credential used to generate the AC
- * @param platformCredentials the platform credentials used to generate the AC
- * @param device the device to which the attestation certificate is tied
- * @param ldevID whether the certificate is a ldevid
- * @return whether the certificate was saved successfully
- */
- public boolean saveAttestationCertificate(final CertificateRepository certificateRepository,
- final byte[] derEncodedAttestationCertificate,
- final EndorsementCredential endorsementCredential,
- final List platformCredentials,
- final Device device,
- final boolean ldevID) {
- List issuedAc;
- boolean generateCertificate = true;
- PolicySettings policySettings;
- Date currentDate = new Date();
- int days;
- try {
- // save issued certificate
- IssuedAttestationCertificate attCert = new IssuedAttestationCertificate(
- derEncodedAttestationCertificate, endorsementCredential, platformCredentials, ldevID);
-
- policySettings = policyRepository.findByName("Default");
-
- Sort sortCriteria = Sort.by(Sort.Direction.DESC, "endValidity");
- issuedAc = certificateRepository.findByDeviceIdAndLdevID(device.getId(), ldevID,
- sortCriteria);
-
- generateCertificate = ldevID ? policySettings.isIssueDevIdCertificateEnabled()
- : policySettings.isIssueAttestationCertificateEnabled();
-
- if (issuedAc != null && !issuedAc.isEmpty()
- && (ldevID ? policySettings.isGenerateDevIdCertificateOnExpiration()
- : policySettings.isGenerateAttestationCertificateOnExpiration())) {
- if (issuedAc.getFirst().getEndValidity().after(currentDate)) {
- // so the issued AC is not expired
- // however are we within the threshold
- days = ProvisionUtils.daysBetween(currentDate, issuedAc.getFirst().getEndValidity());
- generateCertificate =
- days < (ldevID ? policySettings.getDevIdReissueThreshold()
- : policySettings.getReissueThreshold());
- }
- }
-
- if (generateCertificate) {
- attCert.setDeviceId(device.getId());
- attCert.setDeviceName(device.getName());
- certificateRepository.save(attCert);
- }
- } catch (Exception e) {
- log.error("Error saving generated Attestation Certificate to database.", e);
- throw new CertificateProcessingException(
- "Encountered error while storing Attestation Certificate: "
- + e.getMessage(), e);
- }
-
- return generateCertificate;
- }
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java
similarity index 61%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java
index 98c4369be..f983bc894 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java
@@ -1,46 +1,130 @@
-package hirs.attestationca.persist.provision.helper;
+package hirs.attestationca.persist.provision.service;
import com.google.protobuf.ByteString;
import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
import hirs.attestationca.persist.DBManagerException;
import hirs.attestationca.persist.entity.manager.CertificateRepository;
+import hirs.attestationca.persist.entity.manager.PolicyRepository;
import hirs.attestationca.persist.entity.userdefined.Certificate;
+import hirs.attestationca.persist.entity.userdefined.Device;
+import hirs.attestationca.persist.entity.userdefined.PolicySettings;
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
+import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
+import hirs.attestationca.persist.exceptions.CertificateProcessingException;
+import hirs.attestationca.persist.provision.helper.ProvisionUtils;
import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
import java.io.IOException;
import java.security.PublicKey;
+import java.util.Date;
import java.util.LinkedList;
import java.util.List;
/**
- * Utility class which includes credential management functions used by the ACA.
+ * Service layer class that encapsulates credential management functions used by the ACA.
*/
+@Service
@Log4j2
-public final class CredentialManagementHelper {
+public class CredentialManagementService {
+ private final PolicyRepository policyRepository;
+ private final CertificateRepository certificateRepository;
- private CredentialManagementHelper() {
+ /**
+ * Constructor.
+ *
+ * @param policyRepository policy repository
+ * @param certificateRepository certificate repository
+ */
+ @Autowired
+ private CredentialManagementService(final PolicyRepository policyRepository,
+ final CertificateRepository certificateRepository) {
+ this.policyRepository = policyRepository;
+ this.certificateRepository = certificateRepository;
+ }
+
+ /**
+ * Parses an Endorsement Credential from a Protobuf generated
+ * IdentityClaim. Will also check if the Endorsement Credential was already uploaded.
+ * Persists the Endorsement Credential if it does not already exist.
+ *
+ * @param identityClaim a Protobuf generated Identity Claim object
+ * @param ekPublicKey the endorsement public key from the Identity Claim object
+ * @return the Endorsement Credential, if one exists, null otherwise
+ */
+ public EndorsementCredential parseEcFromIdentityClaim(final ProvisionerTpm2.IdentityClaim identityClaim,
+ final PublicKey ekPublicKey) {
+ EndorsementCredential endorsementCredential = null;
+
+ if (identityClaim.hasEndorsementCredential()) {
+ endorsementCredential = storeEndorsementCredential(identityClaim.getEndorsementCredential().toByteArray(),
+ identityClaim.getDv().getNw().getHostname());
+ } else if (ekPublicKey != null) {
+ log.warn("Endorsement Credential was not in the identity claim from the client.Checking for uploads.");
+ endorsementCredential = getEndorsementCredential(ekPublicKey);
+ } else {
+ log.warn("No endorsement credential was received in identity claim and no EK Public"
+ + " Key was provided to check for uploaded certificates.");
+ }
+
+ return endorsementCredential;
+ }
+
+ /**
+ * Helper method to parse a set of Platform Credentials from a Protobuf generated
+ * IdentityClaim and Endorsement Credential. Persists the Platform Credentials if they
+ * do not already exist.
+ *
+ * @param identityClaim a Protobuf generated Identity Claim object
+ * @param endorsementCredential an endorsement credential to check if platform credentials
+ * exist
+ * @return the List of Platform Credentials, if they exist, an empty set otherwise
+ */
+ public List parsePcsFromIdentityClaim(final ProvisionerTpm2.IdentityClaim identityClaim,
+ final EndorsementCredential endorsementCredential) {
+ List platformCredentials = new LinkedList<>();
+
+ if (identityClaim.getPlatformCredentialCount() > 0) {
+
+ List platformCredentialList = identityClaim.getPlatformCredentialList();
+
+ for (ByteString platformCredential : platformCredentialList) {
+ if (!platformCredential.isEmpty()) {
+ PlatformCredential storedPlatformCredential =
+ storePlatformCredential(platformCredential.toByteArray(),
+ identityClaim.getDv().getNw().getHostname());
+
+ if (storedPlatformCredential != null) {
+ platformCredentials.add(storedPlatformCredential);
+ }
+ }
+ }
+ } else if (endorsementCredential != null) {
+ // if none in the identity claim, look for uploaded platform credentials
+ log.warn("PC was not in the identity claim from the client. Checking for uploads.");
+ platformCredentials.addAll(getPlatformCredentials(endorsementCredential));
+ } else {
+ log.warn("No platform credential received in identity claim.");
+ }
+
+ return platformCredentials;
}
/**
* Parses and stores the EK in the cert manager. If the cert is already present and archived,
* it is unarchived.
*
- * @param certificateRepository the certificate manager used for storage
- * @param endorsementBytes the raw EK bytes used for parsing
- * @param deviceName the host name
+ * @param endorsementBytes the raw EK bytes used for parsing
+ * @param deviceName the host name
* @return the parsed, valid EK
* @throws IllegalArgumentException if the provided bytes are not a valid EK.
*/
- public static EndorsementCredential storeEndorsementCredential(
- final CertificateRepository certificateRepository,
- final byte[] endorsementBytes, final String deviceName) throws IllegalArgumentException {
-
- if (certificateRepository == null) {
- throw new IllegalArgumentException("null certificate manager");
- }
+ public EndorsementCredential storeEndorsementCredential(final byte[] endorsementBytes, final String deviceName)
+ throws IllegalArgumentException {
if (endorsementBytes == null) {
throw new IllegalArgumentException("null endorsement credential bytes");
@@ -86,19 +170,11 @@ public static EndorsementCredential storeEndorsementCredential(
* Parses and stores the PC in the cert manager. If the cert is already present and archived,
* it is unarchived.
*
- * @param certificateRepository the certificate manager used for storage
- * @param platformBytes the raw PC bytes used for parsing
- * @param deviceName the host name of the associated machine
+ * @param platformBytes the raw PC bytes used for parsing
+ * @param deviceName the host name of the associated machine
* @return the parsed, valid PC, or null if the provided bytes are not a valid EK.
*/
- public static PlatformCredential storePlatformCredential(
- final CertificateRepository certificateRepository,
- final byte[] platformBytes, final String deviceName) {
-
- if (certificateRepository == null) {
- log.error("The provided certificate repository is null.");
- throw new IllegalArgumentException("null certificate manager");
- }
+ public PlatformCredential storePlatformCredential(final byte[] platformBytes, final String deviceName) {
if (platformBytes == null) {
log.error("The provided platform credential byte array is null.");
@@ -170,91 +246,76 @@ public static PlatformCredential storePlatformCredential(
}
/**
- * Helper method to parse an Endorsement Credential from a Protobuf generated
- * IdentityClaim. Will also check if the Endorsement Credential was already uploaded.
- * Persists the Endorsement Credential if it does not already exist.
+ * Creates an {@link IssuedAttestationCertificate} object and set its corresponding device and persists it.
*
- * @param identityClaim a Protobuf generated Identity Claim object
- * @param ekPub the endorsement public key from the Identity Claim object
- * @param certificateRepository db connector from certificates
- * @return the Endorsement Credential, if one exists, null otherwise
+ * @param derEncodedAttestationCertificate the byte array representing the Attestation
+ * certificate
+ * @param endorsementCredential the endorsement credential used to generate the AC
+ * @param platformCredentials the platform credentials used to generate the AC
+ * @param device the device to which the attestation certificate is tied
+ * @param ldevID whether the certificate is a ldevid
+ * @return whether the certificate was saved successfully
*/
- public static EndorsementCredential parseEcFromIdentityClaim(
- final ProvisionerTpm2.IdentityClaim identityClaim,
- final PublicKey ekPub, final CertificateRepository certificateRepository) {
- EndorsementCredential endorsementCredential = null;
-
- if (identityClaim.hasEndorsementCredential()) {
- endorsementCredential = CredentialManagementHelper.storeEndorsementCredential(
- certificateRepository,
- identityClaim.getEndorsementCredential().toByteArray(),
- identityClaim.getDv().getNw().getHostname());
- } else if (ekPub != null) {
- log.warn("Endorsement Cred was not in the identity claim from the client."
- + " Checking for uploads.");
- endorsementCredential = getEndorsementCredential(ekPub, certificateRepository);
- } else {
- log.warn("No endorsement credential was received in identity claim and no EK Public"
- + " Key was provided to check for uploaded certificates.");
- }
-
- return endorsementCredential;
- }
-
- /**
- * Helper method to parse a set of Platform Credentials from a Protobuf generated
- * IdentityClaim and Endorsement Credential. Persists the Platform Credentials if they
- * do not already exist.
- *
- * @param identityClaim a Protobuf generated Identity Claim object
- * @param endorsementCredential an endorsement credential to check if platform credentials
- * exist
- * @param certificateRepository db connector from certificates
- * @return the List of Platform Credentials, if they exist, an empty set otherwise
- */
- public static List parsePcsFromIdentityClaim(
- final ProvisionerTpm2.IdentityClaim identityClaim,
+ public boolean saveAttestationCertificate(
+ final byte[] derEncodedAttestationCertificate,
final EndorsementCredential endorsementCredential,
- final CertificateRepository certificateRepository) {
- List platformCredentials = new LinkedList<>();
-
- if (identityClaim.getPlatformCredentialCount() > 0) {
-
- List platformCredentialList = identityClaim.getPlatformCredentialList();
-
- for (ByteString platformCredential : platformCredentialList) {
- if (!platformCredential.isEmpty()) {
- PlatformCredential storedPlatformCredential =
- CredentialManagementHelper.storePlatformCredential(
- certificateRepository, platformCredential.toByteArray(),
- identityClaim.getDv().getNw().getHostname());
-
- if (storedPlatformCredential != null) {
- platformCredentials.add(storedPlatformCredential);
- }
+ final List platformCredentials,
+ final Device device,
+ final boolean ldevID) {
+ List issuedAc;
+ boolean generateCertificate = true;
+ PolicySettings policySettings;
+ Date currentDate = new Date();
+ int days;
+ try {
+ // save issued certificate
+ IssuedAttestationCertificate attCert = new IssuedAttestationCertificate(
+ derEncodedAttestationCertificate, endorsementCredential, platformCredentials, ldevID);
+
+ policySettings = policyRepository.findByName("Default");
+
+ Sort sortCriteria = Sort.by(Sort.Direction.DESC, "endValidity");
+ issuedAc = certificateRepository.findByDeviceIdAndLdevID(device.getId(), ldevID,
+ sortCriteria);
+
+ generateCertificate = ldevID ? policySettings.isIssueDevIdCertificateEnabled()
+ : policySettings.isIssueAttestationCertificateEnabled();
+
+ if (issuedAc != null && !issuedAc.isEmpty()
+ && (ldevID ? policySettings.isGenerateDevIdCertificateOnExpiration()
+ : policySettings.isGenerateAttestationCertificateOnExpiration())) {
+ if (issuedAc.getFirst().getEndValidity().after(currentDate)) {
+ // so the issued AC is not expired
+ // however are we within the threshold
+ days = ProvisionUtils.daysBetween(currentDate, issuedAc.getFirst().getEndValidity());
+ generateCertificate =
+ days < (ldevID ? policySettings.getDevIdReissueThreshold()
+ : policySettings.getReissueThreshold());
}
}
- } else if (endorsementCredential != null) {
- // if none in the identity claim, look for uploaded platform credentials
- log.warn("PC was not in the identity claim from the client. Checking for uploads.");
- platformCredentials.addAll(getPlatformCredentials(certificateRepository, endorsementCredential));
- } else {
- log.warn("No platform credential received in identity claim.");
+
+ if (generateCertificate) {
+ attCert.setDeviceId(device.getId());
+ attCert.setDeviceName(device.getName());
+ certificateRepository.save(attCert);
+ }
+ } catch (Exception e) {
+ log.error("Error saving generated Attestation Certificate to database.", e);
+ throw new CertificateProcessingException(
+ "Encountered error while storing Attestation Certificate: "
+ + e.getMessage(), e);
}
- return platformCredentials;
+ return generateCertificate;
}
/**
* Gets the Endorsement Credential from the DB given the EK public key.
*
- * @param ekPublicKey the EK public key
- * @param certificateRepository db store manager for certificates
+ * @param ekPublicKey the EK public key
* @return the Endorsement credential, if found, otherwise null
*/
- private static EndorsementCredential getEndorsementCredential(
- final PublicKey ekPublicKey,
- final CertificateRepository certificateRepository) {
+ private EndorsementCredential getEndorsementCredential(final PublicKey ekPublicKey) {
log.debug("Searching for endorsement credential based on public key: {}", ekPublicKey);
if (ekPublicKey == null) {
@@ -282,12 +343,10 @@ private static EndorsementCredential getEndorsementCredential(
/**
* Helper method that retrieves all the platform credentials associated with the provided Endorsement Credential.
*
- * @param certificateRepository certificateRepository
- * @param ec endorsement credential
+ * @param ec endorsement credential
* @return list of platform credentials
*/
- private static List getPlatformCredentials(final CertificateRepository certificateRepository,
- final EndorsementCredential ec) {
+ private List getPlatformCredentials(final EndorsementCredential ec) {
List credentials = null;
if (ec == null) {
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceManagementService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceManagementService.java
new file mode 100644
index 000000000..ded26b257
--- /dev/null
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceManagementService.java
@@ -0,0 +1,579 @@
+package hirs.attestationca.persist.provision.service;
+
+import com.google.protobuf.ByteString;
+import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
+import hirs.attestationca.persist.entity.manager.DeviceRepository;
+import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository;
+import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository;
+import hirs.attestationca.persist.entity.userdefined.Device;
+import hirs.attestationca.persist.entity.userdefined.ReferenceManifest;
+import hirs.attestationca.persist.entity.userdefined.info.FirmwareInfo;
+import hirs.attestationca.persist.entity.userdefined.info.HardwareInfo;
+import hirs.attestationca.persist.entity.userdefined.info.NetworkInfo;
+import hirs.attestationca.persist.entity.userdefined.info.OSInfo;
+import hirs.attestationca.persist.entity.userdefined.info.TPMInfo;
+import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
+import hirs.attestationca.persist.entity.userdefined.rim.BaseReferenceManifest;
+import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements;
+import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue;
+import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest;
+import hirs.attestationca.persist.exceptions.IdentityProcessingException;
+import hirs.utils.HexUtils;
+import hirs.utils.SwidResource;
+import hirs.utils.enums.DeviceInfoEnums;
+import hirs.utils.tpm.eventlog.TCGEventLog;
+import hirs.utils.tpm.eventlog.TpmPcrEvent;
+import jakarta.xml.bind.UnmarshalException;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.codec.binary.Hex;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Service
+@Log4j2
+public class DeviceManagementService {
+ private static final int NUM_OF_VARIABLES = 5;
+ private static final int MAC_BYTES = 6;
+
+ private final DeviceRepository deviceRepository;
+ private final ReferenceManifestRepository referenceManifestRepository;
+ private final ReferenceDigestValueRepository referenceDigestValueRepository;
+
+ @Autowired
+ public DeviceManagementService(final DeviceRepository deviceRepository,
+ final ReferenceManifestRepository referenceManifestRepository,
+ final ReferenceDigestValueRepository referenceDigestValueRepository) {
+ this.deviceRepository = deviceRepository;
+ this.referenceManifestRepository = referenceManifestRepository;
+ this.referenceDigestValueRepository = referenceDigestValueRepository;
+ }
+
+ /**
+ * Utilizes the identity claim to produce a device info report.
+ *
+ * @param claim identity claim
+ * @return device info
+ */
+ public Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) {
+ DeviceInfoReport deviceInfoReport = null;
+
+ try {
+ deviceInfoReport = parseDeviceInfo(claim);
+ } catch (NoSuchAlgorithmException noSaEx) {
+ log.error(noSaEx);
+ }
+
+ if (deviceInfoReport == null) {
+ log.error("Failed to deserialize Device Info Report");
+ throw new IdentityProcessingException("Device Info Report failed to deserialize "
+ + "from Identity Claim");
+ }
+
+ log.info("Processing Device Info Report");
+
+ // store device and device info report.
+ Device device = null;
+
+ if (deviceInfoReport.getNetworkInfo() != null
+ && deviceInfoReport.getNetworkInfo().getHostname() != null
+ && !deviceInfoReport.getNetworkInfo().getHostname().isEmpty()) {
+ device = this.deviceRepository.findByName(deviceInfoReport.getNetworkInfo().getHostname());
+ }
+
+ if (device == null) {
+ device = new Device(deviceInfoReport);
+ }
+ device.setDeviceInfo(deviceInfoReport);
+ return this.deviceRepository.save(device);
+ }
+
+ /**
+ * Helper method that creates a Device Info Report objec using the provided protobuf identity claim's device info.
+ *
+ * @param protoIdentityClaim the protobuf serialized identity claim containing the device info
+ * @return {@link DeviceInfoReport}
+ */
+ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim protoIdentityClaim)
+ throws NoSuchAlgorithmException {
+ ProvisionerTpm2.DeviceInfo deviceInfoProto = protoIdentityClaim.getDv();
+
+ String pcrValues = "";
+
+ if (deviceInfoProto.hasPcrslist()) {
+ pcrValues = deviceInfoProto.getPcrslist().toStringUtf8();
+ }
+
+ // Get Hardware info
+ HardwareInfo hardwareInfo = getHardwareInfo(deviceInfoProto.getHw());
+
+ retrieveDeviceInfoFromRIMs(deviceInfoProto, hardwareInfo);
+
+ // Get TPM info, currently unimplemented
+ TPMInfo tpmInfo = new TPMInfo(DeviceInfoEnums.NOT_SPECIFIED,
+ (short) 0,
+ (short) 0,
+ (short) 0,
+ (short) 0,
+ pcrValues.getBytes(StandardCharsets.UTF_8),
+ null, null);
+
+ // Get Network info
+ NetworkInfo networkInfo = getNetworkInfo(deviceInfoProto.getNw());
+
+ // Get Firmware info
+ FirmwareInfo firmwareInfo = getFirmwareInfo(deviceInfoProto.getFw());
+
+ // Get OS info
+ OSInfo osInfo = getOSInfo(deviceInfoProto.getOs());
+
+ // Create final report
+ DeviceInfoReport dvReport = new DeviceInfoReport(networkInfo, osInfo, firmwareInfo, hardwareInfo, tpmInfo,
+ protoIdentityClaim.getClientVersion());
+ dvReport.setPaccorOutputString(protoIdentityClaim.getPaccorOutput());
+
+ return dvReport;
+ }
+
+ /**
+ * Helper method that creates a hardware info object using the provided protobuf's version of hardware info.
+ *
+ * @param hardwareInfoProto Protobuf's version of Hardware Info
+ * @return {@link HardwareInfo}
+ */
+ private HardwareInfo getHardwareInfo(ProvisionerTpm2.HardwareInfo hardwareInfoProto) {
+
+ // Make sure chassis info has at least one chassis
+ String firstChassisSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
+ if (hardwareInfoProto.getChassisInfoCount() > 0) {
+ firstChassisSerialNumber = hardwareInfoProto.getChassisInfo(0).getSerialNumber();
+ }
+
+ // Make sure baseboard info has at least one baseboard
+ String firstBaseboardSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
+ if (hardwareInfoProto.getBaseboardInfoCount() > 0) {
+ firstBaseboardSerialNumber = hardwareInfoProto.getBaseboardInfo(0).getSerialNumber();
+ }
+
+ return new HardwareInfo(hardwareInfoProto.getManufacturer(), hardwareInfoProto.getProductName(),
+ hardwareInfoProto.getProductVersion(), hardwareInfoProto.getSystemSerialNumber(),
+ firstChassisSerialNumber, firstBaseboardSerialNumber);
+ }
+
+ /**
+ * @param networkInfoProto Protobuf's version of Network Info
+ * @return {@link NetworkInfo}
+ */
+ private NetworkInfo getNetworkInfo(ProvisionerTpm2.NetworkInfo networkInfoProto) {
+ InetAddress ip = null;
+ try {
+ ip = InetAddress.getByName(networkInfoProto.getIpAddress());
+ } catch (UnknownHostException uhEx) {
+ log.error("Unable to parse IP address: ", uhEx);
+ }
+ String[] macAddressParts = networkInfoProto.getMacAddress().split(":");
+
+ // convert mac hex string to byte values
+ byte[] macAddressBytes = new byte[MAC_BYTES];
+ Integer hex;
+ if (macAddressParts.length == MAC_BYTES) {
+ for (int i = 0; i < MAC_BYTES; i++) {
+ hex = HexUtils.hexToInt(macAddressParts[i]);
+ macAddressBytes[i] = hex.byteValue();
+ }
+ }
+
+ return new NetworkInfo(networkInfoProto.getHostname(), ip, macAddressBytes);
+ }
+
+ /**
+ * @param osInfoProto Protobuf's version of OS Info
+ * @return {@link OSInfo}
+ */
+ private OSInfo getOSInfo(ProvisionerTpm2.OsInfo osInfoProto) {
+ return new OSInfo(osInfoProto.getOsName(), osInfoProto.getOsVersion(), osInfoProto.getOsArch(),
+ osInfoProto.getDistribution(), osInfoProto.getDistributionRelease());
+ }
+
+ /**
+ * @param firmwareInfoProto Protobuf's version of Firmware Info
+ * @return {@link FirmwareInfo}
+ */
+ private FirmwareInfo getFirmwareInfo(ProvisionerTpm2.FirmwareInfo firmwareInfoProto) {
+ return new FirmwareInfo(firmwareInfoProto.getBiosVendor(), firmwareInfoProto.getBiosVersion(),
+ firmwareInfoProto.getBiosReleaseDate());
+ }
+
+ /**
+ * @param deviceInfoProto
+ * @param hw
+ * @throws NoSuchAlgorithmException
+ */
+ private void retrieveDeviceInfoFromRIMs(ProvisionerTpm2.DeviceInfo deviceInfoProto, HardwareInfo hw)
+ throws NoSuchAlgorithmException {
+
+ // check for RIM Base and Support files, if they don't exist in the database, load them
+ final String defaultClientName = String.format("%s_%s", deviceInfoProto.getHw().getManufacturer(),
+ deviceInfoProto.getHw().getProductName());
+
+ BaseReferenceManifest baseRim = null;
+ SupportReferenceManifest supportRim = null;
+ EventLogMeasurements integrityMeasurements;
+ boolean isReplacement = false;
+ String replacementRimId = "";
+ String tagId = "";
+ String fileName = "";
+ Pattern pattern = Pattern.compile("(\\S+(\\.(?i)(rimpcr|rimel|bin|log))$)");
+ Matcher matcher;
+ MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
+
+ if (deviceInfoProto.getSwidfileCount() > 0) {
+ for (ByteString swidFile : deviceInfoProto.getSwidfileList()) {
+ try {
+ baseRim = (BaseReferenceManifest) referenceManifestRepository.findByBase64Hash(Base64.getEncoder()
+ .encodeToString(messageDigest.digest(swidFile.toByteArray())));
+
+ if (baseRim == null) {
+ /*
+ Either the swidFile does not have a corresponding base RIM in the backend
+ or it was deleted. Check if there is a replacement by comparing tagId against
+ all other base RIMs, and then set the corresponding support rim's deviceName.
+ */
+ baseRim = new BaseReferenceManifest(String.format("%s.swidtag", defaultClientName),
+ swidFile.toByteArray());
+
+ List baseRims = referenceManifestRepository.findAllBaseRims();
+
+ for (BaseReferenceManifest bRim : baseRims) {
+ if (bRim.getTagId().equals(baseRim.getTagId())) {
+ baseRim = bRim;
+ replacementRimId = baseRim.getAssociatedRim().toString();
+ isReplacement = true;
+ break;
+ }
+ }
+ baseRim.setDeviceName(deviceInfoProto.getNw().getHostname());
+ this.referenceManifestRepository.save(baseRim);
+ } else if (baseRim.isArchived()) {
+ /*
+ This block accounts for RIMs that may have been soft-deleted (archived)
+ in an older version of the ACA.
+ */
+ List rims = referenceManifestRepository.findByArchiveFlag(false);
+ for (ReferenceManifest rim : rims) {
+ if (rim.isBase() && rim.getTagId().equals(baseRim.getTagId())
+ && rim.getCreateTime().after(baseRim.getCreateTime())) {
+ baseRim.setDeviceName(null);
+ baseRim = (BaseReferenceManifest) rim;
+ baseRim.setDeviceName(deviceInfoProto.getNw().getHostname());
+ }
+ }
+ if (baseRim.isArchived()) {
+ throw new Exception("Unable to locate an unarchived base RIM.");
+ } else {
+ this.referenceManifestRepository.save(baseRim);
+ }
+ } else {
+ baseRim.setDeviceName(deviceInfoProto.getNw().getHostname());
+ this.referenceManifestRepository.save(baseRim);
+ }
+ tagId = baseRim.getTagId();
+ } catch (UnmarshalException e) {
+ log.error(e);
+ } catch (Exception ex) {
+ log.error("Failed to load base rim: {}", ex.getMessage());
+ }
+ }
+ } else {
+ log.warn("{} did not send swid tag file...", deviceInfoProto.getNw().getHostname());
+ }
+
+ if (deviceInfoProto.getLogfileCount() > 0) {
+ for (ByteString logFile : deviceInfoProto.getLogfileList()) {
+ try {
+ supportRim =
+ (SupportReferenceManifest) referenceManifestRepository.findByHexDecHashAndRimType(
+ Hex.encodeHexString(messageDigest.digest(logFile.toByteArray())),
+ ReferenceManifest.SUPPORT_RIM);
+ if (supportRim == null) {
+ /*
+ Either the logFile does not have a corresponding support RIM in the backend
+ or it was deleted. The support RIM for a replacement base RIM is handled
+ in the previous loop block.
+ */
+ if (isReplacement) {
+ Optional replacementRim =
+ referenceManifestRepository.findById(UUID.fromString(replacementRimId));
+ if (replacementRim.isPresent()) {
+ supportRim = (SupportReferenceManifest) replacementRim.get();
+ supportRim.setDeviceName(deviceInfoProto.getNw().getHostname());
+ } else {
+ throw new Exception("Unable to locate support RIM " + replacementRimId);
+ }
+ } else {
+ supportRim = new SupportReferenceManifest(String.format("%s.rimel", defaultClientName),
+ logFile.toByteArray());
+ // this is a validity check
+ new TCGEventLog(supportRim.getRimBytes());
+ // no issues, continue
+ supportRim.setPlatformManufacturer(deviceInfoProto.getHw().getManufacturer());
+ supportRim.setPlatformModel(deviceInfoProto.getHw().getProductName());
+ supportRim.setFileName(String.format("%s_[%s].rimel", defaultClientName,
+ supportRim.getHexDecHash().substring(
+ supportRim.getHexDecHash().length() - NUM_OF_VARIABLES)));
+ }
+ supportRim.setDeviceName(deviceInfoProto.getNw().getHostname());
+ this.referenceManifestRepository.save(supportRim);
+ } else if (supportRim.isArchived()) {
+ /*
+ This block accounts for RIMs that may have been soft-deleted (archived)
+ in an older version of the ACA.
+ */
+ List rims = referenceManifestRepository.findByArchiveFlag(false);
+ for (ReferenceManifest rim : rims) {
+ if (rim.isSupport()
+ && rim.getTagId().equals(supportRim.getTagId())
+ && rim.getCreateTime().after(supportRim.getCreateTime())) {
+ supportRim.setDeviceName(null);
+ supportRim = (SupportReferenceManifest) rim;
+ supportRim.setDeviceName(deviceInfoProto.getNw().getHostname());
+ }
+ }
+ if (supportRim.isArchived()) {
+ throw new Exception("Unable to locate an unarchived support RIM.");
+ } else {
+ this.referenceManifestRepository.save(supportRim);
+ }
+ } else {
+ supportRim.setDeviceName(deviceInfoProto.getNw().getHostname());
+ this.referenceManifestRepository.save(supportRim);
+ }
+ } catch (IOException ioEx) {
+ log.error(ioEx);
+ } catch (Exception ex) {
+ log.error("Failed to load support rim: {}", ex.getMessage());
+ }
+ }
+ } else {
+ log.warn("{} did not send support RIM file...", deviceInfoProto.getNw().getHostname());
+ }
+
+ //update Support RIMs and Base RIMs.
+ for (ByteString swidFile : deviceInfoProto.getSwidfileList()) {
+ baseRim = (BaseReferenceManifest) referenceManifestRepository
+ .findByBase64Hash(Base64.getEncoder().encodeToString(messageDigest.digest(
+ swidFile.toByteArray())));
+ if (baseRim != null) {
+ // get file name to use
+ for (SwidResource swid : baseRim.getFileResources()) {
+ matcher = pattern.matcher(swid.getName());
+ if (matcher.matches()) {
+ //found the file name
+ int dotIndex = swid.getName().lastIndexOf(".");
+ fileName = swid.getName().substring(0, dotIndex);
+ baseRim.setFileName(String.format("%s.swidtag",
+ fileName));
+ }
+
+ // now update support rim
+ SupportReferenceManifest dbSupport =
+ (SupportReferenceManifest) referenceManifestRepository
+ .findByHexDecHashAndRimType(swid.getHashValue(),
+ ReferenceManifest.SUPPORT_RIM);
+ if (dbSupport != null) {
+ dbSupport.setFileName(swid.getName());
+ dbSupport.setSwidTagVersion(baseRim.getSwidTagVersion());
+ dbSupport.setTagId(baseRim.getTagId());
+ dbSupport.setSwidTagVersion(baseRim.getSwidTagVersion());
+ dbSupport.setSwidVersion(baseRim.getSwidVersion());
+ dbSupport.setSwidPatch(baseRim.isSwidPatch());
+ dbSupport.setSwidSupplemental(baseRim.isSwidSupplemental());
+ baseRim.setAssociatedRim(dbSupport.getId());
+ dbSupport.setUpdated(true);
+ dbSupport.setAssociatedRim(baseRim.getId());
+ this.referenceManifestRepository.save(dbSupport);
+ } else {
+ log.warn("Could not locate support RIM with hash {}}", swid.getHashValue());
+ }
+ }
+ this.referenceManifestRepository.save(baseRim);
+ }
+ }
+
+ generateDigestRecords(hw.getManufacturer(), hw.getProductName());
+
+ if (deviceInfoProto.hasLivelog()) {
+ log.info("Device sent bios measurement log...");
+ fileName = String.format("%s.measurement", deviceInfoProto.getNw().getHostname());
+ try {
+ EventLogMeasurements deviceLiveLog = new EventLogMeasurements(fileName,
+ deviceInfoProto.getLivelog().toByteArray());
+ // find previous version.
+ integrityMeasurements = referenceManifestRepository.byMeasurementDeviceNameUnarchived(
+ deviceInfoProto.getNw().getHostname());
+
+ if (integrityMeasurements != null) {
+ // Find previous log and archive it
+ integrityMeasurements.archive();
+ this.referenceManifestRepository.save(integrityMeasurements);
+ }
+
+ List baseRims = referenceManifestRepository.getBaseByManufacturerModel(
+ deviceInfoProto.getHw().getManufacturer(),
+ deviceInfoProto.getHw().getProductName());
+
+ integrityMeasurements = deviceLiveLog;
+ integrityMeasurements.setPlatformManufacturer(deviceInfoProto.getHw().getManufacturer());
+ integrityMeasurements.setPlatformModel(deviceInfoProto.getHw().getProductName());
+
+ if (tagId != null && !tagId.trim().isEmpty()) {
+ integrityMeasurements.setTagId(tagId);
+ }
+
+ integrityMeasurements.setDeviceName(deviceInfoProto.getNw().getHostname());
+
+ this.referenceManifestRepository.save(integrityMeasurements);
+
+ for (BaseReferenceManifest bRim : baseRims) {
+ if (bRim != null) {
+ // pull the base versions of the swidtag and rimel and set the
+ // event log hash for use during provision
+ SupportReferenceManifest sBaseRim = referenceManifestRepository
+ .getSupportRimEntityById(bRim.getAssociatedRim());
+ if (sBaseRim != null) {
+ bRim.setEventLogHash(deviceLiveLog.getHexDecHash());
+ sBaseRim.setEventLogHash(deviceLiveLog.getHexDecHash());
+ referenceManifestRepository.save(bRim);
+ referenceManifestRepository.save(sBaseRim);
+ } else {
+ log.warn("Could not locate support RIM associated with base RIM {}", bRim.getId());
+ }
+ }
+ }
+ } catch (IOException ioEx) {
+ log.error(ioEx);
+ }
+ } else {
+ log.warn("{} did not send bios measurement log...", deviceInfoProto.getNw().getHostname());
+ }
+ }
+
+ /**
+ * Helper method that generates digest records using the provided device's manufacturer and model
+ * information.
+ *
+ * @param manufacturer device manufacturer
+ * @param model device model
+ */
+ private void generateDigestRecords(final String manufacturer, final String model) {
+ List rdValues = new LinkedList<>();
+ SupportReferenceManifest baseSupportRim = null;
+ List supplementalRims = new ArrayList<>();
+ List patchRims = new ArrayList<>();
+ List dbSupportRims = this.referenceManifestRepository
+ .getSupportByManufacturerModel(manufacturer, model);
+ List expectedValues = referenceDigestValueRepository
+ .findByManufacturerAndModel(manufacturer, model);
+
+ Map digestValueMap = new HashMap<>();
+ expectedValues.forEach((rdv) -> digestValueMap.put(rdv.getDigestValue(), rdv));
+
+ for (SupportReferenceManifest dbSupport : dbSupportRims) {
+ if (dbSupport.isSwidPatch()) {
+ patchRims.add(dbSupport);
+ } else if (dbSupport.isSwidSupplemental()) {
+ supplementalRims.add(dbSupport);
+ } else {
+ // we have a base support rim (verify this is getting set)
+ baseSupportRim = dbSupport;
+ }
+ }
+
+ if (baseSupportRim != null &&
+ referenceDigestValueRepository.findBySupportRimHash(baseSupportRim.getHexDecHash()).isEmpty()) {
+ try {
+ TCGEventLog eventLog = new TCGEventLog(baseSupportRim.getRimBytes());
+ ReferenceDigestValue rdv;
+ for (TpmPcrEvent tpe : eventLog.getEventList()) {
+ rdv = new ReferenceDigestValue(baseSupportRim.getAssociatedRim(),
+ baseSupportRim.getId(), manufacturer, model, tpe.getPcrIndex(),
+ tpe.getEventDigestStr(), baseSupportRim.getHexDecHash(),
+ tpe.getEventTypeStr(),
+ false, false, true, tpe.getEventContent());
+ rdValues.add(rdv);
+ }
+
+ // since I have the base already I don't have to care about the backward
+ // linkage
+ for (SupportReferenceManifest supplemental : supplementalRims) {
+ eventLog = new TCGEventLog(supplemental.getRimBytes());
+ for (TpmPcrEvent tpe : eventLog.getEventList()) {
+ // all RDVs will have the same base rim
+ rdv = new ReferenceDigestValue(baseSupportRim.getAssociatedRim(),
+ supplemental.getId(), manufacturer, model, tpe.getPcrIndex(),
+ tpe.getEventDigestStr(), baseSupportRim.getHexDecHash(),
+ tpe.getEventTypeStr(),
+ false, false, true, tpe.getEventContent());
+ rdValues.add(rdv);
+ }
+ }
+
+ // Save all supplemental values
+ ReferenceDigestValue tempRdv;
+ for (ReferenceDigestValue subRdv : rdValues) {
+ // check if the value already exists
+ if (digestValueMap.containsKey(subRdv.getDigestValue())) {
+ tempRdv = digestValueMap.get(subRdv.getDigestValue());
+ if (tempRdv.getPcrIndex() != subRdv.getPcrIndex()
+ && !tempRdv.getEventType().equals(subRdv.getEventType())) {
+ referenceDigestValueRepository.save(subRdv);
+ } else {
+ // will this be a problem down the line?
+ referenceDigestValueRepository.save(subRdv);
+ }
+ } else {
+ referenceDigestValueRepository.save(subRdv);
+ }
+ digestValueMap.put(subRdv.getDigestValue(), subRdv);
+ }
+
+ // if a patch value doesn't exist, error?
+ ReferenceDigestValue dbRdv;
+ String patchedValue;
+ for (SupportReferenceManifest patch : patchRims) {
+ eventLog = new TCGEventLog(patch.getRimBytes());
+ for (TpmPcrEvent tpe : eventLog.getEventList()) {
+ patchedValue = tpe.getEventDigestStr();
+ dbRdv = digestValueMap.get(patchedValue);
+
+ if (dbRdv == null) {
+ log.error("Patching value does not exist ({})", patchedValue);
+ } else {
+ // WIP - Until we get patch examples
+ dbRdv.setPatched(true);
+ }
+ }
+ }
+ } catch (CertificateException | NoSuchAlgorithmException | IOException ex) {
+ log.error(ex);
+ }
+ }
+ }
+}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessor.java
new file mode 100644
index 000000000..eeb9ea073
--- /dev/null
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessor.java
@@ -0,0 +1,374 @@
+package hirs.attestationca.persist.provision.service;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.util.JsonFormat;
+import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
+import hirs.attestationca.persist.entity.manager.CertificateRepository;
+import hirs.attestationca.persist.entity.manager.ComponentInfoRepository;
+import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
+import hirs.attestationca.persist.entity.manager.DeviceRepository;
+import hirs.attestationca.persist.entity.manager.PolicyRepository;
+import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository;
+import hirs.attestationca.persist.entity.tpm.TPM2ProvisionerState;
+import hirs.attestationca.persist.entity.userdefined.Certificate;
+import hirs.attestationca.persist.entity.userdefined.Device;
+import hirs.attestationca.persist.entity.userdefined.PolicySettings;
+import hirs.attestationca.persist.entity.userdefined.SupplyChainValidationSummary;
+import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult;
+import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
+import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
+import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
+import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
+import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
+import hirs.attestationca.persist.enums.AppraisalStatus;
+import hirs.attestationca.persist.provision.helper.ProvisionUtils;
+import hirs.attestationca.persist.validation.SupplyChainCredentialValidator;
+import hirs.utils.HexUtils;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.ArrayUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+@Service
+@Log4j2
+public class IdentityClaimProcessor {
+ /**
+ * Number of bytes to include in the TPM2.0 nonce.
+ */
+ public static final int NONCE_LENGTH = 20;
+ private static final String PCR_QUOTE_MASK = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23";
+
+ private final SupplyChainValidationService supplyChainValidationService;
+ private final CredentialManagementService credentialManagementService;
+ private final DeviceManagementService deviceManagementService;
+ private final CertificateRepository certificateRepository;
+ private final ComponentResultRepository componentResultRepository;
+ private final ComponentInfoRepository componentInfoRepository;
+ private final DeviceRepository deviceRepository;
+ private final PolicyRepository policyRepository;
+ private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
+
+ /**
+ * Constructor.
+ *
+ * @param supplyChainValidationService supply chain validation service
+ * @param certificateRepository certificate repository
+ * @param componentResultRepository component result repository
+ * @param componentInfoRepository component info repository
+ * @param deviceRepository device repository
+ * @param tpm2ProvisionerStateRepository tpm2 provisioner state repository
+ * @param policyRepository policy repository
+ */
+ @Autowired
+ public IdentityClaimProcessor(
+ final SupplyChainValidationService supplyChainValidationService,
+ final CredentialManagementService credentialManagementService,
+ final CertificateRepository certificateRepository,
+ final ComponentResultRepository componentResultRepository,
+ final ComponentInfoRepository componentInfoRepository,
+ final DeviceRepository deviceRepository, DeviceManagementService deviceManagementService,
+ final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
+ final PolicyRepository policyRepository) {
+ this.supplyChainValidationService = supplyChainValidationService;
+ this.credentialManagementService = credentialManagementService;
+ this.certificateRepository = certificateRepository;
+ this.componentResultRepository = componentResultRepository;
+ this.componentInfoRepository = componentInfoRepository;
+ this.deviceRepository = deviceRepository;
+ this.deviceManagementService = deviceManagementService;
+ this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
+ this.policyRepository = policyRepository;
+ }
+
+ /**
+ * Basic implementation of the ACA processIdentityClaimTpm2 method. Parses the claim,
+ * stores the device info, performs supply chain validation, generates a nonce,
+ * and wraps that nonce with the make credential process before returning it to the client.
+ * attCert.setPcrValues(pcrValues);
+ *
+ * @param identityClaim the request to process, cannot be null
+ * @return an identity claim response for the specified request containing a wrapped blob
+ */
+ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
+ log.info("Identity Claim has been received and is ready to be processed");
+
+ if (ArrayUtils.isEmpty(identityClaim)) {
+ final String errorMsg = "The IdentityClaim sent by the client cannot be null or empty.";
+ log.error(errorMsg);
+ throw new IllegalArgumentException(errorMsg);
+ }
+
+ final PolicySettings policySettings = policyRepository.findByName("Default");
+
+ // attempt to deserialize Protobuf IdentityClaim
+ ProvisionerTpm2.IdentityClaim claim = ProvisionUtils.parseIdentityClaim(identityClaim);
+
+ String identityClaimJsonString = "";
+ try {
+ identityClaimJsonString = JsonFormat.printer().print(claim);
+ } catch (InvalidProtocolBufferException exception) {
+ log.error("Identity claim could not be parsed properly into a json string");
+ }
+
+ // parse the EK Public key from the IdentityClaim once for use in supply chain validation
+ // and later tpm20MakeCredential function
+ PublicKey endorsementCredentialPublicKey =
+ ProvisionUtils.parsePublicKeyFromPublicDataSegment(claim.getEkPublicArea().toByteArray());
+
+ AppraisalStatus.Status validationResult = AppraisalStatus.Status.FAIL;
+
+ try {
+ validationResult = doSupplyChainValidation(claim, endorsementCredentialPublicKey);
+ } catch (Exception ex) {
+ log.error(ex.getMessage());
+ }
+
+ ByteString blobStr = ByteString.copyFrom(new byte[]{});
+
+ if (validationResult == AppraisalStatus.Status.PASS) {
+ PublicKey akPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(claim.getAkPublicArea().toByteArray());
+ byte[] nonce = ProvisionUtils.generateRandomBytes(NONCE_LENGTH);
+ blobStr = ProvisionUtils.tpm20MakeCredential(endorsementCredentialPublicKey, akPub,
+ nonce);
+
+ String pcrQuoteMask = PCR_QUOTE_MASK;
+
+ String strNonce = HexUtils.byteArrayToHexString(nonce);
+ log.info("Sending nonce: {}", strNonce);
+ log.info("Persisting identity claim of length: {}", identityClaim.length);
+
+ tpm2ProvisionerStateRepository.save(new TPM2ProvisionerState(nonce, identityClaim));
+
+ if (policySettings.isIgnoreImaEnabled()) {
+ pcrQuoteMask = PCR_QUOTE_MASK.replace("10,", "");
+ }
+
+ // Package response
+ ProvisionerTpm2.IdentityClaimResponse identityClaimResponse
+ = ProvisionerTpm2.IdentityClaimResponse.newBuilder()
+ .setCredentialBlob(blobStr).setPcrMask(pcrQuoteMask)
+ .setStatus(ProvisionerTpm2.ResponseStatus.PASS)
+ .build();
+
+ String identityClaimResponseJsonStringAfterSuccess = "";
+ try {
+ identityClaimResponseJsonStringAfterSuccess =
+ JsonFormat.printer().print(identityClaimResponse);
+ } catch (InvalidProtocolBufferException exception) {
+ log.error("Identity claim response after a successful validation "
+ + "could not be parsed properly into a json string");
+ }
+
+ if (!policySettings.isSaveProtobufToLogNeverEnabled()
+ && policySettings.isSaveProtobufToLogAlwaysEnabled()) {
+
+ log.info("----------------- Start Of Protobuf Logging Of Identity Claim/Response "
+ + " After Successful Validation -----------------");
+
+ log.info("Identity Claim object received after a "
+ + "successful validation: {}", identityClaimJsonString.isEmpty()
+ ? claim : identityClaimJsonString);
+
+ log.info("Identity Claim Response object after a "
+ + "successful validation: {}", identityClaimResponseJsonStringAfterSuccess.isEmpty()
+ ? identityClaimResponse : identityClaimResponseJsonStringAfterSuccess);
+
+ log.info("----------------- End Of Protobuf Logging Of Identity Claim/Response "
+ + " After Successful Validation -----------------");
+ }
+
+ return identityClaimResponse.toByteArray();
+ } else {
+ log.error("Supply chain validation did not succeed. Result is: {}", validationResult);
+ // empty response
+ ProvisionerTpm2.IdentityClaimResponse identityClaimResponse
+ = ProvisionerTpm2.IdentityClaimResponse.newBuilder()
+ .setCredentialBlob(blobStr)
+ .setStatus(ProvisionerTpm2.ResponseStatus.FAIL)
+ .build();
+
+ String identityClaimResponseJsonStringAfterFailure = "";
+ try {
+ identityClaimResponseJsonStringAfterFailure =
+ JsonFormat.printer().print(identityClaimResponse);
+ } catch (InvalidProtocolBufferException exception) {
+ log.error("Identity claim response after a failed validation "
+ + "could not be parsed properly into a json string");
+ }
+
+ if (!policySettings.isSaveProtobufToLogNeverEnabled()
+ && (policySettings.isSaveProtobufToLogAlwaysEnabled()
+ || policySettings.isSaveProtobufToLogOnFailedValEnabled())) {
+ log.info("----------------- Start Of Protobuf Logging Of Identity Claim/Response "
+ + " After Failed Validation -----------------");
+
+ log.info("Identity Claim object received after a "
+ + "failed validation: {}", identityClaimJsonString.isEmpty()
+ ? claim : identityClaimJsonString);
+
+ log.info("Identity Claim Response object after a "
+ + "failed validation: {}", identityClaimResponseJsonStringAfterFailure.isEmpty()
+ ? identityClaimResponse : identityClaimResponseJsonStringAfterFailure);
+
+ log.info("----------------- End Of Protobuf Logging Of Identity Claim/Response "
+ + " After Failed Validation -----------------");
+ }
+
+ return identityClaimResponse.toByteArray();
+ }
+ }
+
+ /**
+ * Performs supply chain validation.
+ *
+ * @param claim the identity claim
+ * @param ekPub the public endorsement key
+ * @return the {@link AppraisalStatus} of the supply chain validation
+ */
+ private AppraisalStatus.Status doSupplyChainValidation(final ProvisionerTpm2.IdentityClaim claim,
+ final PublicKey ekPub) throws IOException {
+
+ // attempt to find an endorsement credential to validate
+ EndorsementCredential endorsementCredential =
+ credentialManagementService.parseEcFromIdentityClaim(claim, ekPub);
+
+ // attempt to find platform credentials to validate
+ List platformCredentials = credentialManagementService.parsePcsFromIdentityClaim(claim,
+ endorsementCredential);
+
+ // Parse and save device info
+ Device device = deviceManagementService.processDeviceInfo(claim);
+
+// device.getDeviceInfo().setPaccorOutputString(claim.getPaccorOutput());
+ handleDeviceComponents(device.getDeviceInfo().getNetworkInfo().getHostname(),
+ claim.getPaccorOutput());
+
+ // There are situations in which the claim is sent with no PCs
+ // or a PC from the tpm which will be deprecated
+ // this is to check what is in the platform object and pull
+ // additional information from the DB if information exists
+ if (platformCredentials.size() == 1) {
+ List tempList = new LinkedList<>();
+ for (PlatformCredential pc : platformCredentials) {
+ if (pc != null && pc.getPlatformSerial() != null) {
+ tempList.addAll(certificateRepository.byBoardSerialNumber(pc.getPlatformSerial()));
+ }
+ }
+
+ platformCredentials.addAll(tempList);
+ }
+
+ // store component results objects
+ for (PlatformCredential platformCredential : platformCredentials) {
+ List componentResults =
+ componentResultRepository.findByCertificateSerialNumberAndBoardSerialNumber(
+ platformCredential.getSerialNumber().toString(),
+ platformCredential.getPlatformSerial());
+
+ if (componentResults.isEmpty()) {
+ savePlatformComponents(platformCredential);
+ } else {
+ componentResults.forEach((componentResult) -> {
+ componentResult.restore();
+ componentResult.resetCreateTime();
+ componentResultRepository.save(componentResult);
+ });
+ }
+ }
+
+ // perform supply chain validation
+ SupplyChainValidationSummary summary = supplyChainValidationService.validateSupplyChain(
+ endorsementCredential, platformCredentials, device,
+ componentInfoRepository.findByDeviceName(device.getName()));
+ device.setSummaryId(summary.getId().toString());
+
+ // update the validation result in the device
+ AppraisalStatus.Status validationResult = summary.getOverallValidationResult();
+ device.setSupplyChainValidationStatus(validationResult);
+ this.deviceRepository.save(device);
+
+ return validationResult;
+ }
+
+
+ /**
+ * Helper method that saves the provided platform certificate's components in the database.
+ *
+ * @param certificate certificate
+ */
+ private void savePlatformComponents(final Certificate certificate) throws IOException {
+ PlatformCredential platformCredential;
+
+ if (certificate instanceof PlatformCredential) {
+ platformCredential = (PlatformCredential) certificate;
+ ComponentResult componentResult;
+
+ if (platformCredential.getPlatformConfigurationV1() != null) {
+ List componentIdentifiers = platformCredential
+ .getComponentIdentifiers();
+
+ for (ComponentIdentifier componentIdentifier : componentIdentifiers) {
+ componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
+ platformCredential.getSerialNumber().toString(),
+ platformCredential.getPlatformChainType(),
+ componentIdentifier);
+ componentResult.setFailedValidation(false);
+ componentResult.setDelta(!platformCredential.isPlatformBase());
+ componentResultRepository.save(componentResult);
+ }
+ } else if (platformCredential.getPlatformConfigurationV2() != null) {
+ List componentIdentifiersV2 = platformCredential
+ .getComponentIdentifiersV2();
+
+ for (ComponentIdentifierV2 componentIdentifierV2 : componentIdentifiersV2) {
+ componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
+ platformCredential.getSerialNumber().toString(),
+ platformCredential.getPlatformChainType(),
+ componentIdentifierV2);
+ componentResult.setFailedValidation(false);
+ componentResult.setDelta(!platformCredential.isPlatformBase());
+ componentResultRepository.save(componentResult);
+ }
+ }
+ }
+ }
+
+ /**
+ * Helper method that attempts to find all the provided device's components.
+ *
+ * @param hostName device's host name
+ * @param paccorString string representation of the paccor tool output
+ */
+ private void handleDeviceComponents(final String hostName, final String paccorString) {
+ Map componentInfoMap = new HashMap<>();
+
+ try {
+ List componentInfos = SupplyChainCredentialValidator
+ .getComponentInfoFromPaccorOutput(hostName, paccorString);
+
+ // check the DB for like component infos
+ List dbComponentInfos = this.componentInfoRepository.findByDeviceName(hostName);
+ dbComponentInfos.forEach((infos) -> componentInfoMap.put(infos.hashCode(), infos));
+
+ for (ComponentInfo componentInfo : dbComponentInfos) {
+ if (componentInfoMap.containsKey(componentInfo.hashCode())) {
+ componentInfos.remove(componentInfo);
+ }
+ }
+
+ for (ComponentInfo componentInfo : componentInfos) {
+ this.componentInfoRepository.save(componentInfo);
+ }
+ } catch (IOException ioEx) {
+ log.warn("Error parsing paccor string");
+ }
+ }
+}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/SupplyChainValidationService.java
similarity index 99%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/SupplyChainValidationService.java
index 943461db3..b2a5374ce 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/SupplyChainValidationService.java
@@ -1,4 +1,4 @@
-package hirs.attestationca.persist.service;
+package hirs.attestationca.persist.provision.service;
import hirs.attestationca.persist.DBManagerException;
import hirs.attestationca.persist.entity.ArchivableEntity;
@@ -24,6 +24,7 @@
import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements;
import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest;
import hirs.attestationca.persist.enums.AppraisalStatus;
+import hirs.attestationca.persist.service.ValidationService;
import hirs.attestationca.persist.validation.PcrValidator;
import hirs.attestationca.persist.validation.SupplyChainCredentialValidator;
import lombok.extern.log4j.Log4j2;
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
index f85de7d7c..b1fc84592 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
@@ -1,11 +1,10 @@
package hirs.attestationca.persist;
import hirs.attestationca.persist.exceptions.CertificateProcessingException;
-import hirs.attestationca.persist.provision.AttestationCertificateAuthorityService;
-import hirs.attestationca.persist.provision.AttestationCertificateAuthorityServiceImpl;
-import hirs.attestationca.persist.provision.CertificateRequestProcessor;
-import hirs.attestationca.persist.provision.IdentityClaimProcessor;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
+import hirs.attestationca.persist.provision.service.AttestationCertificateAuthorityServiceImpl;
+import hirs.attestationca.persist.provision.service.CertificateRequestProcessor;
+import hirs.attestationca.persist.provision.service.IdentityClaimProcessor;
import hirs.utils.HexUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -124,7 +123,7 @@ public void afterEach() throws Exception {
}
/**
- * Tests {@link AttestationCertificateAuthorityService#processIdentityClaimTpm2(byte[])}
+ * Tests {@link AttestationCertificateAuthorityServiceImpl#processIdentityClaimTpm2(byte[])}
* where the byte array is null or empty. Expects an {@link IllegalArgumentException} to be thrown.
*/
@Test
@@ -157,7 +156,7 @@ public void testProcessIdentityClaimTpm2NullOrEmptyRequest() {
}
/**
- * Tests {@link AttestationCertificateAuthorityService#processIdentityClaimTpm2(byte[])}.
+ * Tests {@link AttestationCertificateAuthorityServiceImpl#processIdentityClaimTpm2(byte[])}.
*/
@Test
public void testProcessIdentityClaimTpm2() {
@@ -176,7 +175,7 @@ public void testProcessIdentityClaimTpm2() {
}
/**
- * Tests {@link AttestationCertificateAuthorityService#processCertificateRequest(byte[])}
+ * Tests {@link AttestationCertificateAuthorityServiceImpl#processCertificateRequest(byte[])}
* where the byte array is null or empty. Expects an {@link IllegalArgumentException} to be thrown.
*/
@Test
@@ -209,7 +208,7 @@ public void testProcessCertificateRequestNullOrEmptyRequest() {
}
/**
- * Tests {@link AttestationCertificateAuthorityService#processCertificateRequest(byte[])}
+ * Tests {@link AttestationCertificateAuthorityServiceImpl#processCertificateRequest(byte[])}
* where the byte array is invalid. Expects a {@link CertificateProcessingException} to be thrown.
*/
@Test
@@ -230,7 +229,7 @@ public void testProcessCertificateRequestProcessorDeserializationError() {
}
/**
- * Tests {@link AttestationCertificateAuthorityService#processCertificateRequest(byte[])}.
+ * Tests {@link AttestationCertificateAuthorityServiceImpl#processCertificateRequest(byte[])}.
*/
@Test
public void testProcessCertificateRequest() {
@@ -249,7 +248,7 @@ public void testProcessCertificateRequest() {
}
/**
- * Tests {@link AttestationCertificateAuthorityService#getLeafACACertPublicKey()}.
+ * Tests {@link AttestationCertificateAuthorityServiceImpl#getLeafACACertPublicKey()}.
*/
@Test
public void testGetPublicKey() {
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelperTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementServiceTest.java
similarity index 60%
rename from HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelperTest.java
rename to HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementServiceTest.java
index dfed13110..f9f7c3133 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelperTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementServiceTest.java
@@ -2,30 +2,34 @@
import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.userdefined.Certificate;
+import hirs.attestationca.persist.provision.service.CredentialManagementService;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.FileInputStream;
import java.io.IOException;
+import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
/**
- * Unit tests for {@see CredentialManagementHelper}.
+ * Unit tests for {@see CredentialManagementService}.
*/
-public class CredentialManagementHelperTest {
+public class CredentialManagementServiceTest {
- private static final String EK_HEADER_TRUNCATED
- = "/certificates/nuc-1/ek_cert_7_byte_header_removed.cer";
+ private static final String EK_HEADER_TRUNCATED = "/certificates/nuc-1/ek_cert_7_byte_header_removed.cer";
- private static final String EK_UNTOUCHED
- = "/certificates/nuc-1/ek_cert_untouched.cer";
+ private static final String EK_UNTOUCHED = "/certificates/nuc-1/ek_cert_untouched.cer";
+
+ @InjectMocks
+ private CredentialManagementService credentialManagementService;
@Mock
private CertificateRepository certificateRepository;
@@ -40,7 +44,6 @@ public class CredentialManagementHelperTest {
*/
@BeforeEach
public void setUp() {
- //certificateRepository = mock(CertificateRepository.class);
mocks = MockitoAnnotations.openMocks(this);
}
@@ -56,27 +59,13 @@ public void tearDown() throws Exception {
}
}
- /**
- * Tests exception generated if providing a null cert repository.
- *
- * @throws IOException if an IO error occurs
- */
- @Test
- public void processNullCertRep() throws IOException {
- // use valid EK byte array
- String path = CredentialManagementHelperTest.class.getResource(EK_UNTOUCHED).getPath();
- byte[] ekBytes = IOUtils.toByteArray(new FileInputStream(path));
- assertThrows(IllegalArgumentException.class, () ->
- CredentialManagementHelper.storeEndorsementCredential(null, ekBytes, "testName"));
- }
-
/**
* Tests exception generated when providing a null EK byte array.
*/
@Test
public void processNullEndorsementCredential() {
assertThrows(IllegalArgumentException.class, () ->
- CredentialManagementHelper.storeEndorsementCredential(certificateRepository, null,
+ credentialManagementService.storeEndorsementCredential(null,
"testName"));
}
@@ -86,8 +75,7 @@ public void processNullEndorsementCredential() {
@Test
public void processEmptyEndorsementCredential() {
assertThrows(IllegalArgumentException.class, () ->
- CredentialManagementHelper.storeEndorsementCredential(
- certificateRepository, new byte[0], "testName"));
+ credentialManagementService.storeEndorsementCredential(new byte[0], "testName"));
}
/**
@@ -95,10 +83,9 @@ public void processEmptyEndorsementCredential() {
*/
@Test
public void processInvalidEndorsementCredentialCase1() {
- byte[] ekBytes = new byte[] {1};
+ byte[] ekBytes = new byte[]{1};
assertThrows(IllegalArgumentException.class, () ->
- CredentialManagementHelper.storeEndorsementCredential(
- certificateRepository, ekBytes, "testName"));
+ credentialManagementService.storeEndorsementCredential(ekBytes, "testName"));
}
/**
@@ -106,9 +93,9 @@ public void processInvalidEndorsementCredentialCase1() {
*/
@Test
public void processInvalidEndorsementCredentialCase2() {
- byte[] ekBytes = new byte[] {1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0};
+ byte[] ekBytes = new byte[]{1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0};
assertThrows(IllegalArgumentException.class, () ->
- CredentialManagementHelper.storeEndorsementCredential(certificateRepository, ekBytes,
+ credentialManagementService.storeEndorsementCredential(ekBytes,
"testName"));
}
@@ -119,10 +106,10 @@ public void processInvalidEndorsementCredentialCase2() {
*/
@Test
public void parseUntouchedEndorsementCredential() throws IOException {
- String path = CredentialManagementHelperTest.class.getResource(EK_UNTOUCHED).getPath();
+ String path = Objects.requireNonNull(CredentialManagementServiceTest.class.getResource(EK_UNTOUCHED)).getPath();
byte[] ekBytes = IOUtils.toByteArray(new FileInputStream(path));
- CredentialManagementHelper.storeEndorsementCredential(certificateRepository, ekBytes, "testName");
+ credentialManagementService.storeEndorsementCredential(ekBytes, "testName");
verify(certificateRepository).save(any(Certificate.class));
}
@@ -133,11 +120,11 @@ public void parseUntouchedEndorsementCredential() throws IOException {
*/
@Test
public void parseHeaderTruncatedEndorsementCredential() throws IOException {
- String path = CredentialManagementHelperTest.class.getResource(EK_HEADER_TRUNCATED)
+ String path = Objects.requireNonNull(CredentialManagementServiceTest.class.getResource(EK_HEADER_TRUNCATED))
.getPath();
byte[] ekBytes = IOUtils.toByteArray(new FileInputStream(path));
- CredentialManagementHelper.storeEndorsementCredential(certificateRepository, ekBytes, "testName");
+ credentialManagementService.storeEndorsementCredential(ekBytes, "testName");
verify(certificateRepository).save(any(Certificate.class));
}
}
diff --git a/HIRS_AttestationCAPortal/src/main/resources/application.properties b/HIRS_AttestationCAPortal/src/main/resources/application.properties
index f75e7b107..0a5040c45 100644
--- a/HIRS_AttestationCAPortal/src/main/resources/application.properties
+++ b/HIRS_AttestationCAPortal/src/main/resources/application.properties
@@ -33,7 +33,6 @@ aca.certificates.leaf-three-key-alias=HIRS_leaf_ca3_rsa_3k_sha384
aca.certificates.intermediate-key-alias=HIRS_intermediate_ca_rsa_3k_sha384
aca.certificates.root-key-alias=HIRS_root_ca_rsa_3k_sha384
aca.certificates.validity=3652
-aca.current.public.key.algorithm=rsa
# Compression settings
server.compression.enabled=true
# Compression content types
diff --git a/HIRS_AttestationCAPortal/src/main/resources/application.win.properties b/HIRS_AttestationCAPortal/src/main/resources/application.win.properties
index 7d39de846..946fb2d2f 100644
--- a/HIRS_AttestationCAPortal/src/main/resources/application.win.properties
+++ b/HIRS_AttestationCAPortal/src/main/resources/application.win.properties
@@ -39,7 +39,6 @@ aca.certificates.leaf-three-key-alias=HIRS_leaf_ca3_rsa_3k_sha384
aca.certificates.intermediate-key-alias=HIRS_intermediate_ca_rsa_3k_sha384
aca.certificates.root-key-alias=HIRS_root_ca_rsa_3k_sha384
aca.certificates.validity=3652
-aca.current.public.key.algorithm=rsa
# Compression settings
server.compression.enabled=true
# Compression content types
diff --git a/package/linux/aca/aca_setup.sh b/package/linux/aca/aca_setup.sh
index 054a1d5e2..c7523ea96 100755
--- a/package/linux/aca/aca_setup.sh
+++ b/package/linux/aca/aca_setup.sh
@@ -221,14 +221,12 @@ fi
sed -i '/aca.certificates.leaf-three-key-alias/d' $SPRING_PROP_FILE
sed -i '/aca.certificates.intermediate-key-alias/d' $SPRING_PROP_FILE
sed -i '/aca.certificates.root-key-alias/d' $SPRING_PROP_FILE
- sed -i '/aca.current.public.key.algorithm/d' $SPRING_PROP_FILE
if [ "$ACA_ALG" == "rsa" ]; then
# Add new lines for aca aliases for the RSA public key algorithm
{
echo "aca.certificates.leaf-three-key-alias=HIRS_leaf_ca3_rsa_3k_sha384_key"
echo "aca.certificates.intermediate-key-alias=HIRS_intermediate_ca_rsa_3k_sha384_key"
echo "aca.certificates.root-key-alias=HIRS_root_ca_rsa_3k_sha384_key"
- echo "aca.current.public.key.algorithm=rsa"
} >> $SPRING_PROP_FILE
elif [ "$ACA_ALG" == "ecc" ]; then
{
@@ -236,7 +234,6 @@ elif [ "$ACA_ALG" == "ecc" ]; then
echo "aca.certificates.leaf-three-key-alias=HIRS_leaf_ca3_ecc_512_sha384_key"
echo "aca.certificates.intermediate-key-alias=HIRS_intermediate_ca_ecc_512_sha384_key"
echo "aca.certificates.root-key-alias=HIRS_root_ca_ecc_512_sha384_key"
- echo "aca.current.public.key.algorithm=ecc"
} >> $SPRING_PROP_FILE
fi
From fc79f209d4b1d85dbd15a53ce037d1a2d6df9c88 Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Wed, 4 Mar 2026 17:14:41 -0500
Subject: [PATCH 11/25] v3.1_issue_1090: Made some name changes to the service
classes, refactored the device info processor service so now there isnt one
huge monolith that handles the device info parsing. Will take on more
refactoring for other intricate parts in future commits.
---
...tationCertificateAuthorityServiceImpl.java | 22 +-
...> CertificateRequestProcessorService.java} | 19 +-
.../service/CredentialManagementService.java | 18 +-
...e.java => DeviceInfoProcessorService.java} | 501 ++++++++++--------
...ava => IdentityClaimProcessorService.java} | 18 +-
...tationCertificateAuthorityServiceTest.java | 24 +-
6 files changed, 318 insertions(+), 284 deletions(-)
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/{CertificateRequestProcessor.java => CertificateRequestProcessorService.java} (96%)
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/{DeviceManagementService.java => DeviceInfoProcessorService.java} (51%)
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/{IdentityClaimProcessor.java => IdentityClaimProcessorService.java} (97%)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java
index 70f6b4cae..dc013c12b 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java
@@ -10,21 +10,21 @@
@Service
@Log4j2
public class AttestationCertificateAuthorityServiceImpl implements AttestationCertificateAuthorityService {
- private final CertificateRequestProcessor certificateRequestProcessor;
- private final IdentityClaimProcessor identityClaimProcessor;
+ private final CertificateRequestProcessorService certificateRequestProcessorService;
+ private final IdentityClaimProcessorService identityClaimProcessorService;
/**
* Constructor.
*
- * @param certificateRequestProcessor certificate request processor service
- * @param identityClaimProcessor identity claim processor service
+ * @param certificateRequestProcessorService certificate request processor service
+ * @param identityClaimProcessorService identity claim processor service
*/
@Autowired
public AttestationCertificateAuthorityServiceImpl(
- final CertificateRequestProcessor certificateRequestProcessor,
- final IdentityClaimProcessor identityClaimProcessor) {
- this.certificateRequestProcessor = certificateRequestProcessor;
- this.identityClaimProcessor = identityClaimProcessor;
+ final CertificateRequestProcessorService certificateRequestProcessorService,
+ final IdentityClaimProcessorService identityClaimProcessorService) {
+ this.certificateRequestProcessorService = certificateRequestProcessorService;
+ this.identityClaimProcessorService = identityClaimProcessorService;
}
/**
@@ -34,7 +34,7 @@ public AttestationCertificateAuthorityServiceImpl(
* @return processed identity claim response
*/
public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
- return this.identityClaimProcessor.processIdentityClaimTpm2(identityClaim);
+ return this.identityClaimProcessorService.processIdentityClaimTpm2(identityClaim);
}
/**
@@ -44,7 +44,7 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
* @return processed certificate request response
*/
public byte[] processCertificateRequest(final byte[] certificateRequest) {
- return this.certificateRequestProcessor.processCertificateRequest(certificateRequest);
+ return this.certificateRequestProcessorService.processCertificateRequest(certificateRequest);
}
/**
@@ -53,6 +53,6 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
* @return encoded public key of the leaf certificate
*/
public byte[] getLeafACACertPublicKey() {
- return this.certificateRequestProcessor.getLeafACACertificatePublicKey();
+ return this.certificateRequestProcessorService.getLeafACACertificatePublicKey();
}
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
similarity index 96%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessor.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
index cd32cc0aa..cd8e81afc 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
@@ -49,7 +49,7 @@
@Service
@Log4j2
-public class CertificateRequestProcessor {
+public class CertificateRequestProcessorService {
private final SupplyChainValidationService supplyChainValidationService;
private final CredentialManagementService credentialManagementService;
private final DeviceRepository deviceRepository;
@@ -72,14 +72,15 @@ public class CertificateRequestProcessor {
* @param policyRepository db connector for policies.
*/
@Autowired
- public CertificateRequestProcessor(final SupplyChainValidationService supplyChainValidationService,
- final CredentialManagementService credentialManagementService,
- final DeviceRepository deviceRepository,
- final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
- final PrivateKey privateKey,
- @Qualifier("leafACACert") final X509Certificate acaCertificate,
- @Value("${aca.certificates.validity}") final int certificateValidityInDays,
- final PolicyRepository policyRepository) {
+ public CertificateRequestProcessorService(final SupplyChainValidationService supplyChainValidationService,
+ final CredentialManagementService credentialManagementService,
+ final DeviceRepository deviceRepository,
+ final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
+ final PrivateKey privateKey,
+ @Qualifier("leafACACert") final X509Certificate acaCertificate,
+ @Value("${aca.certificates.validity}")
+ final int certificateValidityInDays,
+ final PolicyRepository policyRepository) {
this.credentialManagementService = credentialManagementService;
this.certificateValidityInDays = certificateValidityInDays;
this.supplyChainValidationService = supplyChainValidationService;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java
index f983bc894..2aafa5230 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java
@@ -131,9 +131,8 @@ public EndorsementCredential storeEndorsementCredential(final byte[] endorsement
}
if (endorsementBytes.length <= 1) {
- throw new IllegalArgumentException(
- String.format("%d-length byte array given for endorsement credential",
- endorsementBytes.length)
+ throw new IllegalArgumentException(String.format("%d-length byte array given for endorsement credential",
+ endorsementBytes.length)
);
}
@@ -141,8 +140,7 @@ public EndorsementCredential storeEndorsementCredential(final byte[] endorsement
EndorsementCredential endorsementCredential;
try {
- endorsementCredential = EndorsementCredential
- .parseWithPossibleHeader(endorsementBytes);
+ endorsementCredential = EndorsementCredential.parseWithPossibleHeader(endorsementBytes);
} catch (IllegalArgumentException iae) {
log.error(iae.getMessage());
throw iae;
@@ -183,9 +181,7 @@ public PlatformCredential storePlatformCredential(final byte[] platformBytes, fi
if (platformBytes.length == 0) {
log.error("The provided platform credential byte array is null.");
- throw new IllegalArgumentException(
- "zero-length byte array given for platform credential"
- );
+ throw new IllegalArgumentException("zero-length byte array given for platform credential");
}
log.info("Parsing Platform Credential of length {}", platformBytes.length);
@@ -195,8 +191,7 @@ public PlatformCredential storePlatformCredential(final byte[] platformBytes, fi
PlatformCredential.parseWithPossibleHeader(platformBytes);
if (platformCredential == null) {
- log.error("The platform credential that was parsed with the provided"
- + "byte array was null");
+ log.error("The platform credential that was parsed with the provided byte array was null");
return null;
}
@@ -239,8 +234,7 @@ public PlatformCredential storePlatformCredential(final byte[] platformBytes, fi
log.error("Error parsing platform credential", e);
}
- log.error("Due to an exception being thrown while "
- + " attempting to store platform certificate(s) "
+ log.error("Due to an exception being thrown while attempting to store platform certificate(s) "
+ "this method will return a null platform certificate.");
return null;
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceManagementService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
similarity index 51%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceManagementService.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
index ded26b257..4ca101168 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceManagementService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
@@ -23,7 +23,6 @@
import hirs.utils.enums.DeviceInfoEnums;
import hirs.utils.tpm.eventlog.TCGEventLog;
import hirs.utils.tpm.eventlog.TpmPcrEvent;
-import jakarta.xml.bind.UnmarshalException;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.factory.annotation.Autowired;
@@ -43,27 +42,32 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.UUID;
-import java.util.regex.Matcher;
import java.util.regex.Pattern;
+/**
+ *
+ */
@Service
@Log4j2
-public class DeviceManagementService {
+public class DeviceInfoProcessorService {
private static final int NUM_OF_VARIABLES = 5;
private static final int MAC_BYTES = 6;
+ private static final String SUPPORT_RIM_FILE_PATTERN = "(\\S+(\\.(?i)(rimpcr|rimel|bin|log))$)";
private final DeviceRepository deviceRepository;
private final ReferenceManifestRepository referenceManifestRepository;
private final ReferenceDigestValueRepository referenceDigestValueRepository;
+ private final MessageDigest messageDigest;
@Autowired
- public DeviceManagementService(final DeviceRepository deviceRepository,
- final ReferenceManifestRepository referenceManifestRepository,
- final ReferenceDigestValueRepository referenceDigestValueRepository) {
+ public DeviceInfoProcessorService(final DeviceRepository deviceRepository,
+ final ReferenceManifestRepository referenceManifestRepository,
+ final ReferenceDigestValueRepository referenceDigestValueRepository)
+ throws NoSuchAlgorithmException {
this.deviceRepository = deviceRepository;
this.referenceManifestRepository = referenceManifestRepository;
this.referenceDigestValueRepository = referenceDigestValueRepository;
+ this.messageDigest = MessageDigest.getInstance("SHA-256");
}
/**
@@ -82,9 +86,9 @@ public Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) {
}
if (deviceInfoReport == null) {
- log.error("Failed to deserialize Device Info Report");
- throw new IdentityProcessingException("Device Info Report failed to deserialize "
- + "from Identity Claim");
+ final String errorMsg = "Failed to parse device info from Protobuf identity claim.";
+ log.error(errorMsg);
+ throw new IdentityProcessingException(errorMsg);
}
log.info("Processing Device Info Report");
@@ -106,7 +110,7 @@ public Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) {
}
/**
- * Helper method that creates a Device Info Report objec using the provided protobuf identity claim's device info.
+ * Helper method that creates a Device Info Report object using the provided protobuf identity claim's device info.
*
* @param protoIdentityClaim the protobuf serialized identity claim containing the device info
* @return {@link DeviceInfoReport}
@@ -124,8 +128,6 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim pro
// Get Hardware info
HardwareInfo hardwareInfo = getHardwareInfo(deviceInfoProto.getHw());
- retrieveDeviceInfoFromRIMs(deviceInfoProto, hardwareInfo);
-
// Get TPM info, currently unimplemented
TPMInfo tpmInfo = new TPMInfo(DeviceInfoEnums.NOT_SPECIFIED,
(short) 0,
@@ -144,7 +146,9 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim pro
// Get OS info
OSInfo osInfo = getOSInfo(deviceInfoProto.getOs());
- // Create final report
+ updateRIMSUsingDeviceInfo(deviceInfoProto, hardwareInfo);
+
+ // Create final device info report
DeviceInfoReport dvReport = new DeviceInfoReport(networkInfo, osInfo, firmwareInfo, hardwareInfo, tpmInfo,
protoIdentityClaim.getClientVersion());
dvReport.setPaccorOutputString(protoIdentityClaim.getPaccorOutput());
@@ -153,12 +157,12 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim pro
}
/**
- * Helper method that creates a hardware info object using the provided protobuf's version of hardware info.
+ * Helper method that creates a {@link HardwareInfo} object using the provided Protobuf's version of Hardware Info.
*
* @param hardwareInfoProto Protobuf's version of Hardware Info
* @return {@link HardwareInfo}
*/
- private HardwareInfo getHardwareInfo(ProvisionerTpm2.HardwareInfo hardwareInfoProto) {
+ private HardwareInfo getHardwareInfo(final ProvisionerTpm2.HardwareInfo hardwareInfoProto) {
// Make sure chassis info has at least one chassis
String firstChassisSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
@@ -178,10 +182,12 @@ private HardwareInfo getHardwareInfo(ProvisionerTpm2.HardwareInfo hardwareInfoPr
}
/**
+ * Helper method that creates a {@link NetworkInfo} object using the provided Protobuf's version of Network Info.
+ *
* @param networkInfoProto Protobuf's version of Network Info
* @return {@link NetworkInfo}
*/
- private NetworkInfo getNetworkInfo(ProvisionerTpm2.NetworkInfo networkInfoProto) {
+ private NetworkInfo getNetworkInfo(final ProvisionerTpm2.NetworkInfo networkInfoProto) {
InetAddress ip = null;
try {
ip = InetAddress.getByName(networkInfoProto.getIpAddress());
@@ -192,6 +198,7 @@ private NetworkInfo getNetworkInfo(ProvisionerTpm2.NetworkInfo networkInfoProto)
// convert mac hex string to byte values
byte[] macAddressBytes = new byte[MAC_BYTES];
+
Integer hex;
if (macAddressParts.length == MAC_BYTES) {
for (int i = 0; i < MAC_BYTES; i++) {
@@ -204,19 +211,23 @@ private NetworkInfo getNetworkInfo(ProvisionerTpm2.NetworkInfo networkInfoProto)
}
/**
+ * Helper method that creates an {@link OSInfo} object using the provided Protobuf's version of hardware info.
+ *
* @param osInfoProto Protobuf's version of OS Info
* @return {@link OSInfo}
*/
- private OSInfo getOSInfo(ProvisionerTpm2.OsInfo osInfoProto) {
+ private OSInfo getOSInfo(final ProvisionerTpm2.OsInfo osInfoProto) {
return new OSInfo(osInfoProto.getOsName(), osInfoProto.getOsVersion(), osInfoProto.getOsArch(),
osInfoProto.getDistribution(), osInfoProto.getDistributionRelease());
}
/**
+ * Helper method that creates a {@link FirmwareInfo} object using the provided Protobuf's version of firmware info.
+ *
* @param firmwareInfoProto Protobuf's version of Firmware Info
* @return {@link FirmwareInfo}
*/
- private FirmwareInfo getFirmwareInfo(ProvisionerTpm2.FirmwareInfo firmwareInfoProto) {
+ private FirmwareInfo getFirmwareInfo(final ProvisionerTpm2.FirmwareInfo firmwareInfoProto) {
return new FirmwareInfo(firmwareInfoProto.getBiosVendor(), firmwareInfoProto.getBiosVersion(),
firmwareInfoProto.getBiosReleaseDate());
}
@@ -224,254 +235,232 @@ private FirmwareInfo getFirmwareInfo(ProvisionerTpm2.FirmwareInfo firmwareInfoPr
/**
* @param deviceInfoProto
* @param hw
- * @throws NoSuchAlgorithmException
*/
- private void retrieveDeviceInfoFromRIMs(ProvisionerTpm2.DeviceInfo deviceInfoProto, HardwareInfo hw)
- throws NoSuchAlgorithmException {
-
+ private void updateRIMSUsingDeviceInfo(ProvisionerTpm2.DeviceInfo deviceInfoProto, HardwareInfo hw) {
// check for RIM Base and Support files, if they don't exist in the database, load them
final String defaultClientName = String.format("%s_%s", deviceInfoProto.getHw().getManufacturer(),
deviceInfoProto.getHw().getProductName());
- BaseReferenceManifest baseRim = null;
- SupportReferenceManifest supportRim = null;
- EventLogMeasurements integrityMeasurements;
- boolean isReplacement = false;
- String replacementRimId = "";
- String tagId = "";
- String fileName = "";
- Pattern pattern = Pattern.compile("(\\S+(\\.(?i)(rimpcr|rimel|bin|log))$)");
- Matcher matcher;
- MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
+ final String deviceInfoHostName = deviceInfoProto.getNw().getHostname();
+
if (deviceInfoProto.getSwidfileCount() > 0) {
- for (ByteString swidFile : deviceInfoProto.getSwidfileList()) {
- try {
- baseRim = (BaseReferenceManifest) referenceManifestRepository.findByBase64Hash(Base64.getEncoder()
- .encodeToString(messageDigest.digest(swidFile.toByteArray())));
+ updateBaseRIMSUsingDeviceInfo(defaultClientName, deviceInfoProto);
+ } else {
+ log.warn("Device {} did not send SWID tag files...", deviceInfoHostName);
+ }
- if (baseRim == null) {
- /*
- Either the swidFile does not have a corresponding base RIM in the backend
- or it was deleted. Check if there is a replacement by comparing tagId against
- all other base RIMs, and then set the corresponding support rim's deviceName.
- */
- baseRim = new BaseReferenceManifest(String.format("%s.swidtag", defaultClientName),
- swidFile.toByteArray());
-
- List baseRims = referenceManifestRepository.findAllBaseRims();
-
- for (BaseReferenceManifest bRim : baseRims) {
- if (bRim.getTagId().equals(baseRim.getTagId())) {
- baseRim = bRim;
- replacementRimId = baseRim.getAssociatedRim().toString();
- isReplacement = true;
- break;
- }
- }
- baseRim.setDeviceName(deviceInfoProto.getNw().getHostname());
- this.referenceManifestRepository.save(baseRim);
- } else if (baseRim.isArchived()) {
+ if (deviceInfoProto.getLogfileCount() > 0) {
+ updateSupportRIMSUsingDeviceInfo(defaultClientName, deviceInfoProto);
+ } else {
+ log.warn("Device {} did not send Support RIM files...", deviceInfoHostName);
+ }
+
+ updateAllBaseAndSupportRIMS(deviceInfoProto);
+
+ generateDigestRecords(hw.getManufacturer(), hw.getProductName());
+
+ if (deviceInfoProto.hasLivelog()) {
+ updateSupportRIMSUsingEventLogAndDeviceInfo(deviceInfoProto);
+ } else {
+ log.warn("Device {} did not send bios measurement log...", deviceInfoHostName);
+ }
+ }
+
+ /**
+ * @param defaultClientName
+ * @param deviceInfoProto
+ */
+ private void updateBaseRIMSUsingDeviceInfo(final String defaultClientName,
+ final ProvisionerTpm2.DeviceInfo deviceInfoProto) {
+
+ final List baseRims = referenceManifestRepository.findAllBaseRims();
+ final List unarchivedRims = referenceManifestRepository.findByArchiveFlag(false);
+ final String deviceHostName = deviceInfoProto.getNw().getHostname();
+
+ log.info("Device {} sent SWID tag files", deviceHostName);
+
+ for (ByteString swidFile : deviceInfoProto.getSwidfileList()) {
+ try {
+ final String swidFileHash =
+ Base64.getEncoder().encodeToString(messageDigest.digest(swidFile.toByteArray()));
+
+ final BaseReferenceManifest baseRim =
+ (BaseReferenceManifest) referenceManifestRepository.findByBase64Hash(swidFileHash);
+ /*
+ Either the swidFile does not have a corresponding base RIM in the backend
+ or it was deleted. Check if there is a replacement by comparing tagId against
+ all other base RIMs, and then set the corresponding support rim's deviceName. */
+ if (baseRim == null) {
+ final BaseReferenceManifest replacementBaseRIM =
+ new BaseReferenceManifest(String.format("%s.swidtag", defaultClientName),
+ swidFile.toByteArray());
+ replacementBaseRIM.setDeviceName(deviceHostName);
+
+ Optional matchedReplacementBaseRIMOptional = baseRims.stream()
+ .filter(bRim ->
+ bRim.getTagId().equals(replacementBaseRIM.getTagId()))
+ .findFirst();
+
+ // if there is a match, save the matched base RIM
+ if (matchedReplacementBaseRIMOptional.isPresent()) {
+ final BaseReferenceManifest matchedReplacementBaseRIM =
+ matchedReplacementBaseRIMOptional.get();
+ matchedReplacementBaseRIM.setDeviceName(replacementBaseRIM.getDeviceName());
+ this.referenceManifestRepository.save(matchedReplacementBaseRIM);
+ continue;
+ }
+
+ // otherwise save the replacement base RIM we created
+ this.referenceManifestRepository.save(replacementBaseRIM);
+ } else if (baseRim.isArchived()) {
/*
This block accounts for RIMs that may have been soft-deleted (archived)
in an older version of the ACA.
*/
- List rims = referenceManifestRepository.findByArchiveFlag(false);
- for (ReferenceManifest rim : rims) {
- if (rim.isBase() && rim.getTagId().equals(baseRim.getTagId())
- && rim.getCreateTime().after(baseRim.getCreateTime())) {
- baseRim.setDeviceName(null);
- baseRim = (BaseReferenceManifest) rim;
- baseRim.setDeviceName(deviceInfoProto.getNw().getHostname());
- }
- }
- if (baseRim.isArchived()) {
- throw new Exception("Unable to locate an unarchived base RIM.");
- } else {
- this.referenceManifestRepository.save(baseRim);
- }
- } else {
- baseRim.setDeviceName(deviceInfoProto.getNw().getHostname());
- this.referenceManifestRepository.save(baseRim);
+ // Filter out unarchived base RIMs that match the tagId and are newer than the baseRim
+ Optional matchedUnarchivedBaseRIMOptional = unarchivedRims.stream()
+ .filter(rim -> rim.isBase()
+ && rim.getTagId().equals(baseRim.getTagId())
+ && rim.getCreateTime().after(baseRim.getCreateTime()))
+ .map(rim -> (BaseReferenceManifest) rim)
+ .findFirst();
+
+ if (matchedUnarchivedBaseRIMOptional.isEmpty()) {
+ throw new Exception("Unable to locate an unarchived base RIM.");
}
- tagId = baseRim.getTagId();
- } catch (UnmarshalException e) {
- log.error(e);
- } catch (Exception ex) {
- log.error("Failed to load base rim: {}", ex.getMessage());
+
+ final BaseReferenceManifest matchedUnarchivedBaseRIM = matchedUnarchivedBaseRIMOptional.get();
+ matchedUnarchivedBaseRIM.setDeviceName(deviceHostName);
+ this.referenceManifestRepository.save(matchedUnarchivedBaseRIM);
+ } else {
+ baseRim.setDeviceName(deviceHostName);
+ this.referenceManifestRepository.save(baseRim);
}
+ } catch (Exception exception) {
+ log.error("Failed to process Bsase RIM file for device {}: {}", deviceHostName,
+ exception.getMessage(), exception);
}
- } else {
- log.warn("{} did not send swid tag file...", deviceInfoProto.getNw().getHostname());
}
+ }
- if (deviceInfoProto.getLogfileCount() > 0) {
- for (ByteString logFile : deviceInfoProto.getLogfileList()) {
- try {
- supportRim =
- (SupportReferenceManifest) referenceManifestRepository.findByHexDecHashAndRimType(
- Hex.encodeHexString(messageDigest.digest(logFile.toByteArray())),
- ReferenceManifest.SUPPORT_RIM);
- if (supportRim == null) {
- /*
- Either the logFile does not have a corresponding support RIM in the backend
- or it was deleted. The support RIM for a replacement base RIM is handled
- in the previous loop block.
- */
- if (isReplacement) {
- Optional replacementRim =
- referenceManifestRepository.findById(UUID.fromString(replacementRimId));
- if (replacementRim.isPresent()) {
- supportRim = (SupportReferenceManifest) replacementRim.get();
- supportRim.setDeviceName(deviceInfoProto.getNw().getHostname());
- } else {
- throw new Exception("Unable to locate support RIM " + replacementRimId);
- }
- } else {
- supportRim = new SupportReferenceManifest(String.format("%s.rimel", defaultClientName),
+ /**
+ * @param defaultClientName
+ * @param deviceInfoProto
+ */
+ private void updateSupportRIMSUsingDeviceInfo(final String defaultClientName,
+ final ProvisionerTpm2.DeviceInfo deviceInfoProto) {
+ final String deviceHostName = deviceInfoProto.getNw().getHostname();
+
+ log.info("Device {} sent Support RIM files", deviceHostName);
+
+ final List unarchivedRims = referenceManifestRepository.findByArchiveFlag(false);
+
+ for (ByteString logFile : deviceInfoProto.getLogfileList()) {
+ try {
+ final String logFileHash = Hex.encodeHexString(messageDigest.digest(logFile.toByteArray()));
+
+ final SupportReferenceManifest supportRim =
+ (SupportReferenceManifest) referenceManifestRepository.findByHexDecHashAndRimType(
+ logFileHash, ReferenceManifest.SUPPORT_RIM);
+
+ if (supportRim == null) {
+ /*
+ Either the logFile does not have a corresponding support RIM in the backend
+ or it was deleted. The support RIM for a replacement base RIM is handled
+ in the previous loop block.
+ */
+ final SupportReferenceManifest replacementSupportRIM =
+ new SupportReferenceManifest(String.format("%s.rimel", defaultClientName),
logFile.toByteArray());
- // this is a validity check
- new TCGEventLog(supportRim.getRimBytes());
- // no issues, continue
- supportRim.setPlatformManufacturer(deviceInfoProto.getHw().getManufacturer());
- supportRim.setPlatformModel(deviceInfoProto.getHw().getProductName());
- supportRim.setFileName(String.format("%s_[%s].rimel", defaultClientName,
- supportRim.getHexDecHash().substring(
- supportRim.getHexDecHash().length() - NUM_OF_VARIABLES)));
- }
- supportRim.setDeviceName(deviceInfoProto.getNw().getHostname());
- this.referenceManifestRepository.save(supportRim);
- } else if (supportRim.isArchived()) {
- /*
- This block accounts for RIMs that may have been soft-deleted (archived)
- in an older version of the ACA.
- */
- List rims = referenceManifestRepository.findByArchiveFlag(false);
- for (ReferenceManifest rim : rims) {
- if (rim.isSupport()
+
+ // this is a validity check
+ new TCGEventLog(replacementSupportRIM.getRimBytes());
+
+ // no issues, continue
+ replacementSupportRIM.setPlatformManufacturer(deviceInfoProto.getHw().getManufacturer());
+ replacementSupportRIM.setPlatformModel(deviceInfoProto.getHw().getProductName());
+ replacementSupportRIM.setFileName(String.format("%s_[%s].rimel", defaultClientName,
+ replacementSupportRIM.getHexDecHash().substring(
+ replacementSupportRIM.getHexDecHash().length() - NUM_OF_VARIABLES)));
+ replacementSupportRIM.setDeviceName(deviceHostName);
+ this.referenceManifestRepository.save(replacementSupportRIM);
+ } else if (supportRim.isArchived()) {
+ /*
+ This block accounts for RIMs that may have been soft-deleted (archived)
+ in an older version of the ACA.
+ */
+ // Filter out unarchived support RIMs that match the tagId and are newer than the support RIM
+ Optional matchedUnarchivedSupportRIMOptional = unarchivedRims.stream()
+ .filter(rim -> rim.isSupport()
&& rim.getTagId().equals(supportRim.getTagId())
- && rim.getCreateTime().after(supportRim.getCreateTime())) {
- supportRim.setDeviceName(null);
- supportRim = (SupportReferenceManifest) rim;
- supportRim.setDeviceName(deviceInfoProto.getNw().getHostname());
- }
- }
- if (supportRim.isArchived()) {
- throw new Exception("Unable to locate an unarchived support RIM.");
- } else {
- this.referenceManifestRepository.save(supportRim);
- }
- } else {
- supportRim.setDeviceName(deviceInfoProto.getNw().getHostname());
- this.referenceManifestRepository.save(supportRim);
+ && rim.getCreateTime().after(supportRim.getCreateTime()))
+ .map(rim -> (SupportReferenceManifest) rim)
+ .findFirst();
+
+ if (matchedUnarchivedSupportRIMOptional.isEmpty()) {
+ throw new Exception("Unable to locate an unarchived support RIM.");
}
- } catch (IOException ioEx) {
- log.error(ioEx);
- } catch (Exception ex) {
- log.error("Failed to load support rim: {}", ex.getMessage());
+
+ final SupportReferenceManifest matchedUnarchivedSupportRIM =
+ matchedUnarchivedSupportRIMOptional.get();
+ matchedUnarchivedSupportRIM.setDeviceName(deviceHostName);
+ this.referenceManifestRepository.save(matchedUnarchivedSupportRIM);
+ } else {
+ supportRim.setDeviceName(deviceHostName);
+ this.referenceManifestRepository.save(supportRim);
}
+ } catch (Exception exception) {
+ log.error("Failed to process Support RIM file for device {}: {}", deviceHostName,
+ exception.getMessage(), exception);
+
}
- } else {
- log.warn("{} did not send support RIM file...", deviceInfoProto.getNw().getHostname());
}
+ }
+
+ private void updateAllBaseAndSupportRIMS(ProvisionerTpm2.DeviceInfo deviceInfoProto) {
+ final Pattern supportRimPattern = Pattern.compile(SUPPORT_RIM_FILE_PATTERN);
//update Support RIMs and Base RIMs.
for (ByteString swidFile : deviceInfoProto.getSwidfileList()) {
- baseRim = (BaseReferenceManifest) referenceManifestRepository
- .findByBase64Hash(Base64.getEncoder().encodeToString(messageDigest.digest(
- swidFile.toByteArray())));
+ final String swidFileHash =
+ Base64.getEncoder().encodeToString(messageDigest.digest(swidFile.toByteArray()));
+
+ final BaseReferenceManifest baseRim =
+ (BaseReferenceManifest) referenceManifestRepository.findByBase64Hash(swidFileHash);
+
if (baseRim != null) {
- // get file name to use
for (SwidResource swid : baseRim.getFileResources()) {
- matcher = pattern.matcher(swid.getName());
- if (matcher.matches()) {
- //found the file name
- int dotIndex = swid.getName().lastIndexOf(".");
- fileName = swid.getName().substring(0, dotIndex);
- baseRim.setFileName(String.format("%s.swidtag",
- fileName));
+ if (supportRimPattern.matcher(swid.getName()).matches()) {
+ final int dotIndex = swid.getName().lastIndexOf(".");
+ final String fileName = swid.getName().substring(0, dotIndex);
+ baseRim.setFileName(String.format("%s.swidtag", fileName));
}
// now update support rim
- SupportReferenceManifest dbSupport =
- (SupportReferenceManifest) referenceManifestRepository
- .findByHexDecHashAndRimType(swid.getHashValue(),
- ReferenceManifest.SUPPORT_RIM);
- if (dbSupport != null) {
- dbSupport.setFileName(swid.getName());
- dbSupport.setSwidTagVersion(baseRim.getSwidTagVersion());
- dbSupport.setTagId(baseRim.getTagId());
- dbSupport.setSwidTagVersion(baseRim.getSwidTagVersion());
- dbSupport.setSwidVersion(baseRim.getSwidVersion());
- dbSupport.setSwidPatch(baseRim.isSwidPatch());
- dbSupport.setSwidSupplemental(baseRim.isSwidSupplemental());
- baseRim.setAssociatedRim(dbSupport.getId());
- dbSupport.setUpdated(true);
- dbSupport.setAssociatedRim(baseRim.getId());
- this.referenceManifestRepository.save(dbSupport);
- } else {
+ SupportReferenceManifest dbSupportRIM = (SupportReferenceManifest) referenceManifestRepository
+ .findByHexDecHashAndRimType(swid.getHashValue(), ReferenceManifest.SUPPORT_RIM);
+
+ if (dbSupportRIM == null) {
log.warn("Could not locate support RIM with hash {}}", swid.getHashValue());
+ continue;
}
- }
- this.referenceManifestRepository.save(baseRim);
- }
- }
-
- generateDigestRecords(hw.getManufacturer(), hw.getProductName());
-
- if (deviceInfoProto.hasLivelog()) {
- log.info("Device sent bios measurement log...");
- fileName = String.format("%s.measurement", deviceInfoProto.getNw().getHostname());
- try {
- EventLogMeasurements deviceLiveLog = new EventLogMeasurements(fileName,
- deviceInfoProto.getLivelog().toByteArray());
- // find previous version.
- integrityMeasurements = referenceManifestRepository.byMeasurementDeviceNameUnarchived(
- deviceInfoProto.getNw().getHostname());
-
- if (integrityMeasurements != null) {
- // Find previous log and archive it
- integrityMeasurements.archive();
- this.referenceManifestRepository.save(integrityMeasurements);
- }
-
- List baseRims = referenceManifestRepository.getBaseByManufacturerModel(
- deviceInfoProto.getHw().getManufacturer(),
- deviceInfoProto.getHw().getProductName());
- integrityMeasurements = deviceLiveLog;
- integrityMeasurements.setPlatformManufacturer(deviceInfoProto.getHw().getManufacturer());
- integrityMeasurements.setPlatformModel(deviceInfoProto.getHw().getProductName());
-
- if (tagId != null && !tagId.trim().isEmpty()) {
- integrityMeasurements.setTagId(tagId);
+ dbSupportRIM.setFileName(swid.getName());
+ dbSupportRIM.setSwidTagVersion(baseRim.getSwidTagVersion());
+ dbSupportRIM.setTagId(baseRim.getTagId());
+ dbSupportRIM.setSwidTagVersion(baseRim.getSwidTagVersion());
+ dbSupportRIM.setSwidVersion(baseRim.getSwidVersion());
+ dbSupportRIM.setSwidPatch(baseRim.isSwidPatch());
+ dbSupportRIM.setSwidSupplemental(baseRim.isSwidSupplemental());
+ dbSupportRIM.setUpdated(true);
+ dbSupportRIM.setAssociatedRim(baseRim.getId());
+ baseRim.setAssociatedRim(dbSupportRIM.getId());
+ this.referenceManifestRepository.save(dbSupportRIM);
}
- integrityMeasurements.setDeviceName(deviceInfoProto.getNw().getHostname());
-
- this.referenceManifestRepository.save(integrityMeasurements);
-
- for (BaseReferenceManifest bRim : baseRims) {
- if (bRim != null) {
- // pull the base versions of the swidtag and rimel and set the
- // event log hash for use during provision
- SupportReferenceManifest sBaseRim = referenceManifestRepository
- .getSupportRimEntityById(bRim.getAssociatedRim());
- if (sBaseRim != null) {
- bRim.setEventLogHash(deviceLiveLog.getHexDecHash());
- sBaseRim.setEventLogHash(deviceLiveLog.getHexDecHash());
- referenceManifestRepository.save(bRim);
- referenceManifestRepository.save(sBaseRim);
- } else {
- log.warn("Could not locate support RIM associated with base RIM {}", bRim.getId());
- }
- }
- }
- } catch (IOException ioEx) {
- log.error(ioEx);
+ this.referenceManifestRepository.save(baseRim);
}
- } else {
- log.warn("{} did not send bios measurement log...", deviceInfoProto.getNw().getHostname());
}
}
@@ -576,4 +565,56 @@ private void generateDigestRecords(final String manufacturer, final String model
}
}
}
+
+ private void updateSupportRIMSUsingEventLogAndDeviceInfo(ProvisionerTpm2.DeviceInfo deviceInfoProto) {
+ log.info("Device sent bios measurement log...");
+
+ final String deviceInfoHostName = deviceInfoProto.getNw().getHostname();
+
+ final String fileName = String.format("%s.measurement", deviceInfoHostName);
+ try {
+ // grab the event log from protobuf's device info
+ EventLogMeasurements deviceInfoProtoEventLog = new EventLogMeasurements(fileName,
+ deviceInfoProto.getLivelog().toByteArray());
+
+ // find the previous event log that's stored in the database.
+ EventLogMeasurements integrityMeasurements =
+ referenceManifestRepository.byMeasurementDeviceNameUnarchived(deviceInfoHostName);
+
+ // if the event log does exist in the database
+ if (integrityMeasurements != null) {
+ // archive it and update the entity in the database
+ integrityMeasurements.archive();
+ this.referenceManifestRepository.save(integrityMeasurements);
+ }
+
+ List baseRims = referenceManifestRepository.getBaseByManufacturerModel(
+ deviceInfoProto.getHw().getManufacturer(),
+ deviceInfoProto.getHw().getProductName());
+
+ deviceInfoProtoEventLog.setDeviceName(deviceInfoHostName);
+ deviceInfoProtoEventLog.setPlatformManufacturer(deviceInfoProto.getHw().getManufacturer());
+ deviceInfoProtoEventLog.setPlatformModel(deviceInfoProto.getHw().getProductName());
+ this.referenceManifestRepository.save(deviceInfoProtoEventLog);
+
+ for (BaseReferenceManifest bRim : baseRims) {
+ if (bRim != null) {
+ // pull the base versions of the swidtag and rimel and set the
+ // event log hash for use during provision
+ SupportReferenceManifest sBaseRim = referenceManifestRepository
+ .getSupportRimEntityById(bRim.getAssociatedRim());
+ if (sBaseRim != null) {
+ bRim.setEventLogHash(deviceInfoProtoEventLog.getHexDecHash());
+ sBaseRim.setEventLogHash(deviceInfoProtoEventLog.getHexDecHash());
+ referenceManifestRepository.save(bRim);
+ referenceManifestRepository.save(sBaseRim);
+ } else {
+ log.warn("Could not locate support RIM associated with base RIM {}", bRim.getId());
+ }
+ }
+ }
+ } catch (Exception exception) {
+ log.error(exception);
+ }
+ }
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
similarity index 97%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessor.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
index eeb9ea073..51ff31761 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessor.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
@@ -39,7 +39,7 @@
@Service
@Log4j2
-public class IdentityClaimProcessor {
+public class IdentityClaimProcessorService {
/**
* Number of bytes to include in the TPM2.0 nonce.
*/
@@ -48,7 +48,7 @@ public class IdentityClaimProcessor {
private final SupplyChainValidationService supplyChainValidationService;
private final CredentialManagementService credentialManagementService;
- private final DeviceManagementService deviceManagementService;
+ private final DeviceInfoProcessorService deviceInfoProcessorService;
private final CertificateRepository certificateRepository;
private final ComponentResultRepository componentResultRepository;
private final ComponentInfoRepository componentInfoRepository;
@@ -68,13 +68,13 @@ public class IdentityClaimProcessor {
* @param policyRepository policy repository
*/
@Autowired
- public IdentityClaimProcessor(
+ public IdentityClaimProcessorService(
final SupplyChainValidationService supplyChainValidationService,
final CredentialManagementService credentialManagementService,
final CertificateRepository certificateRepository,
final ComponentResultRepository componentResultRepository,
final ComponentInfoRepository componentInfoRepository,
- final DeviceRepository deviceRepository, DeviceManagementService deviceManagementService,
+ final DeviceRepository deviceRepository, DeviceInfoProcessorService deviceInfoProcessorService,
final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
final PolicyRepository policyRepository) {
this.supplyChainValidationService = supplyChainValidationService;
@@ -83,7 +83,7 @@ public IdentityClaimProcessor(
this.componentResultRepository = componentResultRepository;
this.componentInfoRepository = componentInfoRepository;
this.deviceRepository = deviceRepository;
- this.deviceManagementService = deviceManagementService;
+ this.deviceInfoProcessorService = deviceInfoProcessorService;
this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
this.policyRepository = policyRepository;
}
@@ -245,11 +245,9 @@ private AppraisalStatus.Status doSupplyChainValidation(final ProvisionerTpm2.Ide
endorsementCredential);
// Parse and save device info
- Device device = deviceManagementService.processDeviceInfo(claim);
-
-// device.getDeviceInfo().setPaccorOutputString(claim.getPaccorOutput());
- handleDeviceComponents(device.getDeviceInfo().getNetworkInfo().getHostname(),
- claim.getPaccorOutput());
+ Device device = deviceInfoProcessorService.processDeviceInfo(claim);
+
+ handleDeviceComponents(device.getDeviceInfo().getNetworkInfo().getHostname(), claim.getPaccorOutput());
// There are situations in which the claim is sent with no PCs
// or a PC from the tpm which will be deprecated
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
index b1fc84592..bd3dfc7e6 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
@@ -3,8 +3,8 @@
import hirs.attestationca.persist.exceptions.CertificateProcessingException;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
import hirs.attestationca.persist.provision.service.AttestationCertificateAuthorityServiceImpl;
-import hirs.attestationca.persist.provision.service.CertificateRequestProcessor;
-import hirs.attestationca.persist.provision.service.IdentityClaimProcessor;
+import hirs.attestationca.persist.provision.service.CertificateRequestProcessorService;
+import hirs.attestationca.persist.provision.service.IdentityClaimProcessorService;
import hirs.utils.HexUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -89,10 +89,10 @@ public class AttestationCertificateAuthorityServiceTest {
private AttestationCertificateAuthorityServiceImpl attestationCertificateAuthorityService;
@Mock
- private CertificateRequestProcessor certificateRequestProcessor;
+ private CertificateRequestProcessorService certificateRequestProcessorService;
@Mock
- private IdentityClaimProcessor identityClaimProcessor;
+ private IdentityClaimProcessorService identityClaimProcessorService;
/**
* Setups configuration prior to each test method.
@@ -131,7 +131,7 @@ public void testProcessIdentityClaimTpm2NullOrEmptyRequest() {
final String expectedExceptionMsg = "The IdentityClaim sent by the client cannot be null or empty.";
// test 1: test null identity claim
- when(identityClaimProcessor.processIdentityClaimTpm2(null)).thenThrow(
+ when(identityClaimProcessorService.processIdentityClaimTpm2(null)).thenThrow(
new IllegalArgumentException(expectedExceptionMsg));
// Act & Assert: Verify that the exception is thrown
@@ -145,7 +145,7 @@ public void testProcessIdentityClaimTpm2NullOrEmptyRequest() {
// initialize an empty byte array
final byte[] emptyArr = {};
- when(identityClaimProcessor.processIdentityClaimTpm2(emptyArr)).thenThrow(
+ when(identityClaimProcessorService.processIdentityClaimTpm2(emptyArr)).thenThrow(
new IllegalArgumentException(expectedExceptionMsg));
// Act & Assert: Verify that the exception is thrown
@@ -164,11 +164,11 @@ public void testProcessIdentityClaimTpm2() {
final byte[] expectedIdentityClaimResponse = {1, 1, 1, 1, 2, 2, 2, 2};
- when(identityClaimProcessor.processIdentityClaimTpm2(identityClaim)).thenReturn(
+ when(identityClaimProcessorService.processIdentityClaimTpm2(identityClaim)).thenReturn(
expectedIdentityClaimResponse);
final byte[] actualCertificateResponse =
- identityClaimProcessor.processIdentityClaimTpm2(identityClaim);
+ identityClaimProcessorService.processIdentityClaimTpm2(identityClaim);
// Assert that the byte arrays match
assertArrayEquals(expectedIdentityClaimResponse, actualCertificateResponse);
@@ -183,7 +183,7 @@ public void testProcessCertificateRequestNullOrEmptyRequest() {
final String expectedExceptionMsg = "The CertificateRequest sent by the client cannot be null or empty.";
// test 1: test null certificate request
- when(certificateRequestProcessor.processCertificateRequest(null)).thenThrow(
+ when(certificateRequestProcessorService.processCertificateRequest(null)).thenThrow(
new IllegalArgumentException(expectedExceptionMsg));
// Act & Assert: Verify that the exception is thrown
@@ -197,7 +197,7 @@ public void testProcessCertificateRequestNullOrEmptyRequest() {
// initialize an empty byte array
final byte[] emptyArr = {};
- when(certificateRequestProcessor.processCertificateRequest(emptyArr)).thenThrow(
+ when(certificateRequestProcessorService.processCertificateRequest(emptyArr)).thenThrow(
new IllegalArgumentException(expectedExceptionMsg));
// Act & Assert: Verify that the exception is thrown
@@ -217,7 +217,7 @@ public void testProcessCertificateRequestProcessorDeserializationError() {
final byte[] badCertificateRequest = {0, 0, 0, 0, 0, 1, 0, 0};
- when(certificateRequestProcessor.processCertificateRequest(badCertificateRequest)).thenThrow(
+ when(certificateRequestProcessorService.processCertificateRequest(badCertificateRequest)).thenThrow(
new CertificateProcessingException(expectedExceptionMsg));
// Act & Assert: Verify that the exception is thrown
@@ -237,7 +237,7 @@ public void testProcessCertificateRequest() {
final byte[] expectedCertificateResponse = {1, 1, 1, 1};
- when(certificateRequestProcessor.processCertificateRequest(certificateRequest)).thenReturn(
+ when(certificateRequestProcessorService.processCertificateRequest(certificateRequest)).thenReturn(
expectedCertificateResponse);
final byte[] actualCertificateResponse =
From 72393a2a0bf80541cf04aa44339bba81d8906327 Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Thu, 5 Mar 2026 17:46:05 -0500
Subject: [PATCH 12/25] v3.1_issue_1120: Finished refactoring the
identityclaimprocessor. neeed to figure how to remove componetinforepo
completely since it is only being used once. Same with device repo.
---
.ci/system-tests/sys_test_common.sh | 2 +-
.../SupplyChainValidationRepository.java | 28 ++
...java => CertificateManagementService.java} | 112 +++++-
.../CertificateRequestProcessorService.java | 18 +-
.../service/DeviceInfoProcessorService.java | 327 +++++++++++-------
.../IdentityClaimProcessorService.java | 139 +-------
... => CertificateManagementServiceTest.java} | 25 +-
7 files changed, 366 insertions(+), 285 deletions(-)
create mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationRepository.java
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/{CredentialManagementService.java => CertificateManagementService.java} (75%)
rename HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/{CredentialManagementServiceTest.java => CertificateManagementServiceTest.java} (76%)
diff --git a/.ci/system-tests/sys_test_common.sh b/.ci/system-tests/sys_test_common.sh
index a7791eff5..95603b994 100644
--- a/.ci/system-tests/sys_test_common.sh
+++ b/.ci/system-tests/sys_test_common.sh
@@ -61,7 +61,7 @@ clearAcaDb() {
docker exec -i $aca_container mysql -u root -proot -e "use hirs_db; set foreign_key_checks=0; truncate Appraiser;
truncate Certificate;truncate Issued_Attestation_Platform_Join_Table;truncate CertificatesUsedToValidate;truncate ComponentAttributeResult;
truncate ComponentInfo;truncate ComponentResult;truncate Device;truncate DeviceInfoReport;truncate PortalInfo;
- truncate ReferenceDigestValue;truncate ReferenceManifest;truncate Report;
+ truncate ReferenceDigestValue;truncate ReferenceManifest;truncate Report;truncate SupplyChainValidation;
truncate SupplyChainValidationSummary;truncate SupplyChainValidationSummary_SupplyChainValidation;
truncate TPM2ProvisionerState;set foreign_key_checks=1;"
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationRepository.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationRepository.java
new file mode 100644
index 000000000..e9446c0f6
--- /dev/null
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationRepository.java
@@ -0,0 +1,28 @@
+package hirs.attestationca.persist.entity.manager;
+
+import hirs.attestationca.persist.entity.userdefined.SupplyChainValidation;
+import hirs.attestationca.persist.enums.AppraisalStatus;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.UUID;
+
+@Repository
+public interface SupplyChainValidationRepository extends JpaRepository {
+ /**
+ * Query that retrieves a list of supply chain validation using the provided validate type.
+ *
+ * @param validationType string representation of the validate type
+ * @return a list of supply chain validation
+ */
+ List findByValidationType(SupplyChainValidation.ValidationType validationType);
+
+ /**
+ * Query that retrieves a list of supply chain validation using the provided validation result.
+ *
+ * @param validationResult string representation of the validation result
+ * @return a list of supply chain validation
+ */
+ List findByValidationResult(AppraisalStatus.Status validationResult);
+}
\ No newline at end of file
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateManagementService.java
similarity index 75%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateManagementService.java
index 2aafa5230..870ed17d0 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateManagementService.java
@@ -4,13 +4,17 @@
import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
import hirs.attestationca.persist.DBManagerException;
import hirs.attestationca.persist.entity.manager.CertificateRepository;
+import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
import hirs.attestationca.persist.entity.manager.PolicyRepository;
import hirs.attestationca.persist.entity.userdefined.Certificate;
import hirs.attestationca.persist.entity.userdefined.Device;
import hirs.attestationca.persist.entity.userdefined.PolicySettings;
+import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult;
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
+import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
+import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
import hirs.attestationca.persist.exceptions.CertificateProcessingException;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
import lombok.extern.log4j.Log4j2;
@@ -30,21 +34,25 @@
*/
@Service
@Log4j2
-public class CredentialManagementService {
+public class CertificateManagementService {
private final PolicyRepository policyRepository;
private final CertificateRepository certificateRepository;
+ private final ComponentResultRepository componentResultRepository;
/**
* Constructor.
*
- * @param policyRepository policy repository
- * @param certificateRepository certificate repository
+ * @param policyRepository policy repository
+ * @param certificateRepository certificate repository
+ * @param componentResultRepository
*/
@Autowired
- private CredentialManagementService(final PolicyRepository policyRepository,
- final CertificateRepository certificateRepository) {
+ private CertificateManagementService(final PolicyRepository policyRepository,
+ final CertificateRepository certificateRepository,
+ final ComponentResultRepository componentResultRepository) {
this.policyRepository = policyRepository;
this.certificateRepository = certificateRepository;
+ this.componentResultRepository = componentResultRepository;
}
/**
@@ -239,6 +247,36 @@ public PlatformCredential storePlatformCredential(final byte[] platformBytes, fi
return null;
}
+ /**
+ * Stores the Platform Certificate's list of associated component results.
+ *
+ * @param platformCredentials list of platform credentials
+ * @throws IOException if any issues arise from storing the platform credentials components
+ */
+ public void saveOrUpdatePlatformCertificateComponents(List platformCredentials)
+ throws IOException {
+
+ handleSpecialCaseForPlatformCertificates(platformCredentials);
+
+ // store component results objects
+ for (PlatformCredential platformCredential : platformCredentials) {
+ List componentResults =
+ componentResultRepository.findByCertificateSerialNumberAndBoardSerialNumber(
+ platformCredential.getSerialNumber().toString(),
+ platformCredential.getPlatformSerial());
+
+ if (componentResults.isEmpty()) {
+ savePlatformCertificateComponents(platformCredential);
+ } else {
+ componentResults.forEach((componentResult) -> {
+ componentResult.restore();
+ componentResult.resetCreateTime();
+ componentResultRepository.save(componentResult);
+ });
+ }
+ }
+ }
+
/**
* Creates an {@link IssuedAttestationCertificate} object and set its corresponding device and persists it.
*
@@ -257,7 +295,7 @@ public boolean saveAttestationCertificate(
final Device device,
final boolean ldevID) {
List issuedAc;
- boolean generateCertificate = true;
+ boolean generateCertificate;
PolicySettings policySettings;
Date currentDate = new Date();
int days;
@@ -349,6 +387,7 @@ private List getPlatformCredentials(final EndorsementCredent
log.debug("Searching for platform credential(s) based on holder serial number: {}",
ec.getSerialNumber());
credentials = certificateRepository.getByHolderSerialNumber(ec.getSerialNumber());
+
if (credentials == null || credentials.isEmpty()) {
log.warn("No platform credential(s) found");
} else {
@@ -358,4 +397,65 @@ private List getPlatformCredentials(final EndorsementCredent
return credentials;
}
+
+ /**
+ * There are situations in which the claim is sent with no platform certificates or a platform certificate
+ * from the tpm which will be deprecated. This is to check what is in the platform object and pull
+ * additional information from the DB if information exists.
+ *
+ * @param platformCredentials list of platform credentials
+ */
+ private void handleSpecialCaseForPlatformCertificates(List platformCredentials) {
+
+ if (platformCredentials.size() == 1) {
+ List additionalPC = new LinkedList<>();
+ PlatformCredential pc = platformCredentials.getFirst();
+ if (pc != null && pc.getPlatformSerial() != null) {
+ additionalPC.addAll(certificateRepository.byBoardSerialNumber(pc.getPlatformSerial()));
+ }
+ platformCredentials.addAll(additionalPC);
+ }
+ }
+
+ /**
+ * Helper method that saves the provided platform certificate's components in the database.
+ *
+ * @param certificate certificate
+ */
+ private void savePlatformCertificateComponents(final Certificate certificate) throws IOException {
+ PlatformCredential platformCredential;
+
+ if (certificate instanceof PlatformCredential) {
+ platformCredential = (PlatformCredential) certificate;
+ ComponentResult componentResult;
+
+ if (platformCredential.getPlatformConfigurationV1() != null) {
+ List componentIdentifiers = platformCredential
+ .getComponentIdentifiers();
+
+ for (ComponentIdentifier componentIdentifier : componentIdentifiers) {
+ componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
+ platformCredential.getSerialNumber().toString(),
+ platformCredential.getPlatformChainType(),
+ componentIdentifier);
+ componentResult.setFailedValidation(false);
+ componentResult.setDelta(!platformCredential.isPlatformBase());
+ componentResultRepository.save(componentResult);
+ }
+ } else if (platformCredential.getPlatformConfigurationV2() != null) {
+ List componentIdentifiersV2 = platformCredential
+ .getComponentIdentifiersV2();
+
+ for (ComponentIdentifierV2 componentIdentifierV2 : componentIdentifiersV2) {
+ componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
+ platformCredential.getSerialNumber().toString(),
+ platformCredential.getPlatformChainType(),
+ componentIdentifierV2);
+ componentResult.setFailedValidation(false);
+ componentResult.setDelta(!platformCredential.isPlatformBase());
+ componentResultRepository.save(componentResult);
+ }
+ }
+ }
+ }
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
index cd8e81afc..5317d400a 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
@@ -51,7 +51,7 @@
@Log4j2
public class CertificateRequestProcessorService {
private final SupplyChainValidationService supplyChainValidationService;
- private final CredentialManagementService credentialManagementService;
+ private final CertificateManagementService certificateManagementService;
private final DeviceRepository deviceRepository;
private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
private final PolicyRepository policyRepository;
@@ -63,7 +63,7 @@ public class CertificateRequestProcessorService {
* Constructor.
*
* @param supplyChainValidationService object that is used to run provisioning
- * @param credentialManagementService credential management service
+ * @param certificateManagementService credential management service
* @param deviceRepository database connector for Devices.
* @param tpm2ProvisionerStateRepository db connector for provisioner state.
* @param privateKey private key used for communication authentication
@@ -73,7 +73,7 @@ public class CertificateRequestProcessorService {
*/
@Autowired
public CertificateRequestProcessorService(final SupplyChainValidationService supplyChainValidationService,
- final CredentialManagementService credentialManagementService,
+ final CertificateManagementService certificateManagementService,
final DeviceRepository deviceRepository,
final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
final PrivateKey privateKey,
@@ -81,7 +81,7 @@ public CertificateRequestProcessorService(final SupplyChainValidationService sup
@Value("${aca.certificates.validity}")
final int certificateValidityInDays,
final PolicyRepository policyRepository) {
- this.credentialManagementService = credentialManagementService;
+ this.certificateManagementService = certificateManagementService;
this.certificateValidityInDays = certificateValidityInDays;
this.supplyChainValidationService = supplyChainValidationService;
this.deviceRepository = deviceRepository;
@@ -155,10 +155,10 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
// Get Endorsement Credential if it exists or was uploaded
EndorsementCredential endorsementCredential =
- credentialManagementService.parseEcFromIdentityClaim(claim, ekPublicKey);
+ certificateManagementService.parseEcFromIdentityClaim(claim, ekPublicKey);
// Get Platform Credentials if they exist or were uploaded
- List platformCredentials = credentialManagementService.parsePcsFromIdentityClaim(claim,
+ List platformCredentials = certificateManagementService.parsePcsFromIdentityClaim(claim,
endorsementCredential);
// Get LDevID public key if it exists
@@ -221,11 +221,11 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
tpm2ProvisionerStateRepository.delete(tpm2ProvisionerState);
boolean generateAtt =
- credentialManagementService.saveAttestationCertificate(derEncodedAttestationCertificate,
+ certificateManagementService.saveAttestationCertificate(derEncodedAttestationCertificate,
endorsementCredential, platformCredentials, device, false);
boolean generateLDevID =
- credentialManagementService.saveAttestationCertificate(derEncodedLdevidCertificate,
+ certificateManagementService.saveAttestationCertificate(derEncodedLdevidCertificate,
endorsementCredential, platformCredentials, device, true);
ProvisionerTpm2.CertificateResponse.Builder certificateResponseBuilder =
@@ -287,7 +287,7 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
ProvisionerTpm2.CertificateResponse.
newBuilder().setStatus(ProvisionerTpm2.ResponseStatus.PASS);
- boolean generateAtt = credentialManagementService.saveAttestationCertificate(
+ boolean generateAtt = certificateManagementService.saveAttestationCertificate(
derEncodedAttestationCertificate,
endorsementCredential, platformCredentials, device, false);
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
index 4ca101168..b390c7d0e 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
@@ -2,11 +2,13 @@
import com.google.protobuf.ByteString;
import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
+import hirs.attestationca.persist.entity.manager.ComponentInfoRepository;
import hirs.attestationca.persist.entity.manager.DeviceRepository;
import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository;
import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository;
import hirs.attestationca.persist.entity.userdefined.Device;
import hirs.attestationca.persist.entity.userdefined.ReferenceManifest;
+import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import hirs.attestationca.persist.entity.userdefined.info.FirmwareInfo;
import hirs.attestationca.persist.entity.userdefined.info.HardwareInfo;
import hirs.attestationca.persist.entity.userdefined.info.NetworkInfo;
@@ -18,11 +20,13 @@
import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue;
import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest;
import hirs.attestationca.persist.exceptions.IdentityProcessingException;
+import hirs.attestationca.persist.validation.SupplyChainCredentialValidator;
import hirs.utils.HexUtils;
import hirs.utils.SwidResource;
import hirs.utils.enums.DeviceInfoEnums;
import hirs.utils.tpm.eventlog.TCGEventLog;
import hirs.utils.tpm.eventlog.TpmPcrEvent;
+import io.micrometer.common.util.StringUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.factory.annotation.Autowired;
@@ -45,48 +49,62 @@
import java.util.regex.Pattern;
/**
- *
+ * Service class that parses and processes Device information from the Identity Claim and uses it to update the Device
+ * and RIMs.
*/
@Service
@Log4j2
public class DeviceInfoProcessorService {
- private static final int NUM_OF_VARIABLES = 5;
private static final int MAC_BYTES = 6;
- private static final String SUPPORT_RIM_FILE_PATTERN = "(\\S+(\\.(?i)(rimpcr|rimel|bin|log))$)";
private final DeviceRepository deviceRepository;
private final ReferenceManifestRepository referenceManifestRepository;
private final ReferenceDigestValueRepository referenceDigestValueRepository;
+ private final ComponentInfoRepository componentInfoRepository;
private final MessageDigest messageDigest;
+ /**
+ * Constructor.
+ *
+ * @param deviceRepository device repository
+ * @param referenceManifestRepository reference manifest repository
+ * @param referenceDigestValueRepository reference digest value repository
+ * @param componentInfoRepository component info repository
+ * @throws NoSuchAlgorithmException if any issues arise from creating a {@link MessageDigest}
+ */
@Autowired
public DeviceInfoProcessorService(final DeviceRepository deviceRepository,
final ReferenceManifestRepository referenceManifestRepository,
- final ReferenceDigestValueRepository referenceDigestValueRepository)
+ final ReferenceDigestValueRepository referenceDigestValueRepository,
+ final ComponentInfoRepository componentInfoRepository)
throws NoSuchAlgorithmException {
this.deviceRepository = deviceRepository;
this.referenceManifestRepository = referenceManifestRepository;
this.referenceDigestValueRepository = referenceDigestValueRepository;
+ this.componentInfoRepository = componentInfoRepository;
this.messageDigest = MessageDigest.getInstance("SHA-256");
}
/**
- * Utilizes the identity claim to produce a device info report.
+ * Creates a {@link DeviceInfoReport} from the identity claim's Device Info and updates the corresponding
+ * {@link Device}.
*
- * @param claim identity claim
- * @return device info
+ * @param identityClaim Identity Claim
+ * @return device
*/
- public Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) {
+ public Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim identityClaim) {
DeviceInfoReport deviceInfoReport = null;
+ log.info("Parsing Device Info from the Identity Claim");
+
try {
- deviceInfoReport = parseDeviceInfo(claim);
+ deviceInfoReport = parseDeviceInfo(identityClaim);
} catch (NoSuchAlgorithmException noSaEx) {
log.error(noSaEx);
}
if (deviceInfoReport == null) {
- final String errorMsg = "Failed to parse device info from Protobuf identity claim.";
+ final String errorMsg = "Failed to parse device info from Protobuf Identity Claim.";
log.error(errorMsg);
throw new IdentityProcessingException(errorMsg);
}
@@ -96,9 +114,8 @@ public Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) {
// store device and device info report.
Device device = null;
- if (deviceInfoReport.getNetworkInfo() != null
- && deviceInfoReport.getNetworkInfo().getHostname() != null
- && !deviceInfoReport.getNetworkInfo().getHostname().isEmpty()) {
+ if (deviceInfoReport.getNetworkInfo() != null &&
+ !StringUtils.isBlank(deviceInfoReport.getNetworkInfo().getHostname())) {
device = this.deviceRepository.findByName(deviceInfoReport.getNetworkInfo().getHostname());
}
@@ -106,181 +123,199 @@ public Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim claim) {
device = new Device(deviceInfoReport);
}
device.setDeviceInfo(deviceInfoReport);
+
+ processDeviceComponents(deviceInfoReport.getNetworkInfo().getHostname(),
+ deviceInfoReport.getPaccorOutputString());
+
return this.deviceRepository.save(device);
}
/**
- * Helper method that creates a Device Info Report object using the provided protobuf identity claim's device info.
+ * Helper method that creates a Device Info Report using the provided Identity Claim's Device Info.
*
- * @param protoIdentityClaim the protobuf serialized identity claim containing the device info
+ * @param identityClaim the protobuf serialized Identity Claim containing the device info
* @return {@link DeviceInfoReport}
*/
- private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim protoIdentityClaim)
+ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim identityClaim)
throws NoSuchAlgorithmException {
- ProvisionerTpm2.DeviceInfo deviceInfoProto = protoIdentityClaim.getDv();
-
- String pcrValues = "";
-
- if (deviceInfoProto.hasPcrslist()) {
- pcrValues = deviceInfoProto.getPcrslist().toStringUtf8();
- }
+ ProvisionerTpm2.DeviceInfo tpmDeviceInfo = identityClaim.getDv();
// Get Hardware info
- HardwareInfo hardwareInfo = getHardwareInfo(deviceInfoProto.getHw());
+ HardwareInfo hardwareInfo = getHardwareInfo(tpmDeviceInfo.getHw());
- // Get TPM info, currently unimplemented
- TPMInfo tpmInfo = new TPMInfo(DeviceInfoEnums.NOT_SPECIFIED,
- (short) 0,
- (short) 0,
- (short) 0,
- (short) 0,
- pcrValues.getBytes(StandardCharsets.UTF_8),
- null, null);
+ // Get TPM info ( todo Currently unimplemented)
+ TPMInfo tpmInfo = getTPMInfo(tpmDeviceInfo);
// Get Network info
- NetworkInfo networkInfo = getNetworkInfo(deviceInfoProto.getNw());
+ NetworkInfo networkInfo = getNetworkInfo(tpmDeviceInfo.getNw());
// Get Firmware info
- FirmwareInfo firmwareInfo = getFirmwareInfo(deviceInfoProto.getFw());
+ FirmwareInfo firmwareInfo = getFirmwareInfo(tpmDeviceInfo.getFw());
// Get OS info
- OSInfo osInfo = getOSInfo(deviceInfoProto.getOs());
+ OSInfo osInfo = getOSInfo(tpmDeviceInfo.getOs());
- updateRIMSUsingDeviceInfo(deviceInfoProto, hardwareInfo);
+ getAndUpdateRIMSUsingTPMDeviceInfo(tpmDeviceInfo);
// Create final device info report
DeviceInfoReport dvReport = new DeviceInfoReport(networkInfo, osInfo, firmwareInfo, hardwareInfo, tpmInfo,
- protoIdentityClaim.getClientVersion());
- dvReport.setPaccorOutputString(protoIdentityClaim.getPaccorOutput());
+ identityClaim.getClientVersion());
+ dvReport.setPaccorOutputString(identityClaim.getPaccorOutput());
return dvReport;
}
/**
- * Helper method that creates a {@link HardwareInfo} object using the provided Protobuf's version of Hardware Info.
+ * Helper method that creates a {@link TPMInfo} using the provided TPM Device Info ( todo Currently unimplemented)
*
- * @param hardwareInfoProto Protobuf's version of Hardware Info
+ * @param tpmDeviceInfo TPM Device Info
+ * @return {@link TPMInfo}
+ */
+ private TPMInfo getTPMInfo(ProvisionerTpm2.DeviceInfo tpmDeviceInfo) {
+ String pcrValues = "";
+
+ if (tpmDeviceInfo.hasPcrslist()) {
+ pcrValues = tpmDeviceInfo.getPcrslist().toStringUtf8();
+ }
+
+ return new TPMInfo(DeviceInfoEnums.NOT_SPECIFIED,
+ (short) 0,
+ (short) 0,
+ (short) 0,
+ (short) 0,
+ pcrValues.getBytes(StandardCharsets.UTF_8),
+ null, null);
+ }
+
+ /**
+ * Helper method that creates a {@link HardwareInfo} using the provided TPM Device Info's Hardware Info.
+ *
+ * @param tpmHardwareInfo TPM Device Info's Hardware Info
* @return {@link HardwareInfo}
*/
- private HardwareInfo getHardwareInfo(final ProvisionerTpm2.HardwareInfo hardwareInfoProto) {
+ private HardwareInfo getHardwareInfo(final ProvisionerTpm2.HardwareInfo tpmHardwareInfo) {
// Make sure chassis info has at least one chassis
String firstChassisSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
- if (hardwareInfoProto.getChassisInfoCount() > 0) {
- firstChassisSerialNumber = hardwareInfoProto.getChassisInfo(0).getSerialNumber();
+ if (tpmHardwareInfo.getChassisInfoCount() > 0) {
+ firstChassisSerialNumber = tpmHardwareInfo.getChassisInfo(0).getSerialNumber();
}
// Make sure baseboard info has at least one baseboard
String firstBaseboardSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
- if (hardwareInfoProto.getBaseboardInfoCount() > 0) {
- firstBaseboardSerialNumber = hardwareInfoProto.getBaseboardInfo(0).getSerialNumber();
+ if (tpmHardwareInfo.getBaseboardInfoCount() > 0) {
+ firstBaseboardSerialNumber = tpmHardwareInfo.getBaseboardInfo(0).getSerialNumber();
}
- return new HardwareInfo(hardwareInfoProto.getManufacturer(), hardwareInfoProto.getProductName(),
- hardwareInfoProto.getProductVersion(), hardwareInfoProto.getSystemSerialNumber(),
+ return new HardwareInfo(tpmHardwareInfo.getManufacturer(), tpmHardwareInfo.getProductName(),
+ tpmHardwareInfo.getProductVersion(), tpmHardwareInfo.getSystemSerialNumber(),
firstChassisSerialNumber, firstBaseboardSerialNumber);
}
/**
- * Helper method that creates a {@link NetworkInfo} object using the provided Protobuf's version of Network Info.
+ * Helper method that creates a {@link NetworkInfo} using the provided TPM Device Info's Network Info.
*
- * @param networkInfoProto Protobuf's version of Network Info
+ * @param tpmNetworkInfo TPM Device Info's Network Info
* @return {@link NetworkInfo}
*/
- private NetworkInfo getNetworkInfo(final ProvisionerTpm2.NetworkInfo networkInfoProto) {
+ private NetworkInfo getNetworkInfo(final ProvisionerTpm2.NetworkInfo tpmNetworkInfo) {
InetAddress ip = null;
try {
- ip = InetAddress.getByName(networkInfoProto.getIpAddress());
+ ip = InetAddress.getByName(tpmNetworkInfo.getIpAddress());
} catch (UnknownHostException uhEx) {
- log.error("Unable to parse IP address: ", uhEx);
+ log.error("Unable to parse IP address from the TPM Device Info: ", uhEx);
}
- String[] macAddressParts = networkInfoProto.getMacAddress().split(":");
+ String[] macAddressParts = tpmNetworkInfo.getMacAddress().split(":");
// convert mac hex string to byte values
byte[] macAddressBytes = new byte[MAC_BYTES];
- Integer hex;
if (macAddressParts.length == MAC_BYTES) {
for (int i = 0; i < MAC_BYTES; i++) {
- hex = HexUtils.hexToInt(macAddressParts[i]);
+ Integer hex = HexUtils.hexToInt(macAddressParts[i]);
macAddressBytes[i] = hex.byteValue();
}
}
- return new NetworkInfo(networkInfoProto.getHostname(), ip, macAddressBytes);
+ return new NetworkInfo(tpmNetworkInfo.getHostname(), ip, macAddressBytes);
}
/**
- * Helper method that creates an {@link OSInfo} object using the provided Protobuf's version of hardware info.
+ * Helper method that creates an {@link OSInfo} using the provided TPM Device Info's OS info.
*
- * @param osInfoProto Protobuf's version of OS Info
+ * @param tpmOsInfo TPM Device Info's OS Info
* @return {@link OSInfo}
*/
- private OSInfo getOSInfo(final ProvisionerTpm2.OsInfo osInfoProto) {
- return new OSInfo(osInfoProto.getOsName(), osInfoProto.getOsVersion(), osInfoProto.getOsArch(),
- osInfoProto.getDistribution(), osInfoProto.getDistributionRelease());
+ private OSInfo getOSInfo(final ProvisionerTpm2.OsInfo tpmOsInfo) {
+ return new OSInfo(tpmOsInfo.getOsName(), tpmOsInfo.getOsVersion(), tpmOsInfo.getOsArch(),
+ tpmOsInfo.getDistribution(), tpmOsInfo.getDistributionRelease());
}
/**
- * Helper method that creates a {@link FirmwareInfo} object using the provided Protobuf's version of firmware info.
+ * Helper method that creates a {@link FirmwareInfo} using the provided TPM Device Info's Firmware Info.
*
- * @param firmwareInfoProto Protobuf's version of Firmware Info
+ * @param tpmFirmwareInfo TPM Device Info's Firmware Info
* @return {@link FirmwareInfo}
*/
- private FirmwareInfo getFirmwareInfo(final ProvisionerTpm2.FirmwareInfo firmwareInfoProto) {
- return new FirmwareInfo(firmwareInfoProto.getBiosVendor(), firmwareInfoProto.getBiosVersion(),
- firmwareInfoProto.getBiosReleaseDate());
+ private FirmwareInfo getFirmwareInfo(final ProvisionerTpm2.FirmwareInfo tpmFirmwareInfo) {
+ return new FirmwareInfo(tpmFirmwareInfo.getBiosVendor(), tpmFirmwareInfo.getBiosVersion(),
+ tpmFirmwareInfo.getBiosReleaseDate());
}
/**
- * @param deviceInfoProto
- * @param hw
+ * Helper method that updates all Reference Integrity Manifests (RIMs) using the provided TPM's Device Info.
+ *
+ * @param tpmDeviceInfo TPM Device Info
*/
- private void updateRIMSUsingDeviceInfo(ProvisionerTpm2.DeviceInfo deviceInfoProto, HardwareInfo hw) {
+ private void getAndUpdateRIMSUsingTPMDeviceInfo(ProvisionerTpm2.DeviceInfo tpmDeviceInfo) {
// check for RIM Base and Support files, if they don't exist in the database, load them
- final String defaultClientName = String.format("%s_%s", deviceInfoProto.getHw().getManufacturer(),
- deviceInfoProto.getHw().getProductName());
-
- final String deviceInfoHostName = deviceInfoProto.getNw().getHostname();
+ final String defaultClientName = String.format("%s_%s", tpmDeviceInfo.getHw().getManufacturer(),
+ tpmDeviceInfo.getHw().getProductName());
+ final String deviceInfoHostName = tpmDeviceInfo.getNw().getHostname();
- if (deviceInfoProto.getSwidfileCount() > 0) {
- updateBaseRIMSUsingDeviceInfo(defaultClientName, deviceInfoProto);
+ // update base RIMs using the identity claim's device information
+ if (tpmDeviceInfo.getSwidfileCount() > 0) {
+ updateBaseRIMSUsingTPMDeviceInfo(defaultClientName, tpmDeviceInfo);
} else {
log.warn("Device {} did not send SWID tag files...", deviceInfoHostName);
}
- if (deviceInfoProto.getLogfileCount() > 0) {
- updateSupportRIMSUsingDeviceInfo(defaultClientName, deviceInfoProto);
+ // update support RIMs using the identity claim's device information
+ if (tpmDeviceInfo.getLogfileCount() > 0) {
+ updateSupportRIMSUsingTPMDeviceInfo(defaultClientName, tpmDeviceInfo);
} else {
log.warn("Device {} did not send Support RIM files...", deviceInfoHostName);
}
- updateAllBaseAndSupportRIMS(deviceInfoProto);
+ // update both base and support RIMs to ensure updates are consistent
+ updateBaseSupportRIMSUsingTpmDeviceInfo(tpmDeviceInfo);
- generateDigestRecords(hw.getManufacturer(), hw.getProductName());
+ generateDigestRecords(tpmDeviceInfo.getHw().getManufacturer(), tpmDeviceInfo.getHw().getProductName());
- if (deviceInfoProto.hasLivelog()) {
- updateSupportRIMSUsingEventLogAndDeviceInfo(deviceInfoProto);
+ // update event log information
+ if (tpmDeviceInfo.hasLivelog()) {
+ updateEventLogInfoUsingTPMDeviceInfo(tpmDeviceInfo);
} else {
- log.warn("Device {} did not send bios measurement log...", deviceInfoHostName);
+ log.warn("Device {} did not send BIOS measurement log...", deviceInfoHostName);
}
}
/**
- * @param defaultClientName
- * @param deviceInfoProto
+ * Helper method that updates the Base RIMs in the database using the information provided by the TPM's Device Info.
+ *
+ * @param defaultClientName default client name
+ * @param tpmDeviceInfo TPM Device Info
*/
- private void updateBaseRIMSUsingDeviceInfo(final String defaultClientName,
- final ProvisionerTpm2.DeviceInfo deviceInfoProto) {
-
+ private void updateBaseRIMSUsingTPMDeviceInfo(final String defaultClientName,
+ final ProvisionerTpm2.DeviceInfo tpmDeviceInfo) {
final List baseRims = referenceManifestRepository.findAllBaseRims();
final List unarchivedRims = referenceManifestRepository.findByArchiveFlag(false);
- final String deviceHostName = deviceInfoProto.getNw().getHostname();
+ final String deviceHostName = tpmDeviceInfo.getNw().getHostname();
log.info("Device {} sent SWID tag files", deviceHostName);
- for (ByteString swidFile : deviceInfoProto.getSwidfileList()) {
+ for (ByteString swidFile : tpmDeviceInfo.getSwidfileList()) {
try {
final String swidFileHash =
Base64.getEncoder().encodeToString(messageDigest.digest(swidFile.toByteArray()));
@@ -288,7 +323,7 @@ private void updateBaseRIMSUsingDeviceInfo(final String defaultClientName,
final BaseReferenceManifest baseRim =
(BaseReferenceManifest) referenceManifestRepository.findByBase64Hash(swidFileHash);
/*
- Either the swidFile does not have a corresponding base RIM in the backend
+ Either the swidFile does not have a corresponding base RIM in the backend,
or it was deleted. Check if there is a replacement by comparing tagId against
all other base RIMs, and then set the corresponding support rim's deviceName. */
if (baseRim == null) {
@@ -314,10 +349,8 @@ private void updateBaseRIMSUsingDeviceInfo(final String defaultClientName,
// otherwise save the replacement base RIM we created
this.referenceManifestRepository.save(replacementBaseRIM);
} else if (baseRim.isArchived()) {
- /*
- This block accounts for RIMs that may have been soft-deleted (archived)
- in an older version of the ACA.
- */
+ /* This block accounts for RIMs that may have been soft-deleted (archived)
+ in an older version of the ACA. */
// Filter out unarchived base RIMs that match the tagId and are newer than the baseRim
Optional matchedUnarchivedBaseRIMOptional = unarchivedRims.stream()
.filter(rim -> rim.isBase()
@@ -338,25 +371,29 @@ private void updateBaseRIMSUsingDeviceInfo(final String defaultClientName,
this.referenceManifestRepository.save(baseRim);
}
} catch (Exception exception) {
- log.error("Failed to process Bsase RIM file for device {}: {}", deviceHostName,
+ log.error("Failed to process Base RIM file for device {}: {}", deviceHostName,
exception.getMessage(), exception);
}
}
}
/**
- * @param defaultClientName
- * @param deviceInfoProto
+ * Helper method that updates the Support RIMs in the database using the information provided by the TPM's Device
+ * Info.
+ *
+ * @param defaultClientName default client name
+ * @param tpmDeviceInfo TPM Device Info
*/
- private void updateSupportRIMSUsingDeviceInfo(final String defaultClientName,
- final ProvisionerTpm2.DeviceInfo deviceInfoProto) {
- final String deviceHostName = deviceInfoProto.getNw().getHostname();
+ private void updateSupportRIMSUsingTPMDeviceInfo(final String defaultClientName,
+ final ProvisionerTpm2.DeviceInfo tpmDeviceInfo) {
+ final String deviceHostName = tpmDeviceInfo.getNw().getHostname();
+ final int NUM_OF_VARIABLES = 5;
log.info("Device {} sent Support RIM files", deviceHostName);
final List unarchivedRims = referenceManifestRepository.findByArchiveFlag(false);
- for (ByteString logFile : deviceInfoProto.getLogfileList()) {
+ for (ByteString logFile : tpmDeviceInfo.getLogfileList()) {
try {
final String logFileHash = Hex.encodeHexString(messageDigest.digest(logFile.toByteArray()));
@@ -365,11 +402,9 @@ private void updateSupportRIMSUsingDeviceInfo(final String defaultClientName,
logFileHash, ReferenceManifest.SUPPORT_RIM);
if (supportRim == null) {
- /*
- Either the logFile does not have a corresponding support RIM in the backend
+ /* Either the logFile does not have a corresponding support RIM in the backend,
or it was deleted. The support RIM for a replacement base RIM is handled
- in the previous loop block.
- */
+ in the previous loop block. */
final SupportReferenceManifest replacementSupportRIM =
new SupportReferenceManifest(String.format("%s.rimel", defaultClientName),
logFile.toByteArray());
@@ -378,8 +413,8 @@ private void updateSupportRIMSUsingDeviceInfo(final String defaultClientName,
new TCGEventLog(replacementSupportRIM.getRimBytes());
// no issues, continue
- replacementSupportRIM.setPlatformManufacturer(deviceInfoProto.getHw().getManufacturer());
- replacementSupportRIM.setPlatformModel(deviceInfoProto.getHw().getProductName());
+ replacementSupportRIM.setPlatformManufacturer(tpmDeviceInfo.getHw().getManufacturer());
+ replacementSupportRIM.setPlatformModel(tpmDeviceInfo.getHw().getProductName());
replacementSupportRIM.setFileName(String.format("%s_[%s].rimel", defaultClientName,
replacementSupportRIM.getHexDecHash().substring(
replacementSupportRIM.getHexDecHash().length() - NUM_OF_VARIABLES)));
@@ -418,11 +453,18 @@ private void updateSupportRIMSUsingDeviceInfo(final String defaultClientName,
}
}
- private void updateAllBaseAndSupportRIMS(ProvisionerTpm2.DeviceInfo deviceInfoProto) {
+ /**
+ * Helper method that updates both base and support RIMs after modifying each type of RIM, ensuring that the
+ * updates are consistent and aligned.
+ *
+ * @param tpmDeviceInfo TPM Device Info
+ */
+ private void updateBaseSupportRIMSUsingTpmDeviceInfo(ProvisionerTpm2.DeviceInfo tpmDeviceInfo) {
+ final String SUPPORT_RIM_FILE_PATTERN = "(\\S+(\\.(?i)(rimpcr|rimel|bin|log))$)";
final Pattern supportRimPattern = Pattern.compile(SUPPORT_RIM_FILE_PATTERN);
//update Support RIMs and Base RIMs.
- for (ByteString swidFile : deviceInfoProto.getSwidfileList()) {
+ for (ByteString swidFile : tpmDeviceInfo.getSwidfileList()) {
final String swidFileHash =
Base64.getEncoder().encodeToString(messageDigest.digest(swidFile.toByteArray()));
@@ -476,6 +518,7 @@ private void generateDigestRecords(final String manufacturer, final String model
SupportReferenceManifest baseSupportRim = null;
List supplementalRims = new ArrayList<>();
List patchRims = new ArrayList<>();
+
List dbSupportRims = this.referenceManifestRepository
.getSupportByManufacturerModel(manufacturer, model);
List expectedValues = referenceDigestValueRepository
@@ -566,20 +609,23 @@ private void generateDigestRecords(final String manufacturer, final String model
}
}
- private void updateSupportRIMSUsingEventLogAndDeviceInfo(ProvisionerTpm2.DeviceInfo deviceInfoProto) {
- log.info("Device sent bios measurement log...");
+ /**
+ * @param tpmDeviceInfo TPM Device Info
+ */
+ private void updateEventLogInfoUsingTPMDeviceInfo(ProvisionerTpm2.DeviceInfo tpmDeviceInfo) {
+ final String deviceHostName = tpmDeviceInfo.getNw().getHostname();
+ final String fileName = String.format("%s.measurement", deviceHostName);
- final String deviceInfoHostName = deviceInfoProto.getNw().getHostname();
+ log.info("Device {} sent bios measurement log...", deviceHostName);
- final String fileName = String.format("%s.measurement", deviceInfoHostName);
try {
- // grab the event log from protobuf's device info
- EventLogMeasurements deviceInfoProtoEventLog = new EventLogMeasurements(fileName,
- deviceInfoProto.getLivelog().toByteArray());
+ // grab the event log from TPM's device info
+ EventLogMeasurements tpmEventLog = new EventLogMeasurements(fileName,
+ tpmDeviceInfo.getLivelog().toByteArray());
// find the previous event log that's stored in the database.
EventLogMeasurements integrityMeasurements =
- referenceManifestRepository.byMeasurementDeviceNameUnarchived(deviceInfoHostName);
+ referenceManifestRepository.byMeasurementDeviceNameUnarchived(deviceHostName);
// if the event log does exist in the database
if (integrityMeasurements != null) {
@@ -589,13 +635,13 @@ private void updateSupportRIMSUsingEventLogAndDeviceInfo(ProvisionerTpm2.DeviceI
}
List baseRims = referenceManifestRepository.getBaseByManufacturerModel(
- deviceInfoProto.getHw().getManufacturer(),
- deviceInfoProto.getHw().getProductName());
+ tpmDeviceInfo.getHw().getManufacturer(),
+ tpmDeviceInfo.getHw().getProductName());
- deviceInfoProtoEventLog.setDeviceName(deviceInfoHostName);
- deviceInfoProtoEventLog.setPlatformManufacturer(deviceInfoProto.getHw().getManufacturer());
- deviceInfoProtoEventLog.setPlatformModel(deviceInfoProto.getHw().getProductName());
- this.referenceManifestRepository.save(deviceInfoProtoEventLog);
+ tpmEventLog.setDeviceName(deviceHostName);
+ tpmEventLog.setPlatformManufacturer(tpmDeviceInfo.getHw().getManufacturer());
+ tpmEventLog.setPlatformModel(tpmDeviceInfo.getHw().getProductName());
+ this.referenceManifestRepository.save(tpmEventLog);
for (BaseReferenceManifest bRim : baseRims) {
if (bRim != null) {
@@ -604,8 +650,8 @@ private void updateSupportRIMSUsingEventLogAndDeviceInfo(ProvisionerTpm2.DeviceI
SupportReferenceManifest sBaseRim = referenceManifestRepository
.getSupportRimEntityById(bRim.getAssociatedRim());
if (sBaseRim != null) {
- bRim.setEventLogHash(deviceInfoProtoEventLog.getHexDecHash());
- sBaseRim.setEventLogHash(deviceInfoProtoEventLog.getHexDecHash());
+ bRim.setEventLogHash(tpmEventLog.getHexDecHash());
+ sBaseRim.setEventLogHash(tpmEventLog.getHexDecHash());
referenceManifestRepository.save(bRim);
referenceManifestRepository.save(sBaseRim);
} else {
@@ -617,4 +663,35 @@ private void updateSupportRIMSUsingEventLogAndDeviceInfo(ProvisionerTpm2.DeviceI
log.error(exception);
}
}
+
+ /**
+ * Helper method that attempts to find all the provided device's components and stores them in the database.
+ *
+ * @param hostName device's host name
+ * @param paccorString string representation of the PACCOR tool output
+ */
+ private void processDeviceComponents(final String hostName, final String paccorString) {
+ Map componentInfoMap = new HashMap<>();
+
+ try {
+ List componentInfos =
+ SupplyChainCredentialValidator.getComponentInfoFromPaccorOutput(hostName, paccorString);
+
+ // check the DB for like component infos
+ List dbComponentInfos = this.componentInfoRepository.findByDeviceName(hostName);
+ dbComponentInfos.forEach((infos) -> componentInfoMap.put(infos.hashCode(), infos));
+
+ for (ComponentInfo componentInfo : dbComponentInfos) {
+ if (componentInfoMap.containsKey(componentInfo.hashCode())) {
+ componentInfos.remove(componentInfo);
+ }
+ }
+
+ for (ComponentInfo componentInfo : componentInfos) {
+ this.componentInfoRepository.save(componentInfo);
+ }
+ } catch (IOException ioEx) {
+ log.warn("Error parsing paccor string");
+ }
+ }
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
index 51ff31761..efca79e55 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
@@ -4,26 +4,18 @@
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
-import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.manager.ComponentInfoRepository;
-import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
import hirs.attestationca.persist.entity.manager.DeviceRepository;
import hirs.attestationca.persist.entity.manager.PolicyRepository;
import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository;
import hirs.attestationca.persist.entity.tpm.TPM2ProvisionerState;
-import hirs.attestationca.persist.entity.userdefined.Certificate;
import hirs.attestationca.persist.entity.userdefined.Device;
import hirs.attestationca.persist.entity.userdefined.PolicySettings;
import hirs.attestationca.persist.entity.userdefined.SupplyChainValidationSummary;
-import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult;
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
-import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
-import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
-import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import hirs.attestationca.persist.enums.AppraisalStatus;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
-import hirs.attestationca.persist.validation.SupplyChainCredentialValidator;
import hirs.utils.HexUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ArrayUtils;
@@ -32,10 +24,7 @@
import java.io.IOException;
import java.security.PublicKey;
-import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
@Service
@Log4j2
@@ -47,10 +36,8 @@ public class IdentityClaimProcessorService {
private static final String PCR_QUOTE_MASK = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23";
private final SupplyChainValidationService supplyChainValidationService;
- private final CredentialManagementService credentialManagementService;
+ private final CertificateManagementService certificateManagementService;
private final DeviceInfoProcessorService deviceInfoProcessorService;
- private final CertificateRepository certificateRepository;
- private final ComponentResultRepository componentResultRepository;
private final ComponentInfoRepository componentInfoRepository;
private final DeviceRepository deviceRepository;
private final PolicyRepository policyRepository;
@@ -60,8 +47,6 @@ public class IdentityClaimProcessorService {
* Constructor.
*
* @param supplyChainValidationService supply chain validation service
- * @param certificateRepository certificate repository
- * @param componentResultRepository component result repository
* @param componentInfoRepository component info repository
* @param deviceRepository device repository
* @param tpm2ProvisionerStateRepository tpm2 provisioner state repository
@@ -70,17 +55,13 @@ public class IdentityClaimProcessorService {
@Autowired
public IdentityClaimProcessorService(
final SupplyChainValidationService supplyChainValidationService,
- final CredentialManagementService credentialManagementService,
- final CertificateRepository certificateRepository,
- final ComponentResultRepository componentResultRepository,
+ final CertificateManagementService certificateManagementService,
final ComponentInfoRepository componentInfoRepository,
final DeviceRepository deviceRepository, DeviceInfoProcessorService deviceInfoProcessorService,
final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
final PolicyRepository policyRepository) {
this.supplyChainValidationService = supplyChainValidationService;
- this.credentialManagementService = credentialManagementService;
- this.certificateRepository = certificateRepository;
- this.componentResultRepository = componentResultRepository;
+ this.certificateManagementService = certificateManagementService;
this.componentInfoRepository = componentInfoRepository;
this.deviceRepository = deviceRepository;
this.deviceInfoProcessorService = deviceInfoProcessorService;
@@ -238,49 +219,17 @@ private AppraisalStatus.Status doSupplyChainValidation(final ProvisionerTpm2.Ide
// attempt to find an endorsement credential to validate
EndorsementCredential endorsementCredential =
- credentialManagementService.parseEcFromIdentityClaim(claim, ekPub);
+ certificateManagementService.parseEcFromIdentityClaim(claim, ekPub);
// attempt to find platform credentials to validate
- List platformCredentials = credentialManagementService.parsePcsFromIdentityClaim(claim,
+ List platformCredentials = certificateManagementService.parsePcsFromIdentityClaim(claim,
endorsementCredential);
// Parse and save device info
Device device = deviceInfoProcessorService.processDeviceInfo(claim);
-
- handleDeviceComponents(device.getDeviceInfo().getNetworkInfo().getHostname(), claim.getPaccorOutput());
-
- // There are situations in which the claim is sent with no PCs
- // or a PC from the tpm which will be deprecated
- // this is to check what is in the platform object and pull
- // additional information from the DB if information exists
- if (platformCredentials.size() == 1) {
- List tempList = new LinkedList<>();
- for (PlatformCredential pc : platformCredentials) {
- if (pc != null && pc.getPlatformSerial() != null) {
- tempList.addAll(certificateRepository.byBoardSerialNumber(pc.getPlatformSerial()));
- }
- }
- platformCredentials.addAll(tempList);
- }
-
- // store component results objects
- for (PlatformCredential platformCredential : platformCredentials) {
- List componentResults =
- componentResultRepository.findByCertificateSerialNumberAndBoardSerialNumber(
- platformCredential.getSerialNumber().toString(),
- platformCredential.getPlatformSerial());
-
- if (componentResults.isEmpty()) {
- savePlatformComponents(platformCredential);
- } else {
- componentResults.forEach((componentResult) -> {
- componentResult.restore();
- componentResult.resetCreateTime();
- componentResultRepository.save(componentResult);
- });
- }
- }
+ // Store the platform certificates' components
+ certificateManagementService.saveOrUpdatePlatformCertificateComponents(platformCredentials);
// perform supply chain validation
SupplyChainValidationSummary summary = supplyChainValidationService.validateSupplyChain(
@@ -295,78 +244,4 @@ private AppraisalStatus.Status doSupplyChainValidation(final ProvisionerTpm2.Ide
return validationResult;
}
-
-
- /**
- * Helper method that saves the provided platform certificate's components in the database.
- *
- * @param certificate certificate
- */
- private void savePlatformComponents(final Certificate certificate) throws IOException {
- PlatformCredential platformCredential;
-
- if (certificate instanceof PlatformCredential) {
- platformCredential = (PlatformCredential) certificate;
- ComponentResult componentResult;
-
- if (platformCredential.getPlatformConfigurationV1() != null) {
- List componentIdentifiers = platformCredential
- .getComponentIdentifiers();
-
- for (ComponentIdentifier componentIdentifier : componentIdentifiers) {
- componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
- platformCredential.getSerialNumber().toString(),
- platformCredential.getPlatformChainType(),
- componentIdentifier);
- componentResult.setFailedValidation(false);
- componentResult.setDelta(!platformCredential.isPlatformBase());
- componentResultRepository.save(componentResult);
- }
- } else if (platformCredential.getPlatformConfigurationV2() != null) {
- List componentIdentifiersV2 = platformCredential
- .getComponentIdentifiersV2();
-
- for (ComponentIdentifierV2 componentIdentifierV2 : componentIdentifiersV2) {
- componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
- platformCredential.getSerialNumber().toString(),
- platformCredential.getPlatformChainType(),
- componentIdentifierV2);
- componentResult.setFailedValidation(false);
- componentResult.setDelta(!platformCredential.isPlatformBase());
- componentResultRepository.save(componentResult);
- }
- }
- }
- }
-
- /**
- * Helper method that attempts to find all the provided device's components.
- *
- * @param hostName device's host name
- * @param paccorString string representation of the paccor tool output
- */
- private void handleDeviceComponents(final String hostName, final String paccorString) {
- Map componentInfoMap = new HashMap<>();
-
- try {
- List componentInfos = SupplyChainCredentialValidator
- .getComponentInfoFromPaccorOutput(hostName, paccorString);
-
- // check the DB for like component infos
- List dbComponentInfos = this.componentInfoRepository.findByDeviceName(hostName);
- dbComponentInfos.forEach((infos) -> componentInfoMap.put(infos.hashCode(), infos));
-
- for (ComponentInfo componentInfo : dbComponentInfos) {
- if (componentInfoMap.containsKey(componentInfo.hashCode())) {
- componentInfos.remove(componentInfo);
- }
- }
-
- for (ComponentInfo componentInfo : componentInfos) {
- this.componentInfoRepository.save(componentInfo);
- }
- } catch (IOException ioEx) {
- log.warn("Error parsing paccor string");
- }
- }
}
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementServiceTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CertificateManagementServiceTest.java
similarity index 76%
rename from HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementServiceTest.java
rename to HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CertificateManagementServiceTest.java
index f9f7c3133..80973b687 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementServiceTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CertificateManagementServiceTest.java
@@ -2,7 +2,7 @@
import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.userdefined.Certificate;
-import hirs.attestationca.persist.provision.service.CredentialManagementService;
+import hirs.attestationca.persist.provision.service.CertificateManagementService;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -20,16 +20,16 @@
import static org.mockito.Mockito.verify;
/**
- * Unit tests for {@see CredentialManagementService}.
+ * Unit tests for {@see CertificateManagementService}.
*/
-public class CredentialManagementServiceTest {
+public class CertificateManagementServiceTest {
private static final String EK_HEADER_TRUNCATED = "/certificates/nuc-1/ek_cert_7_byte_header_removed.cer";
private static final String EK_UNTOUCHED = "/certificates/nuc-1/ek_cert_untouched.cer";
@InjectMocks
- private CredentialManagementService credentialManagementService;
+ private CertificateManagementService certificateManagementService;
@Mock
private CertificateRepository certificateRepository;
@@ -65,7 +65,7 @@ public void tearDown() throws Exception {
@Test
public void processNullEndorsementCredential() {
assertThrows(IllegalArgumentException.class, () ->
- credentialManagementService.storeEndorsementCredential(null,
+ certificateManagementService.storeEndorsementCredential(null,
"testName"));
}
@@ -75,7 +75,7 @@ public void processNullEndorsementCredential() {
@Test
public void processEmptyEndorsementCredential() {
assertThrows(IllegalArgumentException.class, () ->
- credentialManagementService.storeEndorsementCredential(new byte[0], "testName"));
+ certificateManagementService.storeEndorsementCredential(new byte[0], "testName"));
}
/**
@@ -85,7 +85,7 @@ public void processEmptyEndorsementCredential() {
public void processInvalidEndorsementCredentialCase1() {
byte[] ekBytes = new byte[]{1};
assertThrows(IllegalArgumentException.class, () ->
- credentialManagementService.storeEndorsementCredential(ekBytes, "testName"));
+ certificateManagementService.storeEndorsementCredential(ekBytes, "testName"));
}
/**
@@ -95,7 +95,7 @@ public void processInvalidEndorsementCredentialCase1() {
public void processInvalidEndorsementCredentialCase2() {
byte[] ekBytes = new byte[]{1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0};
assertThrows(IllegalArgumentException.class, () ->
- credentialManagementService.storeEndorsementCredential(ekBytes,
+ certificateManagementService.storeEndorsementCredential(ekBytes,
"testName"));
}
@@ -106,10 +106,11 @@ public void processInvalidEndorsementCredentialCase2() {
*/
@Test
public void parseUntouchedEndorsementCredential() throws IOException {
- String path = Objects.requireNonNull(CredentialManagementServiceTest.class.getResource(EK_UNTOUCHED)).getPath();
+ String path =
+ Objects.requireNonNull(CertificateManagementServiceTest.class.getResource(EK_UNTOUCHED)).getPath();
byte[] ekBytes = IOUtils.toByteArray(new FileInputStream(path));
- credentialManagementService.storeEndorsementCredential(ekBytes, "testName");
+ certificateManagementService.storeEndorsementCredential(ekBytes, "testName");
verify(certificateRepository).save(any(Certificate.class));
}
@@ -120,11 +121,11 @@ public void parseUntouchedEndorsementCredential() throws IOException {
*/
@Test
public void parseHeaderTruncatedEndorsementCredential() throws IOException {
- String path = Objects.requireNonNull(CredentialManagementServiceTest.class.getResource(EK_HEADER_TRUNCATED))
+ String path = Objects.requireNonNull(CertificateManagementServiceTest.class.getResource(EK_HEADER_TRUNCATED))
.getPath();
byte[] ekBytes = IOUtils.toByteArray(new FileInputStream(path));
- credentialManagementService.storeEndorsementCredential(ekBytes, "testName");
+ certificateManagementService.storeEndorsementCredential(ekBytes, "testName");
verify(certificateRepository).save(any(Certificate.class));
}
}
From a19068280fb1e92cd3c8b92f480db311c062d22d Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Fri, 6 Mar 2026 16:12:36 -0500
Subject: [PATCH 13/25] v3.1_issue_1090: Fixed the error that is mentioned in
the issue. Will need to add algo param to the powershell scripts so this
works on windows and will have to address scenarios where the ak and ek keys
are not rsa keys. currently have a method that handles that situation but
will need to figure out how to implement that issue.
---
.../SupplyChainValidationRepository.java | 2 +-
.../persist/enums/PublicKeyAlgorithm.java | 19 +-
...ionCertificateAuthorityRestController.java | 4 +-
.../provision/helper/ProvisionUtils.java | 70 ++--
...tationCertificateAuthorityServiceImpl.java | 2 +-
.../CertificateRequestProcessorService.java | 268 +++++++-------
....java => CredentialManagementService.java} | 20 +-
.../service/DeviceInfoProcessorService.java | 339 +++++++++---------
.../IdentityClaimProcessorService.java | 96 ++---
.../provision/service/package-info.java | 1 +
...tationCertificateAuthorityServiceTest.java | 6 +-
...a => CredentialManagementServiceTest.java} | 22 +-
.../resources/{public_keys => tpm2}/ak.name | Bin
.../resources/{public_keys => tpm2}/ak.pub | Bin
.../resources/{public_keys => tpm2}/ek.pub | Bin
15 files changed, 434 insertions(+), 415 deletions(-)
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/{CertificateManagementService.java => CredentialManagementService.java} (95%)
create mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/package-info.java
rename HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/{CertificateManagementServiceTest.java => CredentialManagementServiceTest.java} (78%)
rename HIRS_AttestationCA/src/test/resources/{public_keys => tpm2}/ak.name (100%)
rename HIRS_AttestationCA/src/test/resources/{public_keys => tpm2}/ak.pub (100%)
rename HIRS_AttestationCA/src/test/resources/{public_keys => tpm2}/ek.pub (100%)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationRepository.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationRepository.java
index e9446c0f6..b7571b423 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationRepository.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/SupplyChainValidationRepository.java
@@ -25,4 +25,4 @@ public interface SupplyChainValidationRepository extends JpaRepository findByValidationResult(AppraisalStatus.Status validationResult);
-}
\ No newline at end of file
+}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
index 243e56fe2..4e43467db 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
@@ -38,7 +38,7 @@ public enum PublicKeyAlgorithm {
UNKNOWN(0xFFFF, "UNKNOWN");
/**
- * The hexadecimal representation of the algorithm ID.
+ * The hexadecimal representation of the algorithm ID as represented in the TCG documents.
*/
private final int algorithmId;
@@ -46,22 +46,7 @@ public enum PublicKeyAlgorithm {
* The name of the algorithm.
*/
private final String algorithmName;
-
- /**
- * Converts the provided string public key algorithm into an ENUM.
- *
- * @param algorithmAsString public key algorithm name as a string
- * @return ENUM representation of the public key algorithm
- */
- public static PublicKeyAlgorithm fromString(final String algorithmAsString) {
- for (PublicKeyAlgorithm algorithmEnum : PublicKeyAlgorithm.values()) {
- if (algorithmEnum.getAlgorithmName().equalsIgnoreCase(algorithmAsString)) {
- return algorithmEnum;
- }
- }
- return UNKNOWN; // Return UNKNOWN if no match is found
- }
-
+
/**
* Retrieves the enum by the algorithm ID.
*
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java
index 0c0e728e1..346df7117 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java
@@ -59,9 +59,9 @@ public byte[] processCertificateRequest(@RequestBody final byte[] certificateReq
}
/**
- * Processes a GET request to retrieve the byte array representation of the public key.
+ * Processes a GET request to retrieve the byte array representation of the leaf ACA certificate's public key.
*
- * @return byte array representation of the public key
+ * @return byte array representation of the leaf ACA certificate's public key
*/
@ResponseBody
@GetMapping("/public-key")
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index 824066124..84dc43022 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -185,12 +185,15 @@ public static PublicKeyAlgorithm determinePublicKeyAlgorithm(byte[] byteArray) {
return PublicKeyAlgorithm.UNKNOWN;
}
+ final int unsignedByteMask = 0xFF;
+ final int byteShiftVal = 8;
+
// Extract the first two bytes from the byte array and combine them into a 16-bit integer (algorithm ID).
// - `byteArray[0] & 0xFF` ensures the first byte is treated as unsigned (0-255 range).
// - `<< 8` shifts the first byte 8 bits to the left, placing it in the higher byte of the 16-bit value.
// - `byteArray[1] & 0xFF` ensures the second byte is treated as unsigned, then it occupies the lower byte.
// - The bitwise OR (`|`) combines the two parts into a single 16-bit value (int).
- final int algorithmId = ((byteArray[0] & 0xFF) << 8) | (byteArray[1] & 0xFF);
+ final int algorithmId = ((byteArray[0] & unsignedByteMask) << byteShiftVal) | (byteArray[1] & unsignedByteMask);
// Compare the extracted ID with the enums
return PublicKeyAlgorithm.fromId(algorithmId);
@@ -250,7 +253,6 @@ public static RSAPublicKey assembleRSAPublicKey(final BigInteger modulus) {
}
/**
- * todo
* Parses the ECC public key from public data segment generated by TPM 2.0.
*
* @param publicDataSegment the public area segment to parse
@@ -273,10 +275,12 @@ public static ECPublicKey parseECCKeyFromPublicDataSegment(final byte[] publicDa
}
/**
- * todo
+ * Assembles the ECC public key using the provided byte array.
+ *
+ * @param eccKeySection ecc public key section of the byte array
+ * @return the ECC public key
*/
public static ECPublicKey assembleECCPublicKey(final byte[] eccKeySection) {
- // create the ECC public key
try {
KeyFactory keyFactory = KeyFactory.getInstance("EC");
@@ -292,33 +296,34 @@ public static ECPublicKey assembleECCPublicKey(final byte[] eccKeySection) {
}
/**
- * @param endorsementPublicKey endorsement key in the identity claim
- * @param attestationPublicKey attestation key in the identity claim
+ * Determines the public key algorithm of both the endorsement and attestation public key in order to
+ * properly create a credential blob string.
+ *
+ * @param endorsementPublicKey endorsement public key in the identity claim
+ * @param attestationPublicKey attestation public key in the identity claim
* @param secret a nonce
* @return the encrypted blob forming the identity claim challenge
*/
- public static ByteString tpm20MakeCredential(
- final PublicKey endorsementPublicKey,
- final PublicKey attestationPublicKey,
- final byte[] secret) {
-
- final PublicKeyAlgorithm publicKeyAlgorithm = PublicKeyAlgorithm.RSA;
-
+ public static ByteString tpm20MakeCredential(final PublicKey endorsementPublicKey,
+ final PublicKey attestationPublicKey,
+ final byte[] secret) {
// check size of the secret
if (secret.length > MAX_SECRET_LENGTH) {
- throw new IllegalArgumentException("Secret must be " + MAX_SECRET_LENGTH
- + " bytes or smaller.");
+ throw new IllegalArgumentException("Secret must be " + MAX_SECRET_LENGTH + " bytes or smaller.");
}
- return switch (publicKeyAlgorithm) {
- case RSA -> tpm20MakeCredentialUsingRSA(
+ if (endorsementPublicKey instanceof RSAPublicKey && attestationPublicKey instanceof RSAPublicKey) {
+ return tpm20MakeCredentialUsingRSA(
(RSAPublicKey) endorsementPublicKey,
(RSAPublicKey) attestationPublicKey, secret);
- case ECC -> tpm20MakeCredentialUsingECC(
+ } else if (endorsementPublicKey instanceof ECPublicKey && attestationPublicKey instanceof ECPublicKey) {
+ return tpm20MakeCredentialUsingECC(
(ECPublicKey) endorsementPublicKey,
(ECPublicKey) attestationPublicKey, secret);
- default -> throw new UnsupportedOperationException("Unsupported or invalid public key algorithm");
- };
+ }
+
+ throw new UnsupportedOperationException("Mismatched or unsupported public key algorithms: "
+ + endorsementPublicKey.getAlgorithm() + " / " + attestationPublicKey.getAlgorithm());
}
/**
@@ -351,9 +356,10 @@ public static ByteString tpm20MakeCredentialUsingRSA(final RSAPublicKey endorsem
try {
// encrypt seed with endorsement RSA Public Key
Cipher asymCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
+
OAEPParameterSpec oaepSpec = new OAEPParameterSpec("SHA-256", "MGF1",
- MGF1ParameterSpec.SHA256,
- new PSource.PSpecified("IDENTITY\0".getBytes(StandardCharsets.UTF_8)));
+ MGF1ParameterSpec.SHA256, new PSource.PSpecified("IDENTITY\0".getBytes(StandardCharsets.UTF_8)));
+
asymCipher.init(Cipher.PUBLIC_KEY, endorsementRSAKey, oaepSpec);
asymCipher.update(seed);
byte[] encSeed = asymCipher.doFinal();
@@ -417,6 +423,7 @@ public static ByteString tpm20MakeCredentialUsingRSA(final RSAPublicKey endorsem
}
/**
+ * todo
* Performs the first step of the TPM 2.0 identity claim process using the ECC public key algorithm:
*
* - Takes an ek, ak, and secret and generates a seed that is used to generate AES and HMAC keys.
@@ -441,22 +448,7 @@ public static ByteString tpm20MakeCredentialUsingECC(final ECPublicKey endorseme
final ECPublicKey attestationECCKey,
final byte[] secret) {
- // generate a random 32 byte seed
- //byte[] seed = generateRandomBytes(SEED_LENGTH);
-
- try {
- // encrypt seed with endorsement ECC Public Key
- // Cipher asymCipher = Cipher.getInstance("");
-
- } catch (Exception e) {
- throw new IdentityProcessingException(
- "Encountered error while making the identity claim challenge for the " +
- "provided ECC public keys: "
- + e.getMessage(), e);
- }
-
- //todo
- return ByteString.copyFrom(new byte[]{});
+ throw new UnsupportedOperationException("");
}
/**
@@ -665,7 +657,7 @@ public static byte[] generateRandomBytes(final int numberOfBytes) {
* @param date2 second provided date
* @return difference in days between two dates
*/
- public static int daysBetween(final Date date1, final Date date2) {
+ public static int calculateDaysBetweenDates(final Date date1, final Date date2) {
final int hoursInADay = 24;
final int secondsInAnHour = 3600;
final int millisecondsInASecond = 1000;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java
index dc013c12b..30ecbe4bd 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java
@@ -5,7 +5,7 @@
import org.springframework.stereotype.Service;
/**
- * Service layer class responsible for handling both certificate and identity claim requests made by the provisioner.
+ * Service class responsible for handling both certificate and identity claim requests made by the provisioner.
*/
@Service
@Log4j2
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
index 5317d400a..cfbc93605 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
@@ -43,15 +43,21 @@
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.RSAPrivateKey;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
+import java.util.Objects;
+/**
+ * Service class responsible for processing the Provisioner's certificate request.
+ */
@Service
@Log4j2
public class CertificateRequestProcessorService {
private final SupplyChainValidationService supplyChainValidationService;
- private final CertificateManagementService certificateManagementService;
+ private final CredentialManagementService credentialManagementService;
private final DeviceRepository deviceRepository;
private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
private final PolicyRepository policyRepository;
@@ -63,25 +69,25 @@ public class CertificateRequestProcessorService {
* Constructor.
*
* @param supplyChainValidationService object that is used to run provisioning
- * @param certificateManagementService credential management service
+ * @param credentialManagementService credential management service
* @param deviceRepository database connector for Devices.
* @param tpm2ProvisionerStateRepository db connector for provisioner state.
+ * @param policyRepository db connector for policies.
* @param privateKey private key used for communication authentication
* @param acaCertificate object used to create credential
* @param certificateValidityInDays int for the time in which a certificate is valid.
- * @param policyRepository db connector for policies.
*/
@Autowired
public CertificateRequestProcessorService(final SupplyChainValidationService supplyChainValidationService,
- final CertificateManagementService certificateManagementService,
+ final CredentialManagementService credentialManagementService,
final DeviceRepository deviceRepository,
final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
+ final PolicyRepository policyRepository,
final PrivateKey privateKey,
@Qualifier("leafACACert") final X509Certificate acaCertificate,
- @Value("${aca.certificates.validity}")
- final int certificateValidityInDays,
- final PolicyRepository policyRepository) {
- this.certificateManagementService = certificateManagementService;
+ @Value("${aca.certificates.validity}") final int certificateValidityInDays
+ ) {
+ this.credentialManagementService = credentialManagementService;
this.certificateValidityInDays = certificateValidityInDays;
this.supplyChainValidationService = supplyChainValidationService;
this.deviceRepository = deviceRepository;
@@ -101,18 +107,16 @@ public byte[] getLeafACACertificatePublicKey() {
}
/**
- * Basic implementation of the ACA processCertificateRequest method.
- * Parses the nonce, validates its correctness, generates the signed,
- * public attestation certificate, stores it, and returns it to the client.
+ * Basic implementation of the ACA processCertificateRequest method. Parses the nonce, validates its correctness,
+ * generates the signed, public attestation certificate, stores it, and returns it to the client.
*
- * @param certificateRequest request containing nonce from earlier identity
- * claim handshake
+ * @param certificateRequestByteArray request containing nonce from earlier identity claim handshake
* @return a certificateResponse containing the signed certificate
*/
- public byte[] processCertificateRequest(final byte[] certificateRequest) {
+ public byte[] processCertificateRequest(final byte[] certificateRequestByteArray) {
log.info("Certificate Request has been received and is ready to be processed");
- if (ArrayUtils.isEmpty(certificateRequest)) {
+ if (ArrayUtils.isEmpty(certificateRequestByteArray)) {
final String errorMsg = "The CertificateRequest sent by the client cannot be null or empty.";
log.error(errorMsg);
throw new IllegalArgumentException(errorMsg);
@@ -121,9 +125,9 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
final PolicySettings policySettings = policyRepository.findByName("Default");
// attempt to deserialize Protobuf CertificateRequest
- ProvisionerTpm2.CertificateRequest request;
+ ProvisionerTpm2.CertificateRequest certificateRequest;
try {
- request = ProvisionerTpm2.CertificateRequest.parseFrom(certificateRequest);
+ certificateRequest = ProvisionerTpm2.CertificateRequest.parseFrom(certificateRequestByteArray);
} catch (InvalidProtocolBufferException ipbe) {
final String errorMsg = "Could not deserialize Protobuf Certificate Request object.";
log.error(errorMsg);
@@ -132,82 +136,57 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
String certificateRequestJsonString = "";
try {
- certificateRequestJsonString = JsonFormat.printer().print(request);
+ certificateRequestJsonString = JsonFormat.printer().print(certificateRequest);
} catch (InvalidProtocolBufferException exception) {
log.error("Certificate request could not be parsed properly into a JSON string");
}
// attempt to retrieve provisioner state based on nonce in request
- TPM2ProvisionerState tpm2ProvisionerState = getTpm2ProvisionerState(request);
+ TPM2ProvisionerState tpm2ProvisionerState = getTpm2ProvisionerState(certificateRequest);
if (tpm2ProvisionerState != null) {
- // Reparse Identity Claim to gather necessary components
- byte[] identityClaim = tpm2ProvisionerState.getIdentityClaim();
- ProvisionerTpm2.IdentityClaim claim = ProvisionUtils.parseIdentityClaim(identityClaim);
+ // Parse Identity Claim to gather necessary components
+ ProvisionerTpm2.IdentityClaim identityClaim =
+ ProvisionUtils.parseIdentityClaim(tpm2ProvisionerState.getIdentityClaim());
// Get endorsement public key
PublicKey ekPublicKey = ProvisionUtils.parsePublicKeyFromPublicDataSegment(
- claim.getEkPublicArea().toByteArray());
+ identityClaim.getEkPublicArea().toByteArray());
// Get attestation public key
PublicKey akPublicKey = ProvisionUtils.parsePublicKeyFromPublicDataSegment(
- claim.getAkPublicArea().toByteArray());
-
- // Get Endorsement Credential if it exists or was uploaded
- EndorsementCredential endorsementCredential =
- certificateManagementService.parseEcFromIdentityClaim(claim, ekPublicKey);
-
- // Get Platform Credentials if they exist or were uploaded
- List platformCredentials = certificateManagementService.parsePcsFromIdentityClaim(claim,
- endorsementCredential);
+ identityClaim.getAkPublicArea().toByteArray());
// Get LDevID public key if it exists
PublicKey ldevidPublicKey = null;
- if (claim.hasLdevidPublicArea()) {
+ if (identityClaim.hasLdevidPublicArea()) {
ldevidPublicKey = ProvisionUtils.parsePublicKeyFromPublicDataSegment(
- claim.getLdevidPublicArea().toByteArray());
+ identityClaim.getLdevidPublicArea().toByteArray());
}
- // Get device name and device
- String deviceName = claim.getDv().getNw().getHostname();
- Device device = deviceRepository.findByName(deviceName);
-
- // Parse through the Provisioner supplied TPM Quote and pcr values
- // these fields are optional
- if (!request.getQuote().isEmpty()) {
- TPMInfo savedInfo = device.getDeviceInfo().getTpmInfo();
- TPMInfo tpmInfo = new TPMInfo(savedInfo.getTpmMake(),
- savedInfo.getTpmVersionMajor(),
- savedInfo.getTpmVersionMinor(),
- savedInfo.getTpmVersionRevMajor(),
- savedInfo.getTpmVersionRevMinor(),
- savedInfo.getPcrValues(),
- ProvisionUtils.parseTPMQuoteHash(request.getQuote().toStringUtf8())
- .getBytes(StandardCharsets.UTF_8),
- ProvisionUtils.parseTPMQuoteSignature(request.getQuote().toStringUtf8())
- .getBytes(StandardCharsets.UTF_8));
-
- DeviceInfoReport dvReport = new DeviceInfoReport(
- device.getDeviceInfo().getNetworkInfo(),
- device.getDeviceInfo().getOSInfo(),
- device.getDeviceInfo().getFirmwareInfo(),
- device.getDeviceInfo().getHardwareInfo(), tpmInfo,
- claim.getClientVersion());
-
- device.setDeviceInfo(dvReport);
- device = this.deviceRepository.save(device);
- }
+ // Get Endorsement Credential if it exists or was uploaded
+ EndorsementCredential endorsementCredential =
+ credentialManagementService.parseEcFromIdentityClaim(identityClaim, ekPublicKey);
+
+ // Get Platform Credentials if they exist or were uploaded
+ List platformCredentials =
+ credentialManagementService.parsePcsFromIdentityClaim(identityClaim,
+ endorsementCredential);
+
+ // Get the device associated with the identity claim. Update the device if the cert request quote exists.
+ Device device = retrieveDeviceWithUpdatedTPMInfo(certificateRequest, identityClaim);
AppraisalStatus.Status validationResult = doQuoteValidation(device);
+
if (validationResult == AppraisalStatus.Status.PASS) {
// Create signed, attestation certificate
X509Certificate attestationCertificate = generateCredential(akPublicKey,
- endorsementCredential, platformCredentials, deviceName, acaCertificate);
+ endorsementCredential, platformCredentials, device.getName(), acaCertificate);
if (ldevidPublicKey != null) {
// Create signed LDevID certificate
X509Certificate ldevidCertificate = generateCredential(ldevidPublicKey,
- endorsementCredential, platformCredentials, deviceName, acaCertificate);
+ endorsementCredential, platformCredentials, device.getName(), acaCertificate);
byte[] derEncodedAttestationCertificate = ProvisionUtils.getDerEncodedCertificate(
attestationCertificate);
byte[] derEncodedLdevidCertificate = ProvisionUtils.getDerEncodedCertificate(
@@ -221,16 +200,16 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
tpm2ProvisionerStateRepository.delete(tpm2ProvisionerState);
boolean generateAtt =
- certificateManagementService.saveAttestationCertificate(derEncodedAttestationCertificate,
+ credentialManagementService.saveAttestationCertificate(derEncodedAttestationCertificate,
endorsementCredential, platformCredentials, device, false);
boolean generateLDevID =
- certificateManagementService.saveAttestationCertificate(derEncodedLdevidCertificate,
+ credentialManagementService.saveAttestationCertificate(derEncodedLdevidCertificate,
endorsementCredential, platformCredentials, device, true);
ProvisionerTpm2.CertificateResponse.Builder certificateResponseBuilder =
- ProvisionerTpm2.CertificateResponse.
- newBuilder().setStatus(ProvisionerTpm2.ResponseStatus.PASS);
+ ProvisionerTpm2.CertificateResponse.newBuilder()
+ .setStatus(ProvisionerTpm2.ResponseStatus.PASS);
if (generateAtt) {
certificateResponseBuilder =
@@ -245,11 +224,11 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
String certResponseJsonStringAfterSuccess = "";
try {
- certResponseJsonStringAfterSuccess = JsonFormat.printer().print(request);
+ certResponseJsonStringAfterSuccess = JsonFormat.printer().print(certificateRequest);
} catch (InvalidProtocolBufferException exception) {
log.error("Certificate response object after a successful validation, "
+ "assuming the LDevId public key exists, could not be parsed "
- + "properly into a json string");
+ + "properly into a JSON string");
}
if (!policySettings.isSaveProtobufToLogNeverEnabled()
@@ -261,7 +240,7 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
log.info("Certificate request object received after a successful validation "
+ " and if the LDevID public key exists {}",
certificateRequestJsonString.isEmpty()
- ? request : certificateRequestJsonString);
+ ? certificateRequest : certificateRequestJsonString);
log.info("Certificate Response "
+ "object after a successful validation and if the LDevID "
@@ -287,7 +266,7 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
ProvisionerTpm2.CertificateResponse.
newBuilder().setStatus(ProvisionerTpm2.ResponseStatus.PASS);
- boolean generateAtt = certificateManagementService.saveAttestationCertificate(
+ boolean generateAtt = credentialManagementService.saveAttestationCertificate(
derEncodedAttestationCertificate,
endorsementCredential, platformCredentials, device, false);
@@ -300,11 +279,11 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
String certResponseJsonStringAfterSuccess = "";
try {
- certResponseJsonStringAfterSuccess = JsonFormat.printer().print(request);
+ certResponseJsonStringAfterSuccess = JsonFormat.printer().print(certificateRequest);
} catch (InvalidProtocolBufferException exception) {
log.error("Certificate response object after a successful validation, "
+ "assuming the LDevId public key does not exist, could not be parsed "
- + "propertly into a json string");
+ + "properly into a JSON string");
}
if (!policySettings.isSaveProtobufToLogNeverEnabled()
@@ -317,7 +296,7 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
log.info("Certificate request object received after a successful validation "
+ " and if the LDevID public key does not exist {}",
certificateRequestJsonString.isEmpty()
- ? request : certificateRequestJsonString);
+ ? certificateRequest : certificateRequestJsonString);
log.info("Certificate Request Response "
+ "object after a successful validation and if the LDevID "
@@ -342,10 +321,10 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
String certResponseJsonStringAfterFailure = "";
try {
- certResponseJsonStringAfterFailure = JsonFormat.printer().print(request);
+ certResponseJsonStringAfterFailure = JsonFormat.printer().print(certificateRequest);
} catch (InvalidProtocolBufferException exception) {
log.error("Certificate response object after a failed validation could not be parsed"
- + " properly into a json string");
+ + " properly into a JSON string");
}
if (!policySettings.isSaveProtobufToLogNeverEnabled()
@@ -355,9 +334,8 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
+ " After Failed Validation -------------");
log.info("Certificate request object received after a failed validation:"
- + " {}", request);
- log.info("Certificate Request Response "
- + "object after a failed validation: {}",
+ + " {}", certificateRequest);
+ log.info("Certificate Request Response object after a failed validation: {}",
certResponseJsonStringAfterFailure.isEmpty()
? certificateResponse : certResponseJsonStringAfterFailure);
@@ -375,7 +353,7 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
+ "Validation (Invalid Nonce) -------------");
log.error("Could not process credential request. Invalid nonce provided: {}",
- certificateRequestJsonString.isEmpty() ? request : certificateRequestJsonString);
+ certificateRequestJsonString.isEmpty() ? certificateRequest : certificateRequestJsonString);
log.info("------------- End Of Protobuf Log Of Certificate Request After Failed "
+ "Validation (Invalid Nonce) -------------");
@@ -384,6 +362,49 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
}
}
+ /**
+ * Helper method that retrieves a {@link Device} object from the Identity Claim and updates the {@link Device}
+ * object TPM info if the certificate request's nonce is present.
+ *
+ * @param certificateRequest certificate request
+ * @param identityClaim identity claim
+ * @return a {@link Device} object
+ */
+ private Device retrieveDeviceWithUpdatedTPMInfo(final ProvisionerTpm2.CertificateRequest certificateRequest,
+ final ProvisionerTpm2.IdentityClaim identityClaim) {
+ final String deviceName = identityClaim.getDv().getNw().getHostname();
+ Device device = deviceRepository.findByName(deviceName);
+
+ // Parse through the Provisioner supplied TPM Quote and pcr values. These fields are optional.
+ if (!certificateRequest.getQuote().isEmpty()) {
+ DeviceInfoReport deviceInfoReport = Objects.requireNonNull(device.getDeviceInfo());
+
+ TPMInfo savedInfo = deviceInfoReport.getTpmInfo();
+ TPMInfo tpmInfo = new TPMInfo(savedInfo.getTpmMake(),
+ savedInfo.getTpmVersionMajor(),
+ savedInfo.getTpmVersionMinor(),
+ savedInfo.getTpmVersionRevMajor(),
+ savedInfo.getTpmVersionRevMinor(),
+ savedInfo.getPcrValues(),
+ ProvisionUtils.parseTPMQuoteHash(certificateRequest.getQuote().toStringUtf8())
+ .getBytes(StandardCharsets.UTF_8),
+ ProvisionUtils.parseTPMQuoteSignature(certificateRequest.getQuote().toStringUtf8())
+ .getBytes(StandardCharsets.UTF_8));
+
+ DeviceInfoReport dvReport = new DeviceInfoReport(
+ deviceInfoReport.getNetworkInfo(),
+ deviceInfoReport.getOSInfo(),
+ deviceInfoReport.getFirmwareInfo(),
+ deviceInfoReport.getHardwareInfo(), tpmInfo,
+ identityClaim.getClientVersion());
+
+ device.setDeviceInfo(dvReport);
+ return deviceRepository.save(device);
+ }
+
+ return device;
+ }
+
/**
* Helper method to unwrap the certificate request sent by the client and verify the
* provided nonce.
@@ -391,8 +412,7 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
* @param request Client Certificate Request containing nonce to complete identity claim
* @return the {@link TPM2ProvisionerState} if valid nonce provided / null, otherwise
*/
- private TPM2ProvisionerState getTpm2ProvisionerState(
- final ProvisionerTpm2.CertificateRequest request) {
+ private TPM2ProvisionerState getTpm2ProvisionerState(final ProvisionerTpm2.CertificateRequest request) {
if (request.hasNonce()) {
byte[] nonce = request.getNonce().toByteArray();
return TPM2ProvisionerState.getTPM2ProvisionerState(tpm2ProvisionerStateRepository,
@@ -411,8 +431,7 @@ private TPM2ProvisionerState getTpm2ProvisionerState(
private AppraisalStatus.Status doQuoteValidation(final Device device) {
log.info("Beginning Quote Validation...");
// perform supply chain validation
- SupplyChainValidationSummary scvs = supplyChainValidationService.validateQuote(
- device);
+ SupplyChainValidationSummary scvs = supplyChainValidationService.validateQuote(device);
AppraisalStatus.Status validationResult;
// either validation wasn't enabled or device already failed
@@ -433,9 +452,9 @@ private AppraisalStatus.Status doQuoteValidation(final Device device) {
/**
* Generates a credential using the specified public key.
*
- * @param publicKey cannot be null
+ * @param publicKey non-null public key
* @param endorsementCredential the endorsement credential
- * @param platformCredentials the set of platform credentials
+ * @param platformCredentials the list of platform credentials
* @param deviceName The host name used in the subject alternative name
* @param acaCertificate object used to create credential
* @return identity credential
@@ -450,62 +469,67 @@ private X509Certificate generateCredential(final PublicKey publicKey,
Calendar expiry = Calendar.getInstance();
expiry.add(Calendar.DAY_OF_YEAR, certificateValidityInDays);
- X500Name issuer =
- new X509CertificateHolder(acaCertificate.getEncoded()).getSubject();
+ X500Name issuer = new X509CertificateHolder(acaCertificate.getEncoded()).getSubject();
Date notBefore = new Date();
Date notAfter = expiry.getTime();
BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
- SubjectPublicKeyInfo subjectPublicKeyInfo =
- SubjectPublicKeyInfo.getInstance(publicKey.getEncoded());
+ SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(publicKey.getEncoded());
// The subject should be left blank, per spec
- X509v3CertificateBuilder builder =
- new X509v3CertificateBuilder(issuer, serialNumber,
- notBefore, notAfter, null /* subjectName */, subjectPublicKeyInfo);
+ X509v3CertificateBuilder x509v3CertificateBuilder = new X509v3CertificateBuilder(issuer, serialNumber,
+ notBefore, notAfter, null /* subjectName */, subjectPublicKeyInfo);
+
+ Extension subjectAlternativeName = IssuedCertificateAttributeHelper.buildSubjectAlternativeNameFromCerts(
+ endorsementCredential, platformCredentials, deviceName);
- Extension subjectAlternativeName =
- IssuedCertificateAttributeHelper.buildSubjectAlternativeNameFromCerts(
- endorsementCredential, platformCredentials, deviceName);
+ Extension authKeyIdentifier = IssuedCertificateAttributeHelper.buildAuthorityKeyIdentifier(acaCertificate);
- Extension authKeyIdentifier = IssuedCertificateAttributeHelper
- .buildAuthorityKeyIdentifier(acaCertificate);
+ x509v3CertificateBuilder.addExtension(subjectAlternativeName);
- builder.addExtension(subjectAlternativeName);
if (authKeyIdentifier != null) {
- builder.addExtension(authKeyIdentifier);
+ x509v3CertificateBuilder.addExtension(authKeyIdentifier);
}
+
// identify cert as an AIK with this extension
if (IssuedCertificateAttributeHelper.EXTENDED_KEY_USAGE_EXTENSION != null) {
- builder.addExtension(IssuedCertificateAttributeHelper.EXTENDED_KEY_USAGE_EXTENSION);
+ x509v3CertificateBuilder.addExtension(IssuedCertificateAttributeHelper.EXTENDED_KEY_USAGE_EXTENSION);
} else {
log.warn("Failed to build extended key usage extension and add to AIK");
- throw new IllegalStateException("Extended Key Usage attribute unavailable. "
- + "Unable to issue certificates");
+ throw new IllegalArgumentException(
+ "Extended Key Usage attribute unavailable. Unable to issue certificates");
}
// Add signing extension
- builder.addExtension(
- Extension.keyUsage,
- true,
- new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment)
- );
+ x509v3CertificateBuilder.addExtension(Extension.keyUsage, true,
+ new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment));
// Basic constraints
- builder.addExtension(
- Extension.basicConstraints,
- true,
- new BasicConstraints(false)
- );
-
- ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA")
- .setProvider("BC").build(privateKey);
- X509CertificateHolder holder = builder.build(signer);
- return new JcaX509CertificateConverter()
- .setProvider("BC").getCertificate(holder);
- } catch (IOException | OperatorCreationException | CertificateException exception) {
+ x509v3CertificateBuilder.addExtension(Extension.basicConstraints, true, new BasicConstraints(false));
+
+ ContentSigner signer =
+ new JcaContentSignerBuilder(getSignatureAlgorithm()).setProvider("BC").build(privateKey);
+
+ X509CertificateHolder holder = x509v3CertificateBuilder.build(signer);
+
+ return new JcaX509CertificateConverter().setProvider("BC").getCertificate(holder);
+ } catch (IOException | IllegalArgumentException | OperatorCreationException | CertificateException exception) {
throw new CertificateProcessingException("Encountered error while generating "
+ "identity credential: " + exception.getMessage(), exception);
}
}
+
+ /**
+ * Returns a string representation of the signature algorithm that will be used with the provided private key.
+ *
+ * @return signature algorithm associated with the private key
+ */
+ private String getSignatureAlgorithm() {
+ if (privateKey instanceof RSAPrivateKey) {
+ return "SHA256WithRSA";
+ } else if (privateKey instanceof ECPrivateKey) {
+ return "SHA256withECDSA";
+ }
+ throw new IllegalArgumentException("Unsupported private key type: " + privateKey.getClass().getName());
+ }
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateManagementService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java
similarity index 95%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateManagementService.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java
index 870ed17d0..dfa5a6cbb 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateManagementService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java
@@ -30,11 +30,13 @@
/**
- * Service layer class that encapsulates credential management functions used by the ACA.
+ * Service class responsible for parsing {@link PlatformCredential} and {@link EndorsementCredential} objects,
+ * along with related data such as device components from the Identity Claim. It also handles storing these objects
+ * and assists in generating credentials, including the {@link IssuedAttestationCertificate}.
*/
@Service
@Log4j2
-public class CertificateManagementService {
+public class CredentialManagementService {
private final PolicyRepository policyRepository;
private final CertificateRepository certificateRepository;
private final ComponentResultRepository componentResultRepository;
@@ -44,12 +46,12 @@ public class CertificateManagementService {
*
* @param policyRepository policy repository
* @param certificateRepository certificate repository
- * @param componentResultRepository
+ * @param componentResultRepository component result repository
*/
@Autowired
- private CertificateManagementService(final PolicyRepository policyRepository,
- final CertificateRepository certificateRepository,
- final ComponentResultRepository componentResultRepository) {
+ public CredentialManagementService(final PolicyRepository policyRepository,
+ final CertificateRepository certificateRepository,
+ final ComponentResultRepository componentResultRepository) {
this.policyRepository = policyRepository;
this.certificateRepository = certificateRepository;
this.componentResultRepository = componentResultRepository;
@@ -253,7 +255,7 @@ public PlatformCredential storePlatformCredential(final byte[] platformBytes, fi
* @param platformCredentials list of platform credentials
* @throws IOException if any issues arise from storing the platform credentials components
*/
- public void saveOrUpdatePlatformCertificateComponents(List platformCredentials)
+ public void saveOrUpdatePlatformCertificateComponents(final List platformCredentials)
throws IOException {
handleSpecialCaseForPlatformCertificates(platformCredentials);
@@ -319,7 +321,7 @@ public boolean saveAttestationCertificate(
if (issuedAc.getFirst().getEndValidity().after(currentDate)) {
// so the issued AC is not expired
// however are we within the threshold
- days = ProvisionUtils.daysBetween(currentDate, issuedAc.getFirst().getEndValidity());
+ days = ProvisionUtils.calculateDaysBetweenDates(currentDate, issuedAc.getFirst().getEndValidity());
generateCertificate =
days < (ldevID ? policySettings.getDevIdReissueThreshold()
: policySettings.getReissueThreshold());
@@ -405,7 +407,7 @@ private List getPlatformCredentials(final EndorsementCredent
*
* @param platformCredentials list of platform credentials
*/
- private void handleSpecialCaseForPlatformCertificates(List platformCredentials) {
+ private void handleSpecialCaseForPlatformCertificates(final List platformCredentials) {
if (platformCredentials.size() == 1) {
List additionalPC = new LinkedList<>();
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
index b390c7d0e..d5f3b3450 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
@@ -19,7 +19,6 @@
import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements;
import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue;
import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest;
-import hirs.attestationca.persist.exceptions.IdentityProcessingException;
import hirs.attestationca.persist.validation.SupplyChainCredentialValidator;
import hirs.utils.HexUtils;
import hirs.utils.SwidResource;
@@ -49,8 +48,8 @@
import java.util.regex.Pattern;
/**
- * Service class that parses and processes Device information from the Identity Claim and uses it to update the Device
- * and RIMs.
+ * Service class that parses and processes device information from the provisioned Identity Claim and uses it to
+ * update the {@link Device} and {@link ReferenceManifest} objects.
*/
@Service
@Log4j2
@@ -86,28 +85,16 @@ public DeviceInfoProcessorService(final DeviceRepository deviceRepository,
}
/**
- * Creates a {@link DeviceInfoReport} from the identity claim's Device Info and updates the corresponding
- * {@link Device}.
+ * Creates and updates a {@link Device} object after parsing the identity claim's Device Info.
*
* @param identityClaim Identity Claim
- * @return device
+ * @return the {@link Device} object representing the device
*/
public Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim identityClaim) {
- DeviceInfoReport deviceInfoReport = null;
log.info("Parsing Device Info from the Identity Claim");
- try {
- deviceInfoReport = parseDeviceInfo(identityClaim);
- } catch (NoSuchAlgorithmException noSaEx) {
- log.error(noSaEx);
- }
-
- if (deviceInfoReport == null) {
- final String errorMsg = "Failed to parse device info from Protobuf Identity Claim.";
- log.error(errorMsg);
- throw new IdentityProcessingException(errorMsg);
- }
+ final DeviceInfoReport deviceInfoReport = parseDeviceInfo(identityClaim);
log.info("Processing Device Info Report");
@@ -116,7 +103,7 @@ public Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim identityClai
if (deviceInfoReport.getNetworkInfo() != null &&
!StringUtils.isBlank(deviceInfoReport.getNetworkInfo().getHostname())) {
- device = this.deviceRepository.findByName(deviceInfoReport.getNetworkInfo().getHostname());
+ device = deviceRepository.findByName(deviceInfoReport.getNetworkInfo().getHostname());
}
if (device == null) {
@@ -124,38 +111,79 @@ public Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim identityClai
}
device.setDeviceInfo(deviceInfoReport);
- processDeviceComponents(deviceInfoReport.getNetworkInfo().getHostname(),
- deviceInfoReport.getPaccorOutputString());
+ return saveOrUpdateDevice(device);
+ }
+
+ /**
+ * Finds all components for the given device by combining data from the provided Paccor string
+ * and the current database records, then saves or updates them in the database.
+ *
+ * @param hostName device's host name
+ * @param paccorString string representation of the PACCOR tool output
+ * @return list of device components
+ */
+ public List processDeviceComponents(final String hostName, final String paccorString) {
+ Map componentInfoMap = new HashMap<>();
+
+ try {
+ List componentInfos =
+ SupplyChainCredentialValidator.getComponentInfoFromPaccorOutput(hostName, paccorString);
+
+ // check the DB for like component infos
+ List dbComponentInfos = componentInfoRepository.findByDeviceName(hostName);
+ dbComponentInfos.forEach((infos) -> componentInfoMap.put(infos.hashCode(), infos));
- return this.deviceRepository.save(device);
+ for (ComponentInfo componentInfo : dbComponentInfos) {
+ if (componentInfoMap.containsKey(componentInfo.hashCode())) {
+ componentInfos.remove(componentInfo);
+ }
+ }
+
+ for (ComponentInfo componentInfo : componentInfos) {
+ componentInfoRepository.save(componentInfo);
+ }
+ } catch (IOException ioEx) {
+ log.warn("Error parsing PACCOR string");
+ }
+
+ return componentInfoRepository.findByDeviceName(hostName);
+ }
+
+ /**
+ * Saves or updates the provided {@link Device} object in the database.
+ *
+ * @param device device
+ * @return the {@link Device} representing the device
+ */
+ public Device saveOrUpdateDevice(final Device device) {
+ return deviceRepository.save(device);
}
/**
- * Helper method that creates a Device Info Report using the provided Identity Claim's Device Info.
+ * Helper method that creates a {@link DeviceInfoReport} object using the provided Identity Claim's Device Info.
*
* @param identityClaim the protobuf serialized Identity Claim containing the device info
- * @return {@link DeviceInfoReport}
+ * @return the {@link DeviceInfoReport} object representing the Device Info Report
*/
- private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim identityClaim)
- throws NoSuchAlgorithmException {
- ProvisionerTpm2.DeviceInfo tpmDeviceInfo = identityClaim.getDv();
+ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim identityClaim) {
+ ProvisionerTpm2.DeviceInfo provisionedDeviceInfo = identityClaim.getDv();
// Get Hardware info
- HardwareInfo hardwareInfo = getHardwareInfo(tpmDeviceInfo.getHw());
+ HardwareInfo hardwareInfo = getHardwareInfo(provisionedDeviceInfo.getHw());
// Get TPM info ( todo Currently unimplemented)
- TPMInfo tpmInfo = getTPMInfo(tpmDeviceInfo);
+ TPMInfo tpmInfo = getTPMInfo(provisionedDeviceInfo);
// Get Network info
- NetworkInfo networkInfo = getNetworkInfo(tpmDeviceInfo.getNw());
+ NetworkInfo networkInfo = getNetworkInfo(provisionedDeviceInfo.getNw());
// Get Firmware info
- FirmwareInfo firmwareInfo = getFirmwareInfo(tpmDeviceInfo.getFw());
+ FirmwareInfo firmwareInfo = getFirmwareInfo(provisionedDeviceInfo.getFw());
// Get OS info
- OSInfo osInfo = getOSInfo(tpmDeviceInfo.getOs());
+ OSInfo osInfo = getOSInfo(provisionedDeviceInfo.getOs());
- getAndUpdateRIMSUsingTPMDeviceInfo(tpmDeviceInfo);
+ getAndUpdateRIMSUsingProvisionedDeviceInfo(provisionedDeviceInfo);
// Create final device info report
DeviceInfoReport dvReport = new DeviceInfoReport(networkInfo, osInfo, firmwareInfo, hardwareInfo, tpmInfo,
@@ -166,16 +194,17 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim ide
}
/**
- * Helper method that creates a {@link TPMInfo} using the provided TPM Device Info ( todo Currently unimplemented)
+ * Helper method that creates a {@link TPMInfo} object using the provided provisioned Device Info.
+ * ( todo Currently unimplemented)
*
- * @param tpmDeviceInfo TPM Device Info
- * @return {@link TPMInfo}
+ * @param provisionedDeviceInfo provisioned Device Info
+ * @return the {@link TPMInfo} object representing the Device's TPM Info
*/
- private TPMInfo getTPMInfo(ProvisionerTpm2.DeviceInfo tpmDeviceInfo) {
+ private TPMInfo getTPMInfo(final ProvisionerTpm2.DeviceInfo provisionedDeviceInfo) {
String pcrValues = "";
- if (tpmDeviceInfo.hasPcrslist()) {
- pcrValues = tpmDeviceInfo.getPcrslist().toStringUtf8();
+ if (provisionedDeviceInfo.hasPcrslist()) {
+ pcrValues = provisionedDeviceInfo.getPcrslist().toStringUtf8();
}
return new TPMInfo(DeviceInfoEnums.NOT_SPECIFIED,
@@ -188,44 +217,46 @@ private TPMInfo getTPMInfo(ProvisionerTpm2.DeviceInfo tpmDeviceInfo) {
}
/**
- * Helper method that creates a {@link HardwareInfo} using the provided TPM Device Info's Hardware Info.
+ * Helper method that creates a {@link HardwareInfo} object using the provided provisioned Device Info's
+ * Hardware Info.
*
- * @param tpmHardwareInfo TPM Device Info's Hardware Info
- * @return {@link HardwareInfo}
+ * @param provisionedHardwareInfo provisioned Device Info's Hardware Info
+ * @return the {@link HardwareInfo} object representing the Device's Hardware Info
*/
- private HardwareInfo getHardwareInfo(final ProvisionerTpm2.HardwareInfo tpmHardwareInfo) {
+ private HardwareInfo getHardwareInfo(final ProvisionerTpm2.HardwareInfo provisionedHardwareInfo) {
// Make sure chassis info has at least one chassis
String firstChassisSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
- if (tpmHardwareInfo.getChassisInfoCount() > 0) {
- firstChassisSerialNumber = tpmHardwareInfo.getChassisInfo(0).getSerialNumber();
+ if (provisionedHardwareInfo.getChassisInfoCount() > 0) {
+ firstChassisSerialNumber = provisionedHardwareInfo.getChassisInfo(0).getSerialNumber();
}
// Make sure baseboard info has at least one baseboard
String firstBaseboardSerialNumber = DeviceInfoEnums.NOT_SPECIFIED;
- if (tpmHardwareInfo.getBaseboardInfoCount() > 0) {
- firstBaseboardSerialNumber = tpmHardwareInfo.getBaseboardInfo(0).getSerialNumber();
+ if (provisionedHardwareInfo.getBaseboardInfoCount() > 0) {
+ firstBaseboardSerialNumber = provisionedHardwareInfo.getBaseboardInfo(0).getSerialNumber();
}
- return new HardwareInfo(tpmHardwareInfo.getManufacturer(), tpmHardwareInfo.getProductName(),
- tpmHardwareInfo.getProductVersion(), tpmHardwareInfo.getSystemSerialNumber(),
+ return new HardwareInfo(provisionedHardwareInfo.getManufacturer(), provisionedHardwareInfo.getProductName(),
+ provisionedHardwareInfo.getProductVersion(), provisionedHardwareInfo.getSystemSerialNumber(),
firstChassisSerialNumber, firstBaseboardSerialNumber);
}
/**
- * Helper method that creates a {@link NetworkInfo} using the provided TPM Device Info's Network Info.
+ * Helper method that creates a {@link NetworkInfo} object using the provided provisioned Device Info's Network
+ * Info.
*
- * @param tpmNetworkInfo TPM Device Info's Network Info
- * @return {@link NetworkInfo}
+ * @param provisionedNetworkInfo provisioned Device Info's Network Info
+ * @return the {@link NetworkInfo} object representing the Device's Network Info
*/
- private NetworkInfo getNetworkInfo(final ProvisionerTpm2.NetworkInfo tpmNetworkInfo) {
+ private NetworkInfo getNetworkInfo(final ProvisionerTpm2.NetworkInfo provisionedNetworkInfo) {
InetAddress ip = null;
try {
- ip = InetAddress.getByName(tpmNetworkInfo.getIpAddress());
+ ip = InetAddress.getByName(provisionedNetworkInfo.getIpAddress());
} catch (UnknownHostException uhEx) {
- log.error("Unable to parse IP address from the TPM Device Info: ", uhEx);
+ log.error("Unable to parse IP address from the provisioned Device Info: ", uhEx);
}
- String[] macAddressParts = tpmNetworkInfo.getMacAddress().split(":");
+ String[] macAddressParts = provisionedNetworkInfo.getMacAddress().split(":");
// convert mac hex string to byte values
byte[] macAddressBytes = new byte[MAC_BYTES];
@@ -237,93 +268,97 @@ private NetworkInfo getNetworkInfo(final ProvisionerTpm2.NetworkInfo tpmNetworkI
}
}
- return new NetworkInfo(tpmNetworkInfo.getHostname(), ip, macAddressBytes);
+ return new NetworkInfo(provisionedNetworkInfo.getHostname(), ip, macAddressBytes);
}
/**
- * Helper method that creates an {@link OSInfo} using the provided TPM Device Info's OS info.
+ * Helper method that creates an {@link OSInfo} using the provided provisioned Device Info's OS info.
*
- * @param tpmOsInfo TPM Device Info's OS Info
- * @return {@link OSInfo}
+ * @param provisionedOsInfo provisioned Device Info's OS Info
+ * @return the {@link OSInfo} object representing the Device's OS Info
*/
- private OSInfo getOSInfo(final ProvisionerTpm2.OsInfo tpmOsInfo) {
- return new OSInfo(tpmOsInfo.getOsName(), tpmOsInfo.getOsVersion(), tpmOsInfo.getOsArch(),
- tpmOsInfo.getDistribution(), tpmOsInfo.getDistributionRelease());
+ private OSInfo getOSInfo(final ProvisionerTpm2.OsInfo provisionedOsInfo) {
+ return new OSInfo(provisionedOsInfo.getOsName(), provisionedOsInfo.getOsVersion(),
+ provisionedOsInfo.getOsArch(),
+ provisionedOsInfo.getDistribution(), provisionedOsInfo.getDistributionRelease());
}
/**
- * Helper method that creates a {@link FirmwareInfo} using the provided TPM Device Info's Firmware Info.
+ * Helper method that creates a {@link FirmwareInfo} using the provided provisioned Device Info's Firmware Info.
*
- * @param tpmFirmwareInfo TPM Device Info's Firmware Info
- * @return {@link FirmwareInfo}
+ * @param provisionedFirmwareInfo provisioned Device Info's Firmware Info
+ * @return the {@link FirmwareInfo} object representing the Device's Firmware Info
*/
- private FirmwareInfo getFirmwareInfo(final ProvisionerTpm2.FirmwareInfo tpmFirmwareInfo) {
- return new FirmwareInfo(tpmFirmwareInfo.getBiosVendor(), tpmFirmwareInfo.getBiosVersion(),
- tpmFirmwareInfo.getBiosReleaseDate());
+ private FirmwareInfo getFirmwareInfo(final ProvisionerTpm2.FirmwareInfo provisionedFirmwareInfo) {
+ return new FirmwareInfo(provisionedFirmwareInfo.getBiosVendor(), provisionedFirmwareInfo.getBiosVersion(),
+ provisionedFirmwareInfo.getBiosReleaseDate());
}
/**
- * Helper method that updates all Reference Integrity Manifests (RIMs) using the provided TPM's Device Info.
+ * Helper method that updates all Reference Integrity Manifests (RIMs) using the provided provisioned Device Info.
*
- * @param tpmDeviceInfo TPM Device Info
+ * @param provisionedDeviceInfo provisioned Device Info
*/
- private void getAndUpdateRIMSUsingTPMDeviceInfo(ProvisionerTpm2.DeviceInfo tpmDeviceInfo) {
+ private void getAndUpdateRIMSUsingProvisionedDeviceInfo(final ProvisionerTpm2.DeviceInfo provisionedDeviceInfo) {
// check for RIM Base and Support files, if they don't exist in the database, load them
- final String defaultClientName = String.format("%s_%s", tpmDeviceInfo.getHw().getManufacturer(),
- tpmDeviceInfo.getHw().getProductName());
+ final String defaultClientName = String.format("%s_%s", provisionedDeviceInfo.getHw().getManufacturer(),
+ provisionedDeviceInfo.getHw().getProductName());
- final String deviceInfoHostName = tpmDeviceInfo.getNw().getHostname();
+ final String deviceInfoHostName = provisionedDeviceInfo.getNw().getHostname();
// update base RIMs using the identity claim's device information
- if (tpmDeviceInfo.getSwidfileCount() > 0) {
- updateBaseRIMSUsingTPMDeviceInfo(defaultClientName, tpmDeviceInfo);
+ if (provisionedDeviceInfo.getSwidfileCount() > 0) {
+ updateBaseRIMSUsingDeviceInfo(defaultClientName, provisionedDeviceInfo);
} else {
log.warn("Device {} did not send SWID tag files...", deviceInfoHostName);
}
// update support RIMs using the identity claim's device information
- if (tpmDeviceInfo.getLogfileCount() > 0) {
- updateSupportRIMSUsingTPMDeviceInfo(defaultClientName, tpmDeviceInfo);
+ if (provisionedDeviceInfo.getLogfileCount() > 0) {
+ updateSupportRIMSUsingDeviceInfo(defaultClientName, provisionedDeviceInfo);
} else {
log.warn("Device {} did not send Support RIM files...", deviceInfoHostName);
}
// update both base and support RIMs to ensure updates are consistent
- updateBaseSupportRIMSUsingTpmDeviceInfo(tpmDeviceInfo);
+ updateBaseSupportRIMSUsingDeviceInfo(provisionedDeviceInfo);
- generateDigestRecords(tpmDeviceInfo.getHw().getManufacturer(), tpmDeviceInfo.getHw().getProductName());
+ generateDigestRecords(provisionedDeviceInfo.getHw().getManufacturer(),
+ provisionedDeviceInfo.getHw().getProductName());
// update event log information
- if (tpmDeviceInfo.hasLivelog()) {
- updateEventLogInfoUsingTPMDeviceInfo(tpmDeviceInfo);
+ if (provisionedDeviceInfo.hasLivelog()) {
+ updateEventLogInfoUsingDeviceInfo(provisionedDeviceInfo);
} else {
log.warn("Device {} did not send BIOS measurement log...", deviceInfoHostName);
}
}
/**
- * Helper method that updates the Base RIMs in the database using the information provided by the TPM's Device Info.
+ * Helper method that updates the Base RIMs in the database using the information provided by the provisioned
+ * Device Info.
*
- * @param defaultClientName default client name
- * @param tpmDeviceInfo TPM Device Info
+ * @param defaultClientName default client name
+ * @param provisionedDeviceInfo provisioned Device Info
*/
- private void updateBaseRIMSUsingTPMDeviceInfo(final String defaultClientName,
- final ProvisionerTpm2.DeviceInfo tpmDeviceInfo) {
+ private void updateBaseRIMSUsingDeviceInfo(final String defaultClientName,
+ final ProvisionerTpm2.DeviceInfo provisionedDeviceInfo) {
final List baseRims = referenceManifestRepository.findAllBaseRims();
final List unarchivedRims = referenceManifestRepository.findByArchiveFlag(false);
- final String deviceHostName = tpmDeviceInfo.getNw().getHostname();
+ final String deviceHostName = provisionedDeviceInfo.getNw().getHostname();
log.info("Device {} sent SWID tag files", deviceHostName);
- for (ByteString swidFile : tpmDeviceInfo.getSwidfileList()) {
+ final List swidfileList = provisionedDeviceInfo.getSwidfileList();
+
+ for (ByteString swidFile : swidfileList) {
try {
final String swidFileHash =
Base64.getEncoder().encodeToString(messageDigest.digest(swidFile.toByteArray()));
final BaseReferenceManifest baseRim =
(BaseReferenceManifest) referenceManifestRepository.findByBase64Hash(swidFileHash);
- /*
- Either the swidFile does not have a corresponding base RIM in the backend,
+ /* Either the swidFile does not have a corresponding base RIM in the backend,
or it was deleted. Check if there is a replacement by comparing tagId against
all other base RIMs, and then set the corresponding support rim's deviceName. */
if (baseRim == null) {
@@ -342,12 +377,12 @@ private void updateBaseRIMSUsingTPMDeviceInfo(final String defaultClientName,
final BaseReferenceManifest matchedReplacementBaseRIM =
matchedReplacementBaseRIMOptional.get();
matchedReplacementBaseRIM.setDeviceName(replacementBaseRIM.getDeviceName());
- this.referenceManifestRepository.save(matchedReplacementBaseRIM);
+ referenceManifestRepository.save(matchedReplacementBaseRIM);
continue;
}
// otherwise save the replacement base RIM we created
- this.referenceManifestRepository.save(replacementBaseRIM);
+ referenceManifestRepository.save(replacementBaseRIM);
} else if (baseRim.isArchived()) {
/* This block accounts for RIMs that may have been soft-deleted (archived)
in an older version of the ACA. */
@@ -365,10 +400,10 @@ private void updateBaseRIMSUsingTPMDeviceInfo(final String defaultClientName,
final BaseReferenceManifest matchedUnarchivedBaseRIM = matchedUnarchivedBaseRIMOptional.get();
matchedUnarchivedBaseRIM.setDeviceName(deviceHostName);
- this.referenceManifestRepository.save(matchedUnarchivedBaseRIM);
+ referenceManifestRepository.save(matchedUnarchivedBaseRIM);
} else {
baseRim.setDeviceName(deviceHostName);
- this.referenceManifestRepository.save(baseRim);
+ referenceManifestRepository.save(baseRim);
}
} catch (Exception exception) {
log.error("Failed to process Base RIM file for device {}: {}", deviceHostName,
@@ -378,22 +413,23 @@ private void updateBaseRIMSUsingTPMDeviceInfo(final String defaultClientName,
}
/**
- * Helper method that updates the Support RIMs in the database using the information provided by the TPM's Device
- * Info.
+ * Helper method that updates the Support RIMs in the database using the information provided by the provisioned
+ * Device Info.
*
- * @param defaultClientName default client name
- * @param tpmDeviceInfo TPM Device Info
+ * @param defaultClientName default client name
+ * @param provisionedDeviceInfo provisioned Device Info
*/
- private void updateSupportRIMSUsingTPMDeviceInfo(final String defaultClientName,
- final ProvisionerTpm2.DeviceInfo tpmDeviceInfo) {
- final String deviceHostName = tpmDeviceInfo.getNw().getHostname();
+ private void updateSupportRIMSUsingDeviceInfo(final String defaultClientName,
+ final ProvisionerTpm2.DeviceInfo provisionedDeviceInfo) {
+ final String deviceHostName = provisionedDeviceInfo.getNw().getHostname();
final int NUM_OF_VARIABLES = 5;
log.info("Device {} sent Support RIM files", deviceHostName);
final List unarchivedRims = referenceManifestRepository.findByArchiveFlag(false);
+ final List logfileList = provisionedDeviceInfo.getLogfileList();
- for (ByteString logFile : tpmDeviceInfo.getLogfileList()) {
+ for (ByteString logFile : logfileList) {
try {
final String logFileHash = Hex.encodeHexString(messageDigest.digest(logFile.toByteArray()));
@@ -413,13 +449,13 @@ private void updateSupportRIMSUsingTPMDeviceInfo(final String defaultClientName,
new TCGEventLog(replacementSupportRIM.getRimBytes());
// no issues, continue
- replacementSupportRIM.setPlatformManufacturer(tpmDeviceInfo.getHw().getManufacturer());
- replacementSupportRIM.setPlatformModel(tpmDeviceInfo.getHw().getProductName());
+ replacementSupportRIM.setPlatformManufacturer(provisionedDeviceInfo.getHw().getManufacturer());
+ replacementSupportRIM.setPlatformModel(provisionedDeviceInfo.getHw().getProductName());
replacementSupportRIM.setFileName(String.format("%s_[%s].rimel", defaultClientName,
replacementSupportRIM.getHexDecHash().substring(
replacementSupportRIM.getHexDecHash().length() - NUM_OF_VARIABLES)));
replacementSupportRIM.setDeviceName(deviceHostName);
- this.referenceManifestRepository.save(replacementSupportRIM);
+ referenceManifestRepository.save(replacementSupportRIM);
} else if (supportRim.isArchived()) {
/*
This block accounts for RIMs that may have been soft-deleted (archived)
@@ -440,10 +476,10 @@ private void updateSupportRIMSUsingTPMDeviceInfo(final String defaultClientName,
final SupportReferenceManifest matchedUnarchivedSupportRIM =
matchedUnarchivedSupportRIMOptional.get();
matchedUnarchivedSupportRIM.setDeviceName(deviceHostName);
- this.referenceManifestRepository.save(matchedUnarchivedSupportRIM);
+ referenceManifestRepository.save(matchedUnarchivedSupportRIM);
} else {
supportRim.setDeviceName(deviceHostName);
- this.referenceManifestRepository.save(supportRim);
+ referenceManifestRepository.save(supportRim);
}
} catch (Exception exception) {
log.error("Failed to process Support RIM file for device {}: {}", deviceHostName,
@@ -457,14 +493,16 @@ private void updateSupportRIMSUsingTPMDeviceInfo(final String defaultClientName,
* Helper method that updates both base and support RIMs after modifying each type of RIM, ensuring that the
* updates are consistent and aligned.
*
- * @param tpmDeviceInfo TPM Device Info
+ * @param provisionedDeviceInfo provisioned Device Info
*/
- private void updateBaseSupportRIMSUsingTpmDeviceInfo(ProvisionerTpm2.DeviceInfo tpmDeviceInfo) {
- final String SUPPORT_RIM_FILE_PATTERN = "(\\S+(\\.(?i)(rimpcr|rimel|bin|log))$)";
- final Pattern supportRimPattern = Pattern.compile(SUPPORT_RIM_FILE_PATTERN);
+ private void updateBaseSupportRIMSUsingDeviceInfo(final ProvisionerTpm2.DeviceInfo provisionedDeviceInfo) {
+ final String supportRimFilePattern = "(\\S+(\\.(?i)(rimpcr|rimel|bin|log))$)";
+ final Pattern supportRimPattern = Pattern.compile(supportRimFilePattern);
+
+ final List swidfileList = provisionedDeviceInfo.getSwidfileList();
//update Support RIMs and Base RIMs.
- for (ByteString swidFile : tpmDeviceInfo.getSwidfileList()) {
+ for (ByteString swidFile : swidfileList) {
final String swidFileHash =
Base64.getEncoder().encodeToString(messageDigest.digest(swidFile.toByteArray()));
@@ -472,7 +510,9 @@ private void updateBaseSupportRIMSUsingTpmDeviceInfo(ProvisionerTpm2.DeviceInfo
(BaseReferenceManifest) referenceManifestRepository.findByBase64Hash(swidFileHash);
if (baseRim != null) {
- for (SwidResource swid : baseRim.getFileResources()) {
+ final List swidResourceList = baseRim.getFileResources();
+
+ for (SwidResource swid : swidResourceList) {
if (supportRimPattern.matcher(swid.getName()).matches()) {
final int dotIndex = swid.getName().lastIndexOf(".");
final String fileName = swid.getName().substring(0, dotIndex);
@@ -498,10 +538,10 @@ private void updateBaseSupportRIMSUsingTpmDeviceInfo(ProvisionerTpm2.DeviceInfo
dbSupportRIM.setUpdated(true);
dbSupportRIM.setAssociatedRim(baseRim.getId());
baseRim.setAssociatedRim(dbSupportRIM.getId());
- this.referenceManifestRepository.save(dbSupportRIM);
+ referenceManifestRepository.save(dbSupportRIM);
}
- this.referenceManifestRepository.save(baseRim);
+ referenceManifestRepository.save(baseRim);
}
}
}
@@ -519,7 +559,7 @@ private void generateDigestRecords(final String manufacturer, final String model
List supplementalRims = new ArrayList<>();
List patchRims = new ArrayList<>();
- List dbSupportRims = this.referenceManifestRepository
+ List dbSupportRims = referenceManifestRepository
.getSupportByManufacturerModel(manufacturer, model);
List expectedValues = referenceDigestValueRepository
.findByManufacturerAndModel(manufacturer, model);
@@ -610,18 +650,20 @@ private void generateDigestRecords(final String manufacturer, final String model
}
/**
- * @param tpmDeviceInfo TPM Device Info
+ * Helper method that updates the event log information using the provisioned Device Info.
+ *
+ * @param provisionedDeviceInfo provisioned Device Info
*/
- private void updateEventLogInfoUsingTPMDeviceInfo(ProvisionerTpm2.DeviceInfo tpmDeviceInfo) {
- final String deviceHostName = tpmDeviceInfo.getNw().getHostname();
+ private void updateEventLogInfoUsingDeviceInfo(final ProvisionerTpm2.DeviceInfo provisionedDeviceInfo) {
+ final String deviceHostName = provisionedDeviceInfo.getNw().getHostname();
final String fileName = String.format("%s.measurement", deviceHostName);
log.info("Device {} sent bios measurement log...", deviceHostName);
try {
- // grab the event log from TPM's device info
- EventLogMeasurements tpmEventLog = new EventLogMeasurements(fileName,
- tpmDeviceInfo.getLivelog().toByteArray());
+ // grab the event log from provisioned device info
+ EventLogMeasurements provisionedEventLog = new EventLogMeasurements(fileName,
+ provisionedDeviceInfo.getLivelog().toByteArray());
// find the previous event log that's stored in the database.
EventLogMeasurements integrityMeasurements =
@@ -631,17 +673,17 @@ private void updateEventLogInfoUsingTPMDeviceInfo(ProvisionerTpm2.DeviceInfo tpm
if (integrityMeasurements != null) {
// archive it and update the entity in the database
integrityMeasurements.archive();
- this.referenceManifestRepository.save(integrityMeasurements);
+ referenceManifestRepository.save(integrityMeasurements);
}
List baseRims = referenceManifestRepository.getBaseByManufacturerModel(
- tpmDeviceInfo.getHw().getManufacturer(),
- tpmDeviceInfo.getHw().getProductName());
+ provisionedDeviceInfo.getHw().getManufacturer(),
+ provisionedDeviceInfo.getHw().getProductName());
- tpmEventLog.setDeviceName(deviceHostName);
- tpmEventLog.setPlatformManufacturer(tpmDeviceInfo.getHw().getManufacturer());
- tpmEventLog.setPlatformModel(tpmDeviceInfo.getHw().getProductName());
- this.referenceManifestRepository.save(tpmEventLog);
+ provisionedEventLog.setDeviceName(deviceHostName);
+ provisionedEventLog.setPlatformManufacturer(provisionedDeviceInfo.getHw().getManufacturer());
+ provisionedEventLog.setPlatformModel(provisionedDeviceInfo.getHw().getProductName());
+ referenceManifestRepository.save(provisionedEventLog);
for (BaseReferenceManifest bRim : baseRims) {
if (bRim != null) {
@@ -650,8 +692,8 @@ private void updateEventLogInfoUsingTPMDeviceInfo(ProvisionerTpm2.DeviceInfo tpm
SupportReferenceManifest sBaseRim = referenceManifestRepository
.getSupportRimEntityById(bRim.getAssociatedRim());
if (sBaseRim != null) {
- bRim.setEventLogHash(tpmEventLog.getHexDecHash());
- sBaseRim.setEventLogHash(tpmEventLog.getHexDecHash());
+ bRim.setEventLogHash(provisionedEventLog.getHexDecHash());
+ sBaseRim.setEventLogHash(provisionedEventLog.getHexDecHash());
referenceManifestRepository.save(bRim);
referenceManifestRepository.save(sBaseRim);
} else {
@@ -663,35 +705,4 @@ private void updateEventLogInfoUsingTPMDeviceInfo(ProvisionerTpm2.DeviceInfo tpm
log.error(exception);
}
}
-
- /**
- * Helper method that attempts to find all the provided device's components and stores them in the database.
- *
- * @param hostName device's host name
- * @param paccorString string representation of the PACCOR tool output
- */
- private void processDeviceComponents(final String hostName, final String paccorString) {
- Map componentInfoMap = new HashMap<>();
-
- try {
- List componentInfos =
- SupplyChainCredentialValidator.getComponentInfoFromPaccorOutput(hostName, paccorString);
-
- // check the DB for like component infos
- List dbComponentInfos = this.componentInfoRepository.findByDeviceName(hostName);
- dbComponentInfos.forEach((infos) -> componentInfoMap.put(infos.hashCode(), infos));
-
- for (ComponentInfo componentInfo : dbComponentInfos) {
- if (componentInfoMap.containsKey(componentInfo.hashCode())) {
- componentInfos.remove(componentInfo);
- }
- }
-
- for (ComponentInfo componentInfo : componentInfos) {
- this.componentInfoRepository.save(componentInfo);
- }
- } catch (IOException ioEx) {
- log.warn("Error parsing paccor string");
- }
- }
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
index efca79e55..b2c8cb2e9 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
@@ -4,8 +4,6 @@
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
-import hirs.attestationca.persist.entity.manager.ComponentInfoRepository;
-import hirs.attestationca.persist.entity.manager.DeviceRepository;
import hirs.attestationca.persist.entity.manager.PolicyRepository;
import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository;
import hirs.attestationca.persist.entity.tpm.TPM2ProvisionerState;
@@ -14,6 +12,8 @@
import hirs.attestationca.persist.entity.userdefined.SupplyChainValidationSummary;
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
+import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
+import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
import hirs.attestationca.persist.enums.AppraisalStatus;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
import hirs.utils.HexUtils;
@@ -25,7 +25,11 @@
import java.io.IOException;
import java.security.PublicKey;
import java.util.List;
+import java.util.Objects;
+/**
+ * Service class responsible for processing the Provisioner's Identity Claim.
+ */
@Service
@Log4j2
public class IdentityClaimProcessorService {
@@ -36,10 +40,8 @@ public class IdentityClaimProcessorService {
private static final String PCR_QUOTE_MASK = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23";
private final SupplyChainValidationService supplyChainValidationService;
- private final CertificateManagementService certificateManagementService;
+ private final CredentialManagementService credentialManagementService;
private final DeviceInfoProcessorService deviceInfoProcessorService;
- private final ComponentInfoRepository componentInfoRepository;
- private final DeviceRepository deviceRepository;
private final PolicyRepository policyRepository;
private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
@@ -47,41 +49,38 @@ public class IdentityClaimProcessorService {
* Constructor.
*
* @param supplyChainValidationService supply chain validation service
- * @param componentInfoRepository component info repository
- * @param deviceRepository device repository
+ * @param credentialManagementService certificate processor service
+ * @param deviceInfoProcessorService device info processor service
* @param tpm2ProvisionerStateRepository tpm2 provisioner state repository
* @param policyRepository policy repository
*/
@Autowired
public IdentityClaimProcessorService(
final SupplyChainValidationService supplyChainValidationService,
- final CertificateManagementService certificateManagementService,
- final ComponentInfoRepository componentInfoRepository,
- final DeviceRepository deviceRepository, DeviceInfoProcessorService deviceInfoProcessorService,
+ final CredentialManagementService credentialManagementService,
+ final DeviceInfoProcessorService deviceInfoProcessorService,
final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
final PolicyRepository policyRepository) {
this.supplyChainValidationService = supplyChainValidationService;
- this.certificateManagementService = certificateManagementService;
- this.componentInfoRepository = componentInfoRepository;
- this.deviceRepository = deviceRepository;
+ this.credentialManagementService = credentialManagementService;
this.deviceInfoProcessorService = deviceInfoProcessorService;
this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
this.policyRepository = policyRepository;
}
/**
- * Basic implementation of the ACA processIdentityClaimTpm2 method. Parses the claim,
+ * Basic implementation of the ACA processIdentityClaimTpm2 method. Parses the identity claim,
* stores the device info, performs supply chain validation, generates a nonce,
* and wraps that nonce with the make credential process before returning it to the client.
* attCert.setPcrValues(pcrValues);
*
- * @param identityClaim the request to process, cannot be null
+ * @param identityClaimByteArray the request to process, cannot be null
* @return an identity claim response for the specified request containing a wrapped blob
*/
- public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
+ public byte[] processIdentityClaimTpm2(final byte[] identityClaimByteArray) {
log.info("Identity Claim has been received and is ready to be processed");
- if (ArrayUtils.isEmpty(identityClaim)) {
+ if (ArrayUtils.isEmpty(identityClaimByteArray)) {
final String errorMsg = "The IdentityClaim sent by the client cannot be null or empty.";
log.error(errorMsg);
throw new IllegalArgumentException(errorMsg);
@@ -89,25 +88,24 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
final PolicySettings policySettings = policyRepository.findByName("Default");
- // attempt to deserialize Protobuf IdentityClaim
- ProvisionerTpm2.IdentityClaim claim = ProvisionUtils.parseIdentityClaim(identityClaim);
+ // attempt to deserialize Protobuf Identity Claim
+ ProvisionerTpm2.IdentityClaim identityClaim = ProvisionUtils.parseIdentityClaim(identityClaimByteArray);
String identityClaimJsonString = "";
try {
- identityClaimJsonString = JsonFormat.printer().print(claim);
+ identityClaimJsonString = JsonFormat.printer().print(identityClaim);
} catch (InvalidProtocolBufferException exception) {
log.error("Identity claim could not be parsed properly into a json string");
}
- // parse the EK Public key from the IdentityClaim once for use in supply chain validation
- // and later tpm20MakeCredential function
+ // parse the EK Public key from the IdentityClaim
PublicKey endorsementCredentialPublicKey =
- ProvisionUtils.parsePublicKeyFromPublicDataSegment(claim.getEkPublicArea().toByteArray());
+ ProvisionUtils.parsePublicKeyFromPublicDataSegment(identityClaim.getEkPublicArea().toByteArray());
AppraisalStatus.Status validationResult = AppraisalStatus.Status.FAIL;
try {
- validationResult = doSupplyChainValidation(claim, endorsementCredentialPublicKey);
+ validationResult = doSupplyChainValidation(identityClaim, endorsementCredentialPublicKey);
} catch (Exception ex) {
log.error(ex.getMessage());
}
@@ -115,7 +113,8 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
ByteString blobStr = ByteString.copyFrom(new byte[]{});
if (validationResult == AppraisalStatus.Status.PASS) {
- PublicKey akPub = ProvisionUtils.parsePublicKeyFromPublicDataSegment(claim.getAkPublicArea().toByteArray());
+ PublicKey akPub =
+ ProvisionUtils.parsePublicKeyFromPublicDataSegment(identityClaim.getAkPublicArea().toByteArray());
byte[] nonce = ProvisionUtils.generateRandomBytes(NONCE_LENGTH);
blobStr = ProvisionUtils.tpm20MakeCredential(endorsementCredentialPublicKey, akPub,
nonce);
@@ -124,9 +123,9 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
String strNonce = HexUtils.byteArrayToHexString(nonce);
log.info("Sending nonce: {}", strNonce);
- log.info("Persisting identity claim of length: {}", identityClaim.length);
+ log.info("Persisting identity claim of length: {}", identityClaimByteArray.length);
- tpm2ProvisionerStateRepository.save(new TPM2ProvisionerState(nonce, identityClaim));
+ tpm2ProvisionerStateRepository.save(new TPM2ProvisionerState(nonce, identityClaimByteArray));
if (policySettings.isIgnoreImaEnabled()) {
pcrQuoteMask = PCR_QUOTE_MASK.replace("10,", "");
@@ -156,7 +155,7 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
log.info("Identity Claim object received after a "
+ "successful validation: {}", identityClaimJsonString.isEmpty()
- ? claim : identityClaimJsonString);
+ ? identityClaim : identityClaimJsonString);
log.info("Identity Claim Response object after a "
+ "successful validation: {}", identityClaimResponseJsonStringAfterSuccess.isEmpty()
@@ -193,7 +192,7 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
log.info("Identity Claim object received after a "
+ "failed validation: {}", identityClaimJsonString.isEmpty()
- ? claim : identityClaimJsonString);
+ ? identityClaim : identityClaimJsonString);
log.info("Identity Claim Response object after a "
+ "failed validation: {}", identityClaimResponseJsonStringAfterFailure.isEmpty()
@@ -210,37 +209,42 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
/**
* Performs supply chain validation.
*
- * @param claim the identity claim
- * @param ekPub the public endorsement key
+ * @param identityClaim the identity claim
+ * @param ekPublicKey the public endorsement key
* @return the {@link AppraisalStatus} of the supply chain validation
*/
- private AppraisalStatus.Status doSupplyChainValidation(final ProvisionerTpm2.IdentityClaim claim,
- final PublicKey ekPub) throws IOException {
+ private AppraisalStatus.Status doSupplyChainValidation(final ProvisionerTpm2.IdentityClaim identityClaim,
+ final PublicKey ekPublicKey) throws IOException {
- // attempt to find an endorsement credential to validate
+ // Find an endorsement credential to validate
EndorsementCredential endorsementCredential =
- certificateManagementService.parseEcFromIdentityClaim(claim, ekPub);
+ credentialManagementService.parseEcFromIdentityClaim(identityClaim, ekPublicKey);
- // attempt to find platform credentials to validate
- List platformCredentials = certificateManagementService.parsePcsFromIdentityClaim(claim,
- endorsementCredential);
+ // Find platform credentials to validate
+ List platformCredentials =
+ credentialManagementService.parsePcsFromIdentityClaim(identityClaim, endorsementCredential);
- // Parse and save device info
- Device device = deviceInfoProcessorService.processDeviceInfo(claim);
+ // Parse and store the device info
+ Device device = deviceInfoProcessorService.processDeviceInfo(identityClaim);
+
+ // Parse and store the device components
+ DeviceInfoReport deviceInfo = Objects.requireNonNull(device.getDeviceInfo());
+ List componentInfoList = deviceInfoProcessorService.processDeviceComponents(
+ deviceInfo.getNetworkInfo().getHostname(),
+ deviceInfo.getPaccorOutputString());
// Store the platform certificates' components
- certificateManagementService.saveOrUpdatePlatformCertificateComponents(platformCredentials);
+ credentialManagementService.saveOrUpdatePlatformCertificateComponents(platformCredentials);
- // perform supply chain validation
+ // Perform supply chain validation
SupplyChainValidationSummary summary = supplyChainValidationService.validateSupplyChain(
- endorsementCredential, platformCredentials, device,
- componentInfoRepository.findByDeviceName(device.getName()));
+ endorsementCredential, platformCredentials, device, componentInfoList);
device.setSummaryId(summary.getId().toString());
- // update the validation result in the device
+ // Update the validation result in the device and update the updated device in the database
AppraisalStatus.Status validationResult = summary.getOverallValidationResult();
device.setSupplyChainValidationStatus(validationResult);
- this.deviceRepository.save(device);
+ deviceInfoProcessorService.saveOrUpdateDevice(device);
return validationResult;
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/package-info.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/package-info.java
new file mode 100644
index 000000000..98904bcb1
--- /dev/null
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/package-info.java
@@ -0,0 +1 @@
+package hirs.attestationca.persist.provision.service;
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
index bd3dfc7e6..fa200b590 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityServiceTest.java
@@ -37,11 +37,11 @@
* Tests the {@link AttestationCertificateAuthorityServiceImpl} service class.
*/
public class AttestationCertificateAuthorityServiceTest {
- private static final String EK_PUBLIC_KEY_PATH = "/public_keys/ek.pub";
+ private static final String EK_PUBLIC_KEY_PATH = "/tpm2/ek.pub";
- private static final String AK_PUBLIC_KEY_PATH = "/public_keys/ak.pub";
+ private static final String AK_PUBLIC_KEY_PATH = "/tpm2/ak.pub";
- private static final String AK_NAME_PATH = "/public_keys/ak.name";
+ private static final String AK_NAME_PATH = "/tpm2/ak.name";
private static final String EK_MODULUS_HEX = "a3 b5 c2 1c 57 be 40 c4 3c 78 90 0d 00 81 01 78"
+ "13 ca 02 ec b6 75 89 60 ca 60 9b 10 b6 b4 d0 0b"
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CertificateManagementServiceTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementServiceTest.java
similarity index 78%
rename from HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CertificateManagementServiceTest.java
rename to HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementServiceTest.java
index 80973b687..f01888c6e 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CertificateManagementServiceTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementServiceTest.java
@@ -2,7 +2,7 @@
import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.userdefined.Certificate;
-import hirs.attestationca.persist.provision.service.CertificateManagementService;
+import hirs.attestationca.persist.provision.service.CredentialManagementService;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -22,14 +22,14 @@
/**
* Unit tests for {@see CertificateManagementService}.
*/
-public class CertificateManagementServiceTest {
+public class CredentialManagementServiceTest {
private static final String EK_HEADER_TRUNCATED = "/certificates/nuc-1/ek_cert_7_byte_header_removed.cer";
private static final String EK_UNTOUCHED = "/certificates/nuc-1/ek_cert_untouched.cer";
@InjectMocks
- private CertificateManagementService certificateManagementService;
+ private CredentialManagementService credentialManagementService;
@Mock
private CertificateRepository certificateRepository;
@@ -65,7 +65,7 @@ public void tearDown() throws Exception {
@Test
public void processNullEndorsementCredential() {
assertThrows(IllegalArgumentException.class, () ->
- certificateManagementService.storeEndorsementCredential(null,
+ credentialManagementService.storeEndorsementCredential(null,
"testName"));
}
@@ -75,7 +75,7 @@ public void processNullEndorsementCredential() {
@Test
public void processEmptyEndorsementCredential() {
assertThrows(IllegalArgumentException.class, () ->
- certificateManagementService.storeEndorsementCredential(new byte[0], "testName"));
+ credentialManagementService.storeEndorsementCredential(new byte[0], "testName"));
}
/**
@@ -85,7 +85,7 @@ public void processEmptyEndorsementCredential() {
public void processInvalidEndorsementCredentialCase1() {
byte[] ekBytes = new byte[]{1};
assertThrows(IllegalArgumentException.class, () ->
- certificateManagementService.storeEndorsementCredential(ekBytes, "testName"));
+ credentialManagementService.storeEndorsementCredential(ekBytes, "testName"));
}
/**
@@ -95,7 +95,7 @@ public void processInvalidEndorsementCredentialCase1() {
public void processInvalidEndorsementCredentialCase2() {
byte[] ekBytes = new byte[]{1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0};
assertThrows(IllegalArgumentException.class, () ->
- certificateManagementService.storeEndorsementCredential(ekBytes,
+ credentialManagementService.storeEndorsementCredential(ekBytes,
"testName"));
}
@@ -107,10 +107,10 @@ public void processInvalidEndorsementCredentialCase2() {
@Test
public void parseUntouchedEndorsementCredential() throws IOException {
String path =
- Objects.requireNonNull(CertificateManagementServiceTest.class.getResource(EK_UNTOUCHED)).getPath();
+ Objects.requireNonNull(CredentialManagementServiceTest.class.getResource(EK_UNTOUCHED)).getPath();
byte[] ekBytes = IOUtils.toByteArray(new FileInputStream(path));
- certificateManagementService.storeEndorsementCredential(ekBytes, "testName");
+ credentialManagementService.storeEndorsementCredential(ekBytes, "testName");
verify(certificateRepository).save(any(Certificate.class));
}
@@ -121,11 +121,11 @@ public void parseUntouchedEndorsementCredential() throws IOException {
*/
@Test
public void parseHeaderTruncatedEndorsementCredential() throws IOException {
- String path = Objects.requireNonNull(CertificateManagementServiceTest.class.getResource(EK_HEADER_TRUNCATED))
+ String path = Objects.requireNonNull(CredentialManagementServiceTest.class.getResource(EK_HEADER_TRUNCATED))
.getPath();
byte[] ekBytes = IOUtils.toByteArray(new FileInputStream(path));
- certificateManagementService.storeEndorsementCredential(ekBytes, "testName");
+ credentialManagementService.storeEndorsementCredential(ekBytes, "testName");
verify(certificateRepository).save(any(Certificate.class));
}
}
diff --git a/HIRS_AttestationCA/src/test/resources/public_keys/ak.name b/HIRS_AttestationCA/src/test/resources/tpm2/ak.name
similarity index 100%
rename from HIRS_AttestationCA/src/test/resources/public_keys/ak.name
rename to HIRS_AttestationCA/src/test/resources/tpm2/ak.name
diff --git a/HIRS_AttestationCA/src/test/resources/public_keys/ak.pub b/HIRS_AttestationCA/src/test/resources/tpm2/ak.pub
similarity index 100%
rename from HIRS_AttestationCA/src/test/resources/public_keys/ak.pub
rename to HIRS_AttestationCA/src/test/resources/tpm2/ak.pub
diff --git a/HIRS_AttestationCA/src/test/resources/public_keys/ek.pub b/HIRS_AttestationCA/src/test/resources/tpm2/ek.pub
similarity index 100%
rename from HIRS_AttestationCA/src/test/resources/public_keys/ek.pub
rename to HIRS_AttestationCA/src/test/resources/tpm2/ek.pub
From 8f256fd10c547a5831abd92b64022a7058aceb95 Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Fri, 6 Mar 2026 17:00:30 -0500
Subject: [PATCH 14/25] v3.1_issue_1090: Should fix the unusual system error.
---
.../provision/service/IdentityClaimProcessorService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
index b2c8cb2e9..a55c12e7c 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
@@ -231,7 +231,7 @@ private AppraisalStatus.Status doSupplyChainValidation(final ProvisionerTpm2.Ide
DeviceInfoReport deviceInfo = Objects.requireNonNull(device.getDeviceInfo());
List componentInfoList = deviceInfoProcessorService.processDeviceComponents(
deviceInfo.getNetworkInfo().getHostname(),
- deviceInfo.getPaccorOutputString());
+ identityClaim.getPaccorOutput());
// Store the platform certificates' components
credentialManagementService.saveOrUpdatePlatformCertificateComponents(platformCredentials);
From b368c917867c3a3aed413e05e6a0f9824df34e9f Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Tue, 10 Mar 2026 17:48:04 -0400
Subject: [PATCH 15/25] v3.1_issue_1127: Adding the setup ecc keys param to the
powershell scripts slowly but surely. Renamed some functions in the
service/helper classes.
---
.../provision/helper/ProvisionUtils.java | 6 +-
.../service/DeviceInfoProcessorService.java | 4 +-
package/linux/aca/aca_setup.sh | 7 ++-
package/win/aca/aca_common.ps1 | 29 ++++++++-
package/win/aca/aca_setup.ps1 | 59 +++++++++++++++++--
5 files changed, 92 insertions(+), 13 deletions(-)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index 84dc43022..5b9331a7f 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -163,7 +163,7 @@ public static String getPemEncodedCertificate(final X509Certificate certificate)
* @return the parsed PublicKey instance
*/
public static PublicKey parsePublicKeyFromPublicDataSegment(final byte[] publicAreaSegment) {
- final PublicKeyAlgorithm publicKeyAlgorithm = determinePublicKeyAlgorithm(publicAreaSegment);
+ final PublicKeyAlgorithm publicKeyAlgorithm = extractPublicKeyAlgorithmFromByteArray(publicAreaSegment);
return switch (publicKeyAlgorithm) {
case RSA -> parseRSAKeyFromPublicDataSegment(publicAreaSegment);
@@ -178,7 +178,7 @@ public static PublicKey parsePublicKeyFromPublicDataSegment(final byte[] publicA
* @param byteArray byte array
* @return public key algorithm
*/
- public static PublicKeyAlgorithm determinePublicKeyAlgorithm(byte[] byteArray) {
+ public static PublicKeyAlgorithm extractPublicKeyAlgorithmFromByteArray(byte[] byteArray) {
// Return UNKNOWN if there are not enough bytes for comparison
if (byteArray == null || byteArray.length < 2) {
@@ -195,7 +195,7 @@ public static PublicKeyAlgorithm determinePublicKeyAlgorithm(byte[] byteArray) {
// - The bitwise OR (`|`) combines the two parts into a single 16-bit value (int).
final int algorithmId = ((byteArray[0] & unsignedByteMask) << byteShiftVal) | (byteArray[1] & unsignedByteMask);
- // Compare the extracted ID with the enums
+ // Compare the extracted ID with the enum's list of ids
return PublicKeyAlgorithm.fromId(algorithmId);
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
index d5f3b3450..06047a6e5 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
@@ -689,8 +689,8 @@ private void updateEventLogInfoUsingDeviceInfo(final ProvisionerTpm2.DeviceInfo
if (bRim != null) {
// pull the base versions of the swidtag and rimel and set the
// event log hash for use during provision
- SupportReferenceManifest sBaseRim = referenceManifestRepository
- .getSupportRimEntityById(bRim.getAssociatedRim());
+ SupportReferenceManifest sBaseRim =
+ referenceManifestRepository.getSupportRimEntityById(bRim.getAssociatedRim());
if (sBaseRim != null) {
bRim.setEventLogHash(provisionedEventLog.getHexDecHash());
sBaseRim.setEventLogHash(provisionedEventLog.getHexDecHash());
diff --git a/package/linux/aca/aca_setup.sh b/package/linux/aca/aca_setup.sh
index c7523ea96..0180276c1 100755
--- a/package/linux/aca/aca_setup.sh
+++ b/package/linux/aca/aca_setup.sh
@@ -29,7 +29,7 @@ help () {
echo " -sd | --skip-db run the setup without database setup."
echo " -aa | --aca-alg specify the ACA's default algorithm (rsa, ecc, or mldsa) for Attestation Certificates"
echo " -ta | --tls-alg specify the ACA's default algorithm (rsa, ecc, or mldsa) for TLS on the ACA portal"
- echo " -da | --db-alg specify the ACA's default algorithm (rsa, ecc, or mldsa) for use with maraidb"
+ echo " -da | --db-alg specify the ACA's default algorithm (rsa, ecc, or mldsa) for use with MariaDB"
echo
}
@@ -205,10 +205,12 @@ if [ -z "${ARG_SKIP_DB}" ]; then
fi
# Update properties file based upon algorithm choices
-echo "Setting algorithm setting for TLS and ACA..."
+echo "Setting public key algorithm for TLS and ACA..."
+
# remove default config file lines for tomcat ssl aliases
sed -i '/server.ssl.trust-alias/d' $SPRING_PROP_FILE
sed -i '/server.ssl.key-alias/d' $SPRING_PROP_FILE
+
if [ "$TLS_ALG" == "rsa" ]; then
echo "server.ssl.trust-alias=hirs_aca_tls_rsa_3k_sha384" >> $SPRING_PROP_FILE
echo "server.ssl.key-alias=hirs_aca_tls_rsa_3k_sha384_key" >> $SPRING_PROP_FILE
@@ -221,6 +223,7 @@ fi
sed -i '/aca.certificates.leaf-three-key-alias/d' $SPRING_PROP_FILE
sed -i '/aca.certificates.intermediate-key-alias/d' $SPRING_PROP_FILE
sed -i '/aca.certificates.root-key-alias/d' $SPRING_PROP_FILE
+
if [ "$ACA_ALG" == "rsa" ]; then
# Add new lines for aca aliases for the RSA public key algorithm
{
diff --git a/package/win/aca/aca_common.ps1 b/package/win/aca/aca_common.ps1
index caa7283d5..2f602ce1d 100644
--- a/package/win/aca/aca_common.ps1
+++ b/package/win/aca/aca_common.ps1
@@ -37,12 +37,14 @@ $global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME="mysql_admin_password"
$global:ACA_PROPERTIES_HIRS_DB_USERNAME_PROPERTY_NAME="hirs_db_username"
$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME="hirs_db_password"
-
# Spring Property Keys
$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME="hibernate.connection.username"
$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME="hibernate.connection.password"
$global:SPRING_PROPERTIES_SSL_KEY_STORE_PWD_PROPERTY_NAME="server.ssl.key-store-password"
$global:SPRING_PROPERTIES_SSL_KEY_TRUST_STORE_PWD_PROPERTY_NAME="server.ssl.trust-store-password"
+$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME="aca.certificates.leaf-three-key-alias"
+$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME="aca.certificates.intermediate-key-alias"
+$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME="aca.certificates.root-key-alias"
# DB Configuration file
$global:DB_CONF = (Resolve-Path ([System.IO.Path]::Combine($Env:ProgramFiles, 'MariaDB 11.1', 'data', 'my.ini'))).Path
@@ -311,6 +313,31 @@ Function add_new_spring_property () {
read_spring_properties $file
}
+Function setup_aca_tls_public_key_algorithm(){
+ param(
+ [Parameter(Mandatory=$true)]
+ [string]$tlsAlg,
+ [Parameter(Mandatory=$true)]
+ [string]$acaAlg
+ )
+
+ if (-not $tlsAlg -or -not $acaAlg) {
+ Write-Output "Exiting script while attempting to set the ACA's public key algorithm since the provided TLS and ACA Public Key Algorithm [$file]
+ do not exist/have noot been supplied" | WriteAndLog
+ exit 1
+ }
+
+ if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME")){
+ add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME=hirs_db"
+ Write-Output "Stored the hibernate connection username in the spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ }
+
+ if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME")){
+ add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME=$HIRS_DB_PASS"
+ Write-Output "Stored the hibernate connection password property in the spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ }
+}
+
Function create_random () {
# Step 1: Generate a string of 100 random numbers concatenated together
$randomData = -join (1..100 | ForEach-Object { Get-Random })
diff --git a/package/win/aca/aca_setup.ps1 b/package/win/aca/aca_setup.ps1
index 22ffe61d6..078d6a2df 100644
--- a/package/win/aca/aca_setup.ps1
+++ b/package/win/aca/aca_setup.ps1
@@ -2,23 +2,32 @@ param (
[switch]$sd, [switch]${skip-db} = $false,
[switch]$sp, [switch]${skip-pki} = $false,
[switch]$u, [switch]$unattended = $false,
- [switch]$h, [switch]$help = $false
+ [switch]$h, [switch]$help = $false,
+ [string]$aa, [string]${aca-alg},
+ [string]$ta, [string]${ta-alg},
+ [string]$da, [string]${db-alg}
)
# Parameter Consolidation
-$skipdb=$sd -or ${skip-db}
-$skippki=$sp -or ${skip-pki}
-$unattended=$u -or $unattended
+$skipdb = $sd -or ${skip-db}
+$skippki= $sp -or ${skip-pki}
+$unattended = $u -or $unattended
$help = $h -or $help
+$AcaAlg = $aa ?? ${aca-alg}
+$TlsAlg = $ta ?? ${ta-alg}
+$DbAlg = $da ?? ${db-alg}
if ($help) {
Write-Host " Setup script for the HIRS ACA on Windows"
- Write-Host " Syntax: .\aca_setup.ps1 [-u|-h|-sd|-sp|-skip-db|-skip-pki|-unattended|-help]"
+ Write-Host " Syntax: .\aca_setup.ps1 [-u|-h|-sp|-sb|-aa|-ta|-da|-skip-db|-skip-pki|-unattended|-help]"
Write-Host " Flag options:"
Write-Host " [-u | -unattended] Runs the script unattended."
Write-Host " [-h | -help] Prints this help message."
Write-Host " [-sp | -skip-pki] Skips the pki setup of the setup script."
Write-Host " [-sb | -skip-db] Skips the database setup of the setup script."
+ Write-Host " [-aa | -aca-alg] Sets the ACA's default algorithm (RSA, ECC, or MLDSA) for Attestation Certificates."
+ Write-Host " [-ta | -tls-alg] Sets the ACA's default algorithm (RSA, ECC, or MLDSA) for TLS on the ACA portal."
+ Write-Host " [-da | -db-alg] Sets the ACA's default algorithm (RSA, ECC, or MLDSA) for use with MariaDB."
exit 1
}
@@ -29,6 +38,41 @@ if(!(New-Object Security.Principal.WindowsPrincipal(
exit 1
}
+# Set default algorithms to "RSA" if none provided
+if (-not $AcaAlg) {
+ $AcaAlg = "rsa"
+ Write-Host "Using default algorithm ($AcaAlg) for Attestation Certs."
+}
+
+if (-not $TlsAlg) {
+ $TlsAlg = "rsa"
+ Write-Host "Using default algorithm ($TlsAlg) for the ACA portal."
+}
+
+if (-not $DbAlg) {
+ $DbAlg = "rsa"
+ Write-Host "Using default algorithm ($DbAlg) for the Database."
+}
+
+# Define valid options
+$validAlgs = @("rsa", "ecc")
+
+# Check for valid algorithms
+if ($validAlgs -notcontains $AcaAlg) {
+ Write-Host "Invalid ACA algorithm $AcaAlg specified. Valid options are rsa or ecc."
+ exit 1
+}
+
+if ($validAlgs -notcontains $TlsAlg) {
+ Write-Host "Invalid TLS algorithm $TlsAlg specified. Valid options are rsa or ecc."
+ exit 1
+}
+
+if ($validAlgs -notcontains $DbAlg) {
+ Write-Host "Invalid DB algorithm $DbAlg specified. Valid options are rsa or ecc."
+ exit 1
+}
+
$ACA_SCRIPTS_HOME=(Split-Path -parent $PSCommandPath)
$ACA_COMMON_SCRIPT=(Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
$COMP_JSON = (Resolve-Path ([System.IO.Path]::Combine(
@@ -140,6 +184,11 @@ if (!$skipdb) {
Write-Output ("ACA Database setup cannot be run because there are command line argument(s): "+($PSBoundParameters.Keys | Where-Object { $_ -match 'skip-db|sd'})) | WriteAndLog
}
+# Update properties file based upon algorithm choices
+Write-Host "Setting public key algorithm for TLS and ACA..."
+
+#setup_aca_tls_public_key_algorithm $TlsAlg $AcaAlg
+
Write-Output "ACA setup complete" | WriteAndLog
Write-Host "----------------------------------------------------------------------"
Write-Host ""
\ No newline at end of file
From 5e570272e3ab196fee9b7595c85787393868006e Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Wed, 11 Mar 2026 18:15:23 -0400
Subject: [PATCH 16/25] v3.1_issue1127: Can now add rsa,ecc properties to the
spring file when params are set. Corrrected language/presentation of help
menu for both bash and ps scripts.
---
package/linux/aca/aca_setup.sh | 19 +++---
package/win/aca/aca_common.ps1 | 118 +++++++++++++++++++++++++++++----
package/win/aca/aca_setup.ps1 | 102 ++++++++++++++--------------
3 files changed, 165 insertions(+), 74 deletions(-)
diff --git a/package/linux/aca/aca_setup.sh b/package/linux/aca/aca_setup.sh
index 0180276c1..2ee84992d 100755
--- a/package/linux/aca/aca_setup.sh
+++ b/package/linux/aca/aca_setup.sh
@@ -21,15 +21,16 @@ VENDOR_TABLE='../../../HIRS_Utils/src/main/resources/vendor-table.json'
help () {
echo " Setup script for the HIRS ACA"
- echo " Syntax: sh aca_setup.sh [-u|h|sb|sp|--skip-db|--skip-pki]"
- echo " options:"
- echo " -u | --unattended Run unattended"
- echo " -h | --help Print this Help."
- echo " -sp | --skip-pki run the setup without pki setup."
- echo " -sd | --skip-db run the setup without database setup."
- echo " -aa | --aca-alg specify the ACA's default algorithm (rsa, ecc, or mldsa) for Attestation Certificates"
- echo " -ta | --tls-alg specify the ACA's default algorithm (rsa, ecc, or mldsa) for TLS on the ACA portal"
- echo " -da | --db-alg specify the ACA's default algorithm (rsa, ecc, or mldsa) for use with MariaDB"
+ echo " Syntax (short form): sh aca_setup.sh [-u|h|sp|sd|aa|ta|da]"
+ echo " Syntax (long form): sh aca_setup.sh [--unattended|--help|--skip-db|--skip-pki|--aca-alg|--tls-alg|--db-alg]"
+ echo " Flag options:"
+ echo " [-u | --unattended] Runs the script unattended"
+ echo " [-h | --help] Prints this help message."
+ echo " [-sp | --skip-pki] Skips the pki setup of the setup script."
+ echo " [-sd | --skip-db] Skips the database setup of the setup script."
+ echo " [-aa | --aca-alg] Sets the ACA's default algorithm (rsa, ecc, or mldsa) for Attestation Certificates"
+ echo " [-ta | --tls-alg] Sets the ACA's default algorithm (rsa, ecc, or mldsa) for TLS on the ACA portal"
+ echo " [-da | --db-alg] Sets the ACA's default algorithm (rsa, ecc, or mldsa) for use with MariaDB"
echo
}
diff --git a/package/win/aca/aca_common.ps1 b/package/win/aca/aca_common.ps1
index 2f602ce1d..0c0a21a0f 100644
--- a/package/win/aca/aca_common.ps1
+++ b/package/win/aca/aca_common.ps1
@@ -40,6 +40,8 @@ $global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME="hirs_db_password"
# Spring Property Keys
$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME="hibernate.connection.username"
$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME="hibernate.connection.password"
+$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME="server.ssl.trust-alias"
+$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME="server.ssl.key-alias"
$global:SPRING_PROPERTIES_SSL_KEY_STORE_PWD_PROPERTY_NAME="server.ssl.key-store-password"
$global:SPRING_PROPERTIES_SSL_KEY_TRUST_STORE_PWD_PROPERTY_NAME="server.ssl.trust-store-password"
$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME="aca.certificates.leaf-three-key-alias"
@@ -313,28 +315,120 @@ Function add_new_spring_property () {
read_spring_properties $file
}
-Function setup_aca_tls_public_key_algorithm(){
- param(
+Function remove_spring_property_value_pair(){
+ param (
+ [Parameter(Mandatory=$true)]
+ [string]$file,
[Parameter(Mandatory=$true)]
- [string]$tlsAlg,
+ [string]$keyToBeDeleted
+ )
+
+ if (-not $file -or -not $keyToBeDeleted -or -not (Test-Path $file)) {
+ Write-Output "Exiting script while attempting to delete a Spring property since the provided file [$file] does not exist and/or
+ the provided key to be deleted has not been supplied" | WriteAndLog
+ exit 1
+ }
+
+ # Read all lines
+ $lines = Get-Content $File
+
+ # Filter out lines that start with key=
+ $filteredLines = $lines | Where-Object { $_ -notmatch "^\s*$([regex]::Escape($KeyToBeDeleted))=" }
+
+ # Write back to the file (overwrite)
+ Set-Content -Path $File -Value $filteredLines
+
+ Write-Output "Removed property [$KeyToBeDeleted] from file [$File]."
+
+ # Reset the global spring property hashmap and reload
+ $global:SPRING_PROPERTIES = $null
+ Write-Output "Resetting and reloading the spring properties table" | WriteAndLog
+ read_spring_properties $file
+}
+
+Function setup_aca_public_key_algorithm(){
+ param(
[Parameter(Mandatory=$true)]
[string]$acaAlg
)
- if (-not $tlsAlg -or -not $acaAlg) {
- Write-Output "Exiting script while attempting to set the ACA's public key algorithm since the provided TLS and ACA Public Key Algorithm [$file]
- do not exist/have noot been supplied" | WriteAndLog
+ if (-not $acaAlg) {
+ Write-Output "Exiting script while attempting to set the ACA's public key algorithm since the provided ACA Public Key Algorithm
+ do not exist/have not been supplied" | WriteAndLog
exit 1
}
- if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME")){
- add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME=hirs_db"
- Write-Output "Stored the hibernate connection username in the spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ $aca_leaf_cert_val=$null
+ $aca_intermediate_cert_val=$null
+ $aca_root_cert_val=$null
+
+ if($acaAlg -eq "rsa"){
+ $aca_leaf_cert_val="HIRS_leaf_ca3_rsa_3k_sha384_key"
+ $aca_intermediate_cert_val="HIRS_intermediate_ca_rsa_3k_sha384_key"
+ $aca_root_cert_val="HIRS_root_ca_rsa_3k_sha384_key"
+ }
+ elseif($acaAlg -eq "ecc"){
+ $aca_leaf_cert_val="HIRS_leaf_ca3_ecc_512_sha384_key"
+ $aca_intermediate_cert_val="HIRS_intermediate_ca_ecc_512_sha384_key"
+ $aca_root_cert_val="HIRS_root_ca_ecc_512_sha384_key"
+ }
+
+ remove_spring_property_value_pair -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME"
+ remove_spring_property_value_pair -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME"
+ remove_spring_property_value_pair -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME"
+
+ if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME")){
+ add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME=$aca_leaf_cert_val"
+ Write-Output "Stored the $acaAlg ACA Leaf certificate alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ }
+
+ if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME")){
+ add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME=$aca_intermediate_cert_val"
+ Write-Output "Stored the $acaAlg ACA Intermediate certificate alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ }
+
+ if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME")){
+ add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME=$aca_root_cert_val"
+ Write-Output "Stored the $acaAlg ACA Root certificate alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ }
+}
+
+Function setup_tls_config_aliases(){
+ param(
+ [Parameter(Mandatory=$true)]
+ [string]$tlsAlg
+ )
+
+ if (-not $tlsAlg) {
+ Write-Output "Exiting script while attempting to set the config file lines for tomcat ssl aliases since the provided TLS
+ do not exist/have not been supplied" | WriteAndLog
+ exit 1
+ }
+
+ $server_ssl_trust_alias_val=$null
+ $server_ssl_key_alias_val=$null
+
+ if($acaAlg -eq "rsa"){
+ $server_ssl_trust_alias_val="hirs_aca_tls_rsa_3k_sha384"
+ $server_ssl_key_alias_val="hirs_aca_tls_rsa_3k_sha384_key"
+ }
+ elseif($acaAlg -eq "ecc"){
+ $server_ssl_trust_alias_val="hirs_aca_tls_ecc_512_sha384"
+ $server_ssl_key_alias_val="hirs_aca_tls_ecc_512_sha384_key"
+ }
+
+ # remove default SSL config lines
+ remove_spring_property_value_pair -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME"
+ remove_spring_property_value_pair -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME"
+
+ if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME")){
+ add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME=$server_ssl_trust_alias_val"
+ Write-Output "Stored the $tlsAlg SSL Trust Alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
}
- if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME")){
- add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME=$HIRS_DB_PASS"
- Write-Output "Stored the hibernate connection password property in the spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME")){
+ add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME=$server_ssl_key_alias_val"
+ Write-Output "Stored the $tlsAlg SSL Key alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
}
}
diff --git a/package/win/aca/aca_setup.ps1 b/package/win/aca/aca_setup.ps1
index 078d6a2df..ddbce3c0d 100644
--- a/package/win/aca/aca_setup.ps1
+++ b/package/win/aca/aca_setup.ps1
@@ -1,25 +1,20 @@
param (
- [switch]$sd, [switch]${skip-db} = $false,
- [switch]$sp, [switch]${skip-pki} = $false,
- [switch]$u, [switch]$unattended = $false,
- [switch]$h, [switch]$help = $false,
- [string]$aa, [string]${aca-alg},
- [string]$ta, [string]${ta-alg},
- [string]$da, [string]${db-alg}
+ # Switches
+ [Alias("sd","skip-db")][switch]$skipdb = $false,
+ [Alias("sp","skip-pki")][switch]$skippki = $false,
+ [Alias("u","unattended")][switch]$IsUnattended = $false,
+ [Alias("h","help")][switch]$ShowHelp = $false,
+
+ # Strings
+ [Alias("aa","aca-alg")][string]$AcaAlg,
+ [Alias("ta","ta-alg")][string]$TlsAlg,
+ [Alias("da","db-alg")][string]$DbAlg
)
-# Parameter Consolidation
-$skipdb = $sd -or ${skip-db}
-$skippki= $sp -or ${skip-pki}
-$unattended = $u -or $unattended
-$help = $h -or $help
-$AcaAlg = $aa ?? ${aca-alg}
-$TlsAlg = $ta ?? ${ta-alg}
-$DbAlg = $da ?? ${db-alg}
-
-if ($help) {
+if ($ShowHelp) {
Write-Host " Setup script for the HIRS ACA on Windows"
- Write-Host " Syntax: .\aca_setup.ps1 [-u|-h|-sp|-sb|-aa|-ta|-da|-skip-db|-skip-pki|-unattended|-help]"
+ Write-Host " Syntax (short form): .\aca_setup.ps1 [-u|-h|-sp|-sb|-aa|-ta|-da]"
+ Write-Host " Syntax (long form): .\aca_setup.ps1 [--unattended|--help|--skip-db|--skip-pki|--aca-alg|--tls-alg|--db-alg]"
Write-Host " Flag options:"
Write-Host " [-u | -unattended] Runs the script unattended."
Write-Host " [-h | -help] Prints this help message."
@@ -149,45 +144,46 @@ if (-not (Test-Path $global:HIRS_DATA_SPRING_PROP_FILE)) {
read_spring_properties $global:HIRS_DATA_SPRING_PROP_FILE
# Runs the pki_setup script (along with the other scripts under the PKI folder)
-if (!$skippki) {
- if (!$Env:HIRS_PKI_PWD) {
- $HIRS_PKI_PWD=(create_random)
- # NOTE: Writing to the environment variable did not work within the container
- # This password will be stored in the ACA properties file.
- Write-Output "Using randomly generated password for the PKI key password" | WriteAndLog
- Write-Host "NOT LOGGED: Using pki password=$HIRS_PKI_PWD"
- } else {
- $HIRS_PKI_PWD=$Env:HIRS_PKI_PWD
- Write-Output "Using system supplied password for the PKI key password" | WriteAndLog
- }
- pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_PKI_SETUP -LOG_FILE:"$global:LOG_FILE" -PKI_PASS:"$HIRS_PKI_PWD" -UNATTENDED:"$unattended"
- if ($LastExitCode -eq 0) {
- Write-Output "ACA PKI setup complete" | WriteAndLog
- } else {
- Write-Output "Error setting up ACA PKI" | WriteAndLog
- exit 1
- }
-} else {
- Write-Output ("ACA PKI setup cannot be run because there are command line argument(s): "+($PSBoundParameters.Keys | Where-Object { $_ -match 'skip-pki|sp' } )) | WriteAndLog
-}
-
-# Runs the create_db script (along with the other scripts under the DB folder)
-if (!$skipdb) {
- pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_DB_CREATE -LOG_FILE:"$global:LOG_FILE" -UNATTENDED:"$unattended"
- if ($LastExitCode -eq 0) {
- Write-Output "ACA database setup complete" | WriteAndLog
- } else {
- Write-Output "Error setting up ACA DB" | WriteAndLog
- exit 1
- }
-} else {
- Write-Output ("ACA Database setup cannot be run because there are command line argument(s): "+($PSBoundParameters.Keys | Where-Object { $_ -match 'skip-db|sd'})) | WriteAndLog
-}
+# if (!$skippki) {
+# if (!$Env:HIRS_PKI_PWD) {
+# $HIRS_PKI_PWD=(create_random)
+# # NOTE: Writing to the environment variable did not work within the container
+# # This password will be stored in the ACA properties file.
+# Write-Output "Using randomly generated password for the PKI key password" | WriteAndLog
+# Write-Host "NOT LOGGED: Using pki password=$HIRS_PKI_PWD"
+# } else {
+# $HIRS_PKI_PWD=$Env:HIRS_PKI_PWD
+# Write-Output "Using system supplied password for the PKI key password" | WriteAndLog
+# }
+# pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_PKI_SETUP -LOG_FILE:"$global:LOG_FILE" -PKI_PASS:"$HIRS_PKI_PWD" -UNATTENDED:"$IsUnattended"
+# if ($LastExitCode -eq 0) {
+# Write-Output "ACA PKI setup complete" | WriteAndLog
+# } else {
+# Write-Output "Error setting up ACA PKI" | WriteAndLog
+# exit 1
+# }
+# } else {
+# Write-Output ("ACA PKI setup cannot be run because there are command line argument(s): "+($PSBoundParameters.Keys | Where-Object { $_ -match 'skip-pki|sp' } )) | WriteAndLog
+# }
+
+# # Runs the create_db script (along with the other scripts under the DB folder)
+# if (!$skipdb) {
+# pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_DB_CREATE -LOG_FILE:"$global:LOG_FILE" -UNATTENDED:"$IsUnattended"
+# if ($LastExitCode -eq 0) {
+# Write-Output "ACA database setup complete" | WriteAndLog
+# } else {
+# Write-Output "Error setting up ACA DB" | WriteAndLog
+# exit 1
+# }
+# } else {
+# Write-Output ("ACA Database setup cannot be run because there are command line argument(s): "+($PSBoundParameters.Keys | Where-Object { $_ -match 'skip-db|sd'})) | WriteAndLog
+# }
# Update properties file based upon algorithm choices
Write-Host "Setting public key algorithm for TLS and ACA..."
-#setup_aca_tls_public_key_algorithm $TlsAlg $AcaAlg
+setup_tls_config_aliases -tlsAlg $TlsAlg
+setup_aca_public_key_algorithm -acaAlg $AcaAlg
Write-Output "ACA setup complete" | WriteAndLog
Write-Host "----------------------------------------------------------------------"
From 7fb57570c6401cc159ebfeba9d5e0e4721b267b7 Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Thu, 12 Mar 2026 12:49:48 -0400
Subject: [PATCH 17/25] v3.1_issue1127: Finished modifying powershell scripts
to accept the ta, aa, and da parameters and can now set the ecc and rsa
configs based on the provided alg param. Corrected spelling, syntax errors,
and other minor things to ensure these scripts can be run without any issues.
---
package/win/aca/aca_bootRun.ps1 | 40 +++++--------
package/win/aca/aca_check_setup.ps1 | 69 +++++++++++++---------
package/win/aca/aca_common.ps1 | 56 +++++++++---------
package/win/aca/aca_remove_setup.ps1 | 2 +-
package/win/aca/aca_setup.ps1 | 86 +++++++++++++--------------
package/win/db/db_create.ps1 | 88 +++++++++++++++++-----------
package/win/pki/pki_setup.ps1 | 13 ++--
7 files changed, 186 insertions(+), 168 deletions(-)
diff --git a/package/win/aca/aca_bootRun.ps1 b/package/win/aca/aca_bootRun.ps1
index ab1340a55..b28155747 100644
--- a/package/win/aca/aca_bootRun.ps1
+++ b/package/win/aca/aca_bootRun.ps1
@@ -1,30 +1,18 @@
param (
- [string]$p, [string]$path = $null,
- [switch]$w, [switch]$war = $false,
- [switch]$d, [switch]$debug = $false,
- [switch]$h, [switch]$help = $false
+ [Alias("p","path")][string]$PathToWarFile,
+ [Alias("w","war")][switch]$UseWarFile = $false,
+ [Alias("d","debug")][switch]$EnableDebugMode = $false,
+ [Alias("h","help")][switch]$ShowHelp = $false
)
-# Parameter Consolidation
-if ($p -and $path -and ($p -ne $path)) {
- "-p and -path were given different paths. Use only one." | WriteAndLog
- $help=$true
-}
-if ($p) {
- $path = $p
-}
-$war = $w -or $war
-$debug = $d -or $debug
-$help = $h -or $help
-
-if ($help) {
+if ($ShowHelp) {
Write-Output " Bootrun script for the HIRS ACA"
Write-Output " Syntax: powershell -ExecutionPolicy Bypass aca_bootRun.ps1 [-h|-p|-d|-w|-path|-war|-debug|-help]"
- Write-Output " options:"
+ Write-Output " Flag options:"
Write-Output " [ -p | -path] Path to the HIRS_AttestationCAPortal.war file"
Write-Output " [ -w | -war ] Use deployed war file"
Write-Output " [ -d | -debug ] Launch the JVM with a debug port open"
- Write-Output " [ -h | -help ] Print this help"
+ Write-Output " [ -h | -help ] Print this help menu"
exit 1
}
@@ -48,16 +36,16 @@ $DEBUG_OPTIONS='-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:
set_up_log
# Read aca.properties
-read_aca_properties $global:HIRS_DATA_ACA_PROPERTIES_FILE
+read_aca_properties -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE"
# Read spring application.properties
-read_spring_properties $global:HIRS_DATA_SPRING_PROP_FILE
+read_spring_properties -file "$global:HIRS_DATA_SPRING_PROP_FILE"
Write-Output "-----------------------------------------------------------" | WriteAndLog
Write-Output ("Running with these arguments: "+($PSBoundParameters | Out-String)) | WriteAndLog
-if ($path) {
- $DEPLOYED_WAR = $path
+if ($PathToWarFile) {
+ $DEPLOYED_WAR = $PathToWarFile
}
if (![System.IO.Directory]::Exists($global:HIRS_DATA_CERTIFICATES_HIRS_DIR)) {
@@ -75,9 +63,9 @@ if (!$DEPLOYED_WAR) {
$SPRING_PROP_FILE_FORWARDSLASHES=($global:HIRS_DATA_SPRING_PROP_FILE | ChangeBackslashToForwardSlash)
-if ($w -or $war) {
+if ($UseWarFile) {
Write-Output "Booting the ACA from a war file..." | WriteAndLog
- if ($d -or $debug) {
+ if ($EnableDebugMode) {
Write-Output "... in debug"
java $DEBUG_OPTIONS -jar $DEPLOYED_WAR --spring.config.location=$SPRING_PROP_FILE_FORWARDSLASHES
} else {
@@ -85,7 +73,7 @@ if ($w -or $war) {
}
} else {
Write-Output "Booting the ACA from local build..." | WriteAndLog
- if ($d -or $debug) {
+ if ($EnableDebugMode) {
Write-Output "... in debug"
./gradlew bootRun --args="--spring.config.location=$SPRING_PROP_FILE_FORWARDSLASHES" -Pdebug="$DEBUG_OPTIONS"
} else {
diff --git a/package/win/aca/aca_check_setup.ps1 b/package/win/aca/aca_check_setup.ps1
index 6732e6edf..e5a98a4b0 100644
--- a/package/win/aca/aca_check_setup.ps1
+++ b/package/win/aca/aca_check_setup.ps1
@@ -1,15 +1,11 @@
#This script will check to see if the ACA has already been setup in a Windows environment
param (
- [switch]$v, [switch]$verbose = $false,
- [switch]$h, [switch]$help = $false
+ [Alias("v","verbose")][switch]$ShowVerbose = $false,
+ [Alias("h","help")][switch]$ShowHelp = $false
)
-# Parameter Consolidation
-$verbose=$v -or $verbose
-$help = $h -or $help
-
-if ($help) {
+if ($ShowHelp) {
Write-Output " aca check setup script for the HIRS ACA on Windows. Script checks if everything has been setup properly after the user has run the aca_setup.ps1 script."
Write-Output " Syntax: .\aca_check_setup.ps1 [-v|-h|-verbose|-help]"
Write-Output " Flag Options:"
@@ -93,28 +89,28 @@ Function check_pki() {
return
}
- Push-Location $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH | Out-Null
- check_cert -TrustStore:$global:SSL_DB_RSA_CLIENT_CHAIN -Cert:$global:RSA_HIRS_ROOT
- check_cert -TrustStore:$global:SSL_DB_RSA_CLIENT_CHAIN -Cert:$global:RSA_HIRS_INTERMEDIATE
- check_cert -TrustStore:$global:SSL_DB_RSA_CLIENT_CHAIN -Cert:$global:RSA_HIRS_CA1
- check_cert -TrustStore:$global:SSL_DB_RSA_CLIENT_CHAIN -Cert:$global:RSA_HIRS_CA2
- check_cert -TrustStore:$global:SSL_DB_RSA_CLIENT_CHAIN -Cert:$global:RSA_HIRS_CA3
- check_cert -TrustStore:$global:SSL_DB_RSA_CLIENT_CHAIN -Cert:$global:RSA_RIM_SIGNER
- check_cert -TrustStore:$global:SSL_DB_RSA_CLIENT_CHAIN -Cert:$global:SSL_DB_RSA_SRV_CERT
- check_cert -TrustStore:$global:SSL_DB_RSA_CLIENT_CHAIN -Cert:$global:SSL_DB_RSA_CLIENT_CERT
- check_cert -TrustStore:$global:SSL_DB_RSA_CLIENT_CHAIN -Cert:$global:RSA_WEB_TLS_CERT
+ Push-Location "$global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH" | Out-Null
+ check_cert -TrustStore "$global:SSL_DB_RSA_CLIENT_CHAIN" -Cert "$global:RSA_HIRS_ROOT"
+ check_cert -TrustStore "$global:SSL_DB_RSA_CLIENT_CHAIN" -Cert "$global:RSA_HIRS_INTERMEDIATE"
+ check_cert -TrustStore "$global:SSL_DB_RSA_CLIENT_CHAIN" -Cert "$global:RSA_HIRS_CA1"
+ check_cert -TrustStore "$global:SSL_DB_RSA_CLIENT_CHAIN" -Cert "$global:RSA_HIRS_CA2"
+ check_cert -TrustStore "$global:SSL_DB_RSA_CLIENT_CHAIN" -Cert "$global:RSA_HIRS_CA3"
+ check_cert -TrustStore "$global:SSL_DB_RSA_CLIENT_CHAIN" -Cert "$global:RSA_RIM_SIGNER"
+ check_cert -TrustStore "$global:SSL_DB_RSA_CLIENT_CHAIN" -Cert "$global:SSL_DB_RSA_SRV_CERT"
+ check_cert -TrustStore "$global:SSL_DB_RSA_CLIENT_CHAIN" -Cert "$global:SSL_DB_RSA_CLIENT_CERT"
+ check_cert -TrustStore "$global:SSL_DB_RSA_CLIENT_CHAIN" -Cert "$global:RSA_WEB_TLS_CERT"
Pop-Location | Out-Null
- Push-Location $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH | Out-Null
- check_cert -TrustStore:$global:SSL_DB_ECC_CLIENT_CHAIN -Cert:$global:ECC_HIRS_ROOT
- check_cert -TrustStore:$global:SSL_DB_ECC_CLIENT_CHAIN -Cert:$global:ECC_HIRS_INTERMEDIATE
- check_cert -TrustStore:$global:SSL_DB_ECC_CLIENT_CHAIN -Cert:$global:ECC_HIRS_CA1
- check_cert -TrustStore:$global:SSL_DB_ECC_CLIENT_CHAIN -Cert:$global:ECC_HIRS_CA2
- check_cert -TrustStore:$global:SSL_DB_ECC_CLIENT_CHAIN -Cert:$global:ECC_HIRS_CA3
- check_cert -TrustStore:$global:SSL_DB_ECC_CLIENT_CHAIN -Cert:$global:ECC_RIM_SIGNER
- check_cert -TrustStore:$global:SSL_DB_ECC_CLIENT_CHAIN -Cert:$global:SSL_DB_ECC_SRV_CERT
- check_cert -TrustStore:$global:SSL_DB_ECC_CLIENT_CHAIN -Cert:$global:SSL_DB_ECC_CLIENT_CERT
- check_cert -TrustStore:$global:SSL_DB_ECC_CLIENT_CHAIN -Cert:$global:ECC_WEB_TLS_CERT
+ Push-Location "$global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH" | Out-Null
+ check_cert -TrustStore "$global:SSL_DB_ECC_CLIENT_CHAIN" -Cert "$global:ECC_HIRS_ROOT"
+ check_cert -TrustStore "$global:SSL_DB_ECC_CLIENT_CHAIN" -Cert "$global:ECC_HIRS_INTERMEDIATE"
+ check_cert -TrustStore "$global:SSL_DB_ECC_CLIENT_CHAIN" -Cert "$global:ECC_HIRS_CA1"
+ check_cert -TrustStore "$global:SSL_DB_ECC_CLIENT_CHAIN" -Cert "$global:ECC_HIRS_CA2"
+ check_cert -TrustStore "$global:SSL_DB_ECC_CLIENT_CHAIN" -Cert "$global:ECC_HIRS_CA3"
+ check_cert -TrustStore "$global:SSL_DB_ECC_CLIENT_CHAIN" -Cert "$global:ECC_RIM_SIGNER"
+ check_cert -TrustStore "$global:SSL_DB_ECC_CLIENT_CHAIN" -Cert "$global:SSL_DB_ECC_SRV_CERT"
+ check_cert -TrustStore "$global:SSL_DB_ECC_CLIENT_CHAIN" -Cert "$global:SSL_DB_ECC_CLIENT_CERT"
+ check_cert -TrustStore "$global:SSL_DB_ECC_CLIENT_CHAIN" -Cert "$global:ECC_WEB_TLS_CERT"
Pop-Location | Out-Null
# if the aca properties file does not exist
@@ -166,7 +162,7 @@ Function check_cert() {
$global:ALL_CERTS_PASSED=$false
}
- if($verbose){
+ if($ShowVerbose){
Write-Host "$result"
}
}
@@ -260,7 +256,22 @@ Function check_db() {
Function check_fips() {
Write-Host "Checking FIPS mode on this device..."
- #todo
+
+ if (IsFipsEnabled) {
+ Write-Host "FIPS is ENABLED"
+ } else {
+ Write-Host "FIPS is DISABLED"
+ }
+}
+
+Function IsFipsEnabled {
+ try {
+ $fips = Get-ItemPropertyValue -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy" -Name Enabled -ErrorAction Stop
+ return [bool]$fips
+ } catch {
+ # Key not found → FIPS not enabled
+ return $false
+ }
}
# Check if the aca passwords are stored in the aca.properties file
diff --git a/package/win/aca/aca_common.ps1 b/package/win/aca/aca_common.ps1
index 0c0a21a0f..4d45d4295 100644
--- a/package/win/aca/aca_common.ps1
+++ b/package/win/aca/aca_common.ps1
@@ -254,7 +254,7 @@ Function find_property_value(){
# Reset the global spring property hashmap and reload
$global:SPRING_PROPERTIES = $null
Write-Output "Resetting and reloading the spring properties table" | WriteAndLog
- read_spring_properties $file
+ read_spring_properties -file $file
}
} else {
Write-Host "NOT LOGGED: There are no values associated with the provided key [$key]"
@@ -312,7 +312,7 @@ Function add_new_spring_property () {
Write-Host "NOT LOGGED: KeyValue pair: $newKeyAndValue to file $file"
Write-Output "$newKeyAndValue" >> $file
$global:SPRING_PROPERTIES=$null
- read_spring_properties $file
+ read_spring_properties -file $file
}
Function remove_spring_property_value_pair(){
@@ -343,7 +343,7 @@ Function remove_spring_property_value_pair(){
# Reset the global spring property hashmap and reload
$global:SPRING_PROPERTIES = $null
Write-Output "Resetting and reloading the spring properties table" | WriteAndLog
- read_spring_properties $file
+ read_spring_properties -file $file
}
Function setup_aca_public_key_algorithm(){
@@ -363,32 +363,32 @@ Function setup_aca_public_key_algorithm(){
$aca_root_cert_val=$null
if($acaAlg -eq "rsa"){
- $aca_leaf_cert_val="HIRS_leaf_ca3_rsa_3k_sha384_key"
- $aca_intermediate_cert_val="HIRS_intermediate_ca_rsa_3k_sha384_key"
- $aca_root_cert_val="HIRS_root_ca_rsa_3k_sha384_key"
+ $aca_leaf_cert_val="HIRS_leaf_ca3_rsa_3k_sha384"
+ $aca_intermediate_cert_val="HIRS_intermediate_ca_rsa_3k_sha384"
+ $aca_root_cert_val="HIRS_root_ca_rsa_3k_sha384"
}
elseif($acaAlg -eq "ecc"){
- $aca_leaf_cert_val="HIRS_leaf_ca3_ecc_512_sha384_key"
- $aca_intermediate_cert_val="HIRS_intermediate_ca_ecc_512_sha384_key"
- $aca_root_cert_val="HIRS_root_ca_ecc_512_sha384_key"
+ $aca_leaf_cert_val="HIRS_leaf_ca3_ecc_512_sha384"
+ $aca_intermediate_cert_val="HIRS_intermediate_ca_ecc_512_sha384"
+ $aca_root_cert_val="HIRS_root_ca_ecc_512_sha384"
}
- remove_spring_property_value_pair -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME"
- remove_spring_property_value_pair -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME"
- remove_spring_property_value_pair -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME"
+ remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME"
+ remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME"
+ remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME"
- if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME")){
- add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME=$aca_leaf_cert_val"
+ if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME")){
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME=$aca_leaf_cert_val"
Write-Output "Stored the $acaAlg ACA Leaf certificate alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
}
- if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME")){
- add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME=$aca_intermediate_cert_val"
+ if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME")){
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME=$aca_intermediate_cert_val"
Write-Output "Stored the $acaAlg ACA Intermediate certificate alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
}
- if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME")){
- add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME=$aca_root_cert_val"
+ if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME")){
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME=$aca_root_cert_val"
Write-Output "Stored the $acaAlg ACA Root certificate alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
}
}
@@ -408,26 +408,26 @@ Function setup_tls_config_aliases(){
$server_ssl_trust_alias_val=$null
$server_ssl_key_alias_val=$null
- if($acaAlg -eq "rsa"){
+ if($tlsAlg -eq "rsa"){
$server_ssl_trust_alias_val="hirs_aca_tls_rsa_3k_sha384"
- $server_ssl_key_alias_val="hirs_aca_tls_rsa_3k_sha384_key"
+ $server_ssl_key_alias_val="hirs_aca_tls_rsa_3k_sha384"
}
- elseif($acaAlg -eq "ecc"){
+ elseif($tlsAlg -eq "ecc"){
$server_ssl_trust_alias_val="hirs_aca_tls_ecc_512_sha384"
- $server_ssl_key_alias_val="hirs_aca_tls_ecc_512_sha384_key"
+ $server_ssl_key_alias_val="hirs_aca_tls_ecc_512_sha384"
}
# remove default SSL config lines
- remove_spring_property_value_pair -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME"
- remove_spring_property_value_pair -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME"
+ remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME"
+ remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME"
- if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME")){
- add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME=$server_ssl_trust_alias_val"
+ if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME")){
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME=$server_ssl_trust_alias_val"
Write-Output "Stored the $tlsAlg SSL Trust Alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
}
- if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME")){
- add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME=$server_ssl_key_alias_val"
+ if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME")){
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME=$server_ssl_key_alias_val"
Write-Output "Stored the $tlsAlg SSL Key alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
}
}
diff --git a/package/win/aca/aca_remove_setup.ps1 b/package/win/aca/aca_remove_setup.ps1
index 5991f7432..f9341b3b2 100644
--- a/package/win/aca/aca_remove_setup.ps1
+++ b/package/win/aca/aca_remove_setup.ps1
@@ -62,7 +62,7 @@ if(-not $DB_ADMIN_PWD){
# remove the hrs-db and hirs_db user (execute the .\db_drop.ps1 script)
Write-Host "Calling the db_drop.ps1 script to drop the hirs_db"
-. $global:HIRS_REL_WIN_DB_DROP -DB_ADMIN_PWD:"$DB_ADMIN_PWD"
+. $global:HIRS_REL_WIN_DB_DROP -DB_ADMIN_PWD "$DB_ADMIN_PWD"
# remove the entire hirs directory which contains the rsa/ecc certificates, the logs and the war file
Write-Host "Removing the [$global:HIRS_DATA_DIR] directory"
diff --git a/package/win/aca/aca_setup.ps1 b/package/win/aca/aca_setup.ps1
index ddbce3c0d..5bbaa429d 100644
--- a/package/win/aca/aca_setup.ps1
+++ b/package/win/aca/aca_setup.ps1
@@ -1,11 +1,8 @@
param (
- # Switches
[Alias("sd","skip-db")][switch]$skipdb = $false,
[Alias("sp","skip-pki")][switch]$skippki = $false,
[Alias("u","unattended")][switch]$IsUnattended = $false,
[Alias("h","help")][switch]$ShowHelp = $false,
-
- # Strings
[Alias("aa","aca-alg")][string]$AcaAlg,
[Alias("ta","ta-alg")][string]$TlsAlg,
[Alias("da","db-alg")][string]$DbAlg
@@ -20,9 +17,9 @@ if ($ShowHelp) {
Write-Host " [-h | -help] Prints this help message."
Write-Host " [-sp | -skip-pki] Skips the pki setup of the setup script."
Write-Host " [-sb | -skip-db] Skips the database setup of the setup script."
- Write-Host " [-aa | -aca-alg] Sets the ACA's default algorithm (RSA, ECC, or MLDSA) for Attestation Certificates."
- Write-Host " [-ta | -tls-alg] Sets the ACA's default algorithm (RSA, ECC, or MLDSA) for TLS on the ACA portal."
- Write-Host " [-da | -db-alg] Sets the ACA's default algorithm (RSA, ECC, or MLDSA) for use with MariaDB."
+ Write-Host " [-aa | -aca-alg] Sets the ACA's default algorithm (rsa, ecc, or mldsa) for Attestation Certificates."
+ Write-Host " [-ta | -tls-alg] Sets the ACA's default algorithm (rsa, ecc, or mldsa) for TLS on the ACA portal."
+ Write-Host " [-da | -db-alg] Sets the ACA's default algorithm (rsa, ecc, or mldsa) for use with MariaDB."
exit 1
}
@@ -141,49 +138,52 @@ if (-not (Test-Path $global:HIRS_DATA_SPRING_PROP_FILE)) {
Write-Output "File already exists: $global:HIRS_DATA_SPRING_PROP_FILE" | WriteAndLog
}
-read_spring_properties $global:HIRS_DATA_SPRING_PROP_FILE
+read_spring_properties -file "$global:HIRS_DATA_SPRING_PROP_FILE"
# Runs the pki_setup script (along with the other scripts under the PKI folder)
-# if (!$skippki) {
-# if (!$Env:HIRS_PKI_PWD) {
-# $HIRS_PKI_PWD=(create_random)
-# # NOTE: Writing to the environment variable did not work within the container
-# # This password will be stored in the ACA properties file.
-# Write-Output "Using randomly generated password for the PKI key password" | WriteAndLog
-# Write-Host "NOT LOGGED: Using pki password=$HIRS_PKI_PWD"
-# } else {
-# $HIRS_PKI_PWD=$Env:HIRS_PKI_PWD
-# Write-Output "Using system supplied password for the PKI key password" | WriteAndLog
-# }
-# pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_PKI_SETUP -LOG_FILE:"$global:LOG_FILE" -PKI_PASS:"$HIRS_PKI_PWD" -UNATTENDED:"$IsUnattended"
-# if ($LastExitCode -eq 0) {
-# Write-Output "ACA PKI setup complete" | WriteAndLog
-# } else {
-# Write-Output "Error setting up ACA PKI" | WriteAndLog
-# exit 1
-# }
-# } else {
-# Write-Output ("ACA PKI setup cannot be run because there are command line argument(s): "+($PSBoundParameters.Keys | Where-Object { $_ -match 'skip-pki|sp' } )) | WriteAndLog
-# }
-
-# # Runs the create_db script (along with the other scripts under the DB folder)
-# if (!$skipdb) {
-# pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_DB_CREATE -LOG_FILE:"$global:LOG_FILE" -UNATTENDED:"$IsUnattended"
-# if ($LastExitCode -eq 0) {
-# Write-Output "ACA database setup complete" | WriteAndLog
-# } else {
-# Write-Output "Error setting up ACA DB" | WriteAndLog
-# exit 1
-# }
-# } else {
-# Write-Output ("ACA Database setup cannot be run because there are command line argument(s): "+($PSBoundParameters.Keys | Where-Object { $_ -match 'skip-db|sd'})) | WriteAndLog
-# }
+if (!$skippki) {
+ if (!$Env:HIRS_PKI_PWD) {
+ $HIRS_PKI_PWD=(create_random)
+ # NOTE: Writing to the environment variable did not work within the container
+ # This password will be stored in the ACA properties file.
+ Write-Output "Using randomly generated password for the PKI key password" | WriteAndLog
+ Write-Host "NOT LOGGED: Using pki password=$HIRS_PKI_PWD"
+ } else {
+ $HIRS_PKI_PWD=$Env:HIRS_PKI_PWD
+ Write-Output "Using system supplied password for the PKI key password" | WriteAndLog
+ }
+ pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_PKI_SETUP -LOG_FILE "$global:LOG_FILE" -PKI_PASS "$HIRS_PKI_PWD"
+ if ($LastExitCode -eq 0) {
+ Write-Output "ACA PKI setup complete" | WriteAndLog
+ } else {
+ Write-Output "Error setting up ACA PKI" | WriteAndLog
+ exit 1
+ }
+} else {
+ Write-Output ("ACA PKI setup cannot be run because there are command line argument(s): "+($PSBoundParameters.Keys | Where-Object { $_ -match 'skip-pki|sp' } )) | WriteAndLog
+}
+
+# Runs the create_db script (along with the other scripts under the DB folder)
+if (!$skipdb) {
+ pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_DB_CREATE -LOG_FILE "$global:LOG_FILE" -UNATTENDED:$IsUnattended -DB_ALG "$DbAlg"
+ if ($LastExitCode -eq 0) {
+ Write-Output "ACA database setup complete" | WriteAndLog
+ } else {
+ Write-Output "Error setting up ACA DB" | WriteAndLog
+ exit 1
+ }
+} else {
+ Write-Output ("ACA Database setup cannot be run because there are command line argument(s): "+($PSBoundParameters.Keys | Where-Object { $_ -match 'skip-db|sd'})) | WriteAndLog
+}
# Update properties file based upon algorithm choices
Write-Host "Setting public key algorithm for TLS and ACA..."
-setup_tls_config_aliases -tlsAlg $TlsAlg
-setup_aca_public_key_algorithm -acaAlg $AcaAlg
+# setup the tls configuration using the provided public key algorithm
+setup_tls_config_aliases -tlsAlg "$TlsAlg"
+
+# setup the aca using the provided public key algorithm
+setup_aca_public_key_algorithm -acaAlg "$AcaAlg"
Write-Output "ACA setup complete" | WriteAndLog
Write-Host "----------------------------------------------------------------------"
diff --git a/package/win/db/db_create.ps1 b/package/win/db/db_create.ps1
index 07b249401..4bc0abf19 100644
--- a/package/win/db/db_create.ps1
+++ b/package/win/db/db_create.ps1
@@ -10,7 +10,9 @@
param (
[Parameter(Mandatory=$true)]
[string]$LOG_FILE,
- [switch]$unattended = $false
+ [switch]$UNATTENDED = $false,
+ [Parameter(Mandatory=$true)]
+ [string]$DB_ALG
)
$ACA_SCRIPTS_HOME=(Split-Path -parent $PSCommandPath)
@@ -21,10 +23,10 @@ $ACA_COMMON_SCRIPT=(Join-Path "$ACA_SCRIPTS_HOME" .. aca aca_common.ps1)
. $global:HIRS_REL_WIN_DB_MYSQL_UTIL
# Read aca.properties
-read_aca_properties $global:HIRS_DATA_ACA_PROPERTIES_FILE
+read_aca_properties -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE"
# Read spring application.properties
-read_spring_properties $global:HIRS_DATA_SPRING_PROP_FILE
+read_spring_properties -file "$global:HIRS_DATA_SPRING_PROP_FILE"
# Parameter check
if (-not (Test-Path -Path $LOG_FILE)) {
@@ -46,7 +48,6 @@ if (-not (Test-Path -Path $global:DB_CONF)) {
Write-Output "File already exists: $global:DB_CONF"
}
-
# Make sure required paths exist
New-Item -ItemType Directory -Path $global:HIRS_CONF_DIR -Force | Out-Null
New-Item -ItemType Directory -Path $global:HIRS_DATA_LOG_DIR -Force | Out-Null
@@ -65,7 +66,7 @@ Function check_mysql_root_pwd () {
Write-Output "Using randomly generated password for the DB admin" | WriteAndLog
# Attempt to find the mysql password from the aca property file
- $DB_ADMIN_PWD=find_property_value -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME"
+ $DB_ADMIN_PWD=find_property_value -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME"
# if the value associated with the mysql_admin_password key is empty
if(!$DB_ADMIN_PWD) {
@@ -77,16 +78,16 @@ Function check_mysql_root_pwd () {
Write-Host "NOT LOGGED: DB Admin password will be set to [$DB_ADMIN_PWD]. Please make note of it for future uses of MYSQL."
# Check if unattended flag is set if not then prompt user for permission to store mysql root password
- if (!$unattended) {
+ if (!$UNATTENDED) {
$confirm=Read-Host 'Do you wish to save this password to the aca.properties file?'
if (($confirm -eq "y") -or ($confirm -eq "yes")) { # case-insensitive
- add_new_aca_property -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue:"$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME=$DB_ADMIN_PWD"
+ add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME=$DB_ADMIN_PWD"
Write-Output "A new MYSQL password for the root user has been saved locally." | WriteAndLog
} else {
Write-Output "MYSQL password for the root user has not been saved locally" | WriteAndLog
}
} else { # unattended install
- add_new_aca_property -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue:"$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME=$DB_ADMIN_PWD"
+ add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME=$DB_ADMIN_PWD"
Write-Output "A new MYSQL password for the root user has been saved locally." | WriteAndLog
}
mysqladmin --user=root password "$DB_ADMIN_PWD"
@@ -111,18 +112,37 @@ Function check_mysql_root_pwd () {
}
Function set_mysql_tls () {
+ param (
+ [Parameter(Mandatory=$true)]
+ [string]$ALG
+ )
+
# Check DB server setup. If ssl params dont exist then we need to add them.
if (!(Get-Content $global:DB_CONF | Select-String "ssl")) {
- # Add TLS files to my.ini- Assumes [client] section at the end, and no [server] section
- Write-Output "Updating $global:DB_CONF with ssl parameters..." | WriteAndLog
- Write-Output "ssl_ca=$SSL_DB_RSA_CLIENT_CHAIN" >> $global:DB_CONF
- Write-Output "ssl_cert=$SSL_DB_RSA_CLIENT_CERT" >> $global:DB_CONF
- Write-Output "ssl_key=$SSL_DB_RSA_CLIENT_KEY" >> $global:DB_CONF
- Write-Output "[server]" >> $global:DB_CONF
- Write-Output "ssl_ca=$global:SSL_DB_RSA_SRV_CHAIN" >> $global:DB_CONF
- Write-Output "ssl_cert=$global:SSL_DB_RSA_SRV_CERT" >> $global:DB_CONF
- Write-Output "ssl_key=$global:SSL_DB_RSA_SRV_KEY" >> $global:DB_CONF
- ChangeFileBackslashToForwardSlash $global:DB_CONF
+
+ Write-Output "Updating $global:DB_CONF with $ALG ssl parameters..." | WriteAndLog
+ if($ALG -eq "rsa"){
+ # Add RSA TLS files to my.ini- Assumes [client] section at the end, and no [server] section
+ Write-Output "ssl_ca=$SSL_DB_RSA_CLIENT_CHAIN" >> $global:DB_CONF
+ Write-Output "ssl_cert=$SSL_DB_RSA_CLIENT_CERT" >> $global:DB_CONF
+ Write-Output "ssl_key=$SSL_DB_RSA_CLIENT_KEY" >> $global:DB_CONF
+ Write-Output "[server]" >> $global:DB_CONF
+ Write-Output "ssl_ca=$global:SSL_DB_RSA_SRV_CHAIN" >> $global:DB_CONF
+ Write-Output "ssl_cert=$global:SSL_DB_RSA_SRV_CERT" >> $global:DB_CONF
+ Write-Output "ssl_key=$global:SSL_DB_RSA_SRV_KEY" >> $global:DB_CONF
+ }
+ elseif ($AlG -eq "ecc") {
+ # Add ECC TLS files to my.ini- Assumes [client] section at the end, and no [server] section
+ Write-Output "ssl_ca=$SSL_DB_ECC_CLIENT_CHAIN" >> $global:DB_CONF
+ Write-Output "ssl_cert=$SSL_DB_ECC_CLIENT_CERT" >> $global:DB_CONF
+ Write-Output "ssl_key=$SSL_DB_ECC_CLIENT_KEY" >> $global:DB_CONF
+ Write-Output "[server]" >> $global:DB_CONF
+ Write-Output "ssl_ca=$global:SSL_DB_ECC_SRV_CHAIN" >> $global:DB_CONF
+ Write-Output "ssl_cert=$global:SSL_DB_ECC_SRV_CERT" >> $global:DB_CONF
+ Write-Output "ssl_key=$global:SSL_DB_ECC_SRV_KEY" >> $global:DB_CONF
+ }
+
+ ChangeFileBackslashToForwardSlash -file $global:DB_CONF
} else {
Write-Output "$global:DB_CONF contains existing entry for ssl. Skipping this step ..." | WriteAndLog
}
@@ -153,23 +173,23 @@ Function set_hirs_db_pwd () {
Write-Output "Using randomly generated password for the HIRS_DB key password" | WriteAndLog
}
- if(-not (find_property_value -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_HIRS_DB_USERNAME_PROPERTY_NAME")){
- add_new_aca_property -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue:"$global:ACA_PROPERTIES_HIRS_DB_USERNAME_PROPERTY_NAME=hirs_db"
+ if(-not (find_property_value -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_HIRS_DB_USERNAME_PROPERTY_NAME")){
+ add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_HIRS_DB_USERNAME_PROPERTY_NAME=hirs_db"
Write-Output "Stored hirs_db username in the ACA properties file [$global:HIRS_DATA_ACA_PROPERTIES_FILE]" | WriteAndLog
}
- if(-not (find_property_value -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME")){
- add_new_aca_property -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue:"$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME=$HIRS_DB_PASS"
+ if(-not (find_property_value -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME")){
+ add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME=$HIRS_DB_PASS"
Write-Output "Stored hirs_db password in the ACA properties file [$global:HIRS_DATA_ACA_PROPERTIES_FILE]" | WriteAndLog
}
- if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME")){
- add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME=hirs_db"
+ if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME")){
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME=hirs_db"
Write-Output "Stored the hibernate connection username in the spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
}
- if(-not (find_property_value -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME")){
- add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME=$HIRS_DB_PASS"
+ if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME")){
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME=$HIRS_DB_PASS"
Write-Output "Stored the hibernate connection password property in the spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
}
}
@@ -190,13 +210,13 @@ Function create_hirs_db_with_tls () {
exit 1
}
- $HIRS_DB_EXISTS = check_hirs_db -DB_ADMIN_PWD:"$DB_ADMIN_PWD"
+ $HIRS_DB_EXISTS = check_hirs_db -DB_ADMIN_PWD "$DB_ADMIN_PWD"
#if the hirs_db has already been created, skip this step
if($HIRS_DB_EXISTS -eq 1){
Write-Output "hirs_db already exists. Skipping this step" | WriteAndLog
} else { #othewrise create the hirs_db
- $HIRS_PASS=find_property_value -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key:$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME
+ $HIRS_PASS=find_property_value -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME"
if(!$HIRS_PASS){
Write-Output "Exiting script since the property file does not have the hirs_db password" | WriteAndLog
@@ -228,11 +248,11 @@ Function create_hibernate_url () {
$CONNECTOR_URL="hibernate.connection.url=jdbc:mariadb://localhost:3306/hirs_db?autoReconnect=true&user="+$global:ACA_PROPERTIES.'hirs_db_username'+"&password="+$global:ACA_PROPERTIES.'hirs_db_password'+"&sslMode=VERIFY_CA&serverSslCert=$CERT_CHAIN&keyStoreType=PKCS12&keyStorePassword="+$global:ACA_PROPERTIES.'hirs_pki_password'+"&keyStore=$CLIENT_DB_P12" | ChangeBackslashToForwardSlash
# Save connector information to the application win properties file
- add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$CONNECTOR_URL"
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$CONNECTOR_URL"
}
# Setup the ssl settings in the my.ini settings file that's in the C:\\Program Files\MariaDB 11.1\data directory
-set_mysql_tls
+set_mysql_tls -ALG "$DB_ALG"
# Start the MariaDB service
start_mysqlsd -p
@@ -241,13 +261,13 @@ start_mysqlsd -p
$DB_ADMIN_PWD=check_mysql_root_pwd
# Set the password for the hirs_db user in the aca properties and spring properties files
-set_hirs_db_pwd -DB_ADMIN_PWD:"$DB_ADMIN_PWD"
+set_hirs_db_pwd -DB_ADMIN_PWD "$DB_ADMIN_PWD"
# Create the hirs_db and hirs_db user with the values that were set in the aca properties file
-create_hirs_db_with_tls -DB_ADMIN_PWD:"$DB_ADMIN_PWD"
+create_hirs_db_with_tls -DB_ADMIN_PWD "$DB_ADMIN_PWD"
-# Create the hibernate url using the RSA algorithm and set the url in the aca.properties file
-create_hibernate_url -ALG:"RSA"
+# Create the hibernate url using the provided public key algorithm and set the url in the aca.properties file
+create_hibernate_url -ALG "$DB_ALG"
# Reboot mariadb service
mysqld_reboot -p
\ No newline at end of file
diff --git a/package/win/pki/pki_setup.ps1 b/package/win/pki/pki_setup.ps1
index 67167e809..ea7453fa2 100644
--- a/package/win/pki/pki_setup.ps1
+++ b/package/win/pki/pki_setup.ps1
@@ -10,8 +10,7 @@ param (
[Parameter(Mandatory=$true)]
[string]$LOG_FILE,
[Parameter(Mandatory=$true)]
- [string]$PKI_PASS,
- [switch]$UNATTENDED = $false
+ [string]$PKI_PASS
)
$ACA_SCRIPTS_HOME=(Split-Path -parent $PSCommandPath)
@@ -21,10 +20,10 @@ $ACA_COMMON_SCRIPT=(Join-Path "$ACA_SCRIPTS_HOME" .. aca aca_common.ps1)
. $ACA_COMMON_SCRIPT
# Read aca.properties
-read_aca_properties $global:HIRS_DATA_ACA_PROPERTIES_FILE
+read_aca_properties -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE"
# Read spring application.properties
-read_spring_properties $global:HIRS_DATA_SPRING_PROP_FILE
+read_spring_properties -file "$global:HIRS_DATA_SPRING_PROP_FILE"
# Parameter check
if (-not (Test-Path -Path $LOG_FILE)) {
@@ -70,11 +69,11 @@ if (![System.IO.Directory]::Exists($global:HIRS_DATA_CERTIFICATES_DIR)) {
pwsh -ExecutionPolicy Bypass $PKI_SETUP_DIR/pki_chain_gen.ps1 "HIRS" "ecc" "512" "sha384" "$PKI_PASS" "$global:LOG_FILE"
# Save the password to the ACA properties file.
- add_new_aca_property -file:"$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue:"$global:ACA_PROPERTIES_PKI_PWD_PROPERTY_NAME=$PKI_PASS"
+ add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_PKI_PWD_PROPERTY_NAME=$PKI_PASS"
# Save connector information to the application properties file.
- add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_SSL_KEY_STORE_PWD_PROPERTY_NAME=$PKI_PASS"
- add_new_spring_property -file:"$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue:"$global:SPRING_PROPERTIES_SSL_KEY_TRUST_STORE_PWD_PROPERTY_NAME=$PKI_PASS"
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_SSL_KEY_STORE_PWD_PROPERTY_NAME=$PKI_PASS"
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_SSL_KEY_TRUST_STORE_PWD_PROPERTY_NAME=$PKI_PASS"
} else {
Write-Output "$global:HIRS_DATA_CERTIFICATES_DIR exists, skipping" | WriteAndLog
}
From 1c796c55f249012fc3c2decf2d739cabf7f130cc Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Thu, 12 Mar 2026 12:52:27 -0400
Subject: [PATCH 18/25] Piped output of write-output to WriteAndLog function
---
package/win/aca/aca_common.ps1 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package/win/aca/aca_common.ps1 b/package/win/aca/aca_common.ps1
index 4d45d4295..7b1b5a0fe 100644
--- a/package/win/aca/aca_common.ps1
+++ b/package/win/aca/aca_common.ps1
@@ -338,7 +338,7 @@ Function remove_spring_property_value_pair(){
# Write back to the file (overwrite)
Set-Content -Path $File -Value $filteredLines
- Write-Output "Removed property [$KeyToBeDeleted] from file [$File]."
+ Write-Output "Removed property [$KeyToBeDeleted] from file [$File]." | WriteAndLog
# Reset the global spring property hashmap and reload
$global:SPRING_PROPERTIES = $null
From 35be59666622a3df41c6d687d3ba22463cded8df Mon Sep 17 00:00:00 2001
From: 5B96790E3664F40075A67E6ADF737EDB15B4408DBC91A81228B31537B0CE3E26
<33426478+iadgovuser29@users.noreply.github.com>
Date: Fri, 13 Mar 2026 05:19:49 -0400
Subject: [PATCH 19/25] MSBuild should build msi on fips systems; better
version reporting (#1132)
---
.../hirs/Directory.Build.targets | 18 ++++++++++++++++++
.../hirs/HIRS_Provisioner.NET.csproj | 7 +++++--
HIRS_Provisioner.NET/hirs/src/Program.cs | 5 ++++-
3 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/HIRS_Provisioner.NET/hirs/Directory.Build.targets b/HIRS_Provisioner.NET/hirs/Directory.Build.targets
index c3cf55e97..06cf1b8ab 100644
--- a/HIRS_Provisioner.NET/hirs/Directory.Build.targets
+++ b/HIRS_Provisioner.NET/hirs/Directory.Build.targets
@@ -18,13 +18,31 @@
+ <_WindowsFipsEnabled>false
+
+ <_WindowsFipsEnabled Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' And '$([MSBuild]::GetRegistryValue(`HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy`,`Enabled`,`0`))' == '1'">true
+
+ $(_WindowsFipsEnabled)
+
$(MSBuildThisFileDirectory)\Resources\Product.wxs
$(NuGetPackageRoot)wix\3.14.1\tools\
$(WixInstallPath)heat.exe
$(WixInstallPath)candle.exe
$(WixInstallPath)light.exe
+ $(TargetDir)$(AssemblyName).$(PackageVersion).msi
+ -fips
+
+
+ -nologo -dPublishDir="$(PublishDir)\" -dSetupProductName="$(SetupProductName)" -dSetupProductManufacturer="HIRS" -dSetupFeatureId="$(SetupFeatureId)" -dSetupFeatureName="$(SetupFeatureName)" -dSetupInstallFolderName="$(SetupInstallFolderName)" -dSetupProductVersion="$(Version)" -dSetupProductLanguage="$(SetupProductLanguage)"
+
+
+
+
+
+
+
diff --git a/HIRS_Provisioner.NET/hirs/HIRS_Provisioner.NET.csproj b/HIRS_Provisioner.NET/hirs/HIRS_Provisioner.NET.csproj
index d08ccdc8f..a6227c5ae 100644
--- a/HIRS_Provisioner.NET/hirs/HIRS_Provisioner.NET.csproj
+++ b/HIRS_Provisioner.NET/hirs/HIRS_Provisioner.NET.csproj
@@ -9,8 +9,10 @@
true
enable
enable
- 3.1.0
-
+ 3.2.0
+ $(Version)
+
+ true
@@ -30,6 +32,7 @@
all
+
diff --git a/HIRS_Provisioner.NET/hirs/src/Program.cs b/HIRS_Provisioner.NET/hirs/src/Program.cs
index c5a67e56a..a6845ff11 100644
--- a/HIRS_Provisioner.NET/hirs/src/Program.cs
+++ b/HIRS_Provisioner.NET/hirs/src/Program.cs
@@ -2,13 +2,16 @@
using Serilog;
using System;
using System.Collections.Generic;
+using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Threading.Tasks;
namespace hirs {
class Program {
- public static readonly string VERSION = "17";
+ public static readonly string VERSION = typeof(Program).Assembly
+ .GetCustomAttribute()?
+ .InformationalVersion;
static async Task Main(string[] args) {
ClientExitCodes result = 0;
From 335c42c2570ccb899368d527c605c8b48f15153f Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Fri, 13 Mar 2026 17:55:56 -0400
Subject: [PATCH 20/25] v3.1_issue_1127: Created a new service class for the
tpm state. Refactoring the cert request processor service. Refactored PS
setup script and formatted ps1 scripts. Will work on the method that takes ak
and ek ecc key and should be done with draft PR.
---
.../entity/tpm/TPM2ProvisionerState.java | 38 +-
.../CertificateRequestProcessorService.java | 38 +-
.../service/DeviceInfoProcessorService.java | 4 +-
.../IdentityClaimProcessorService.java | 20 +-
.../service/Tpm2ProvisionerStateService.java | 70 +++
...a => TPM2ProvisionerStateServiceTest.java} | 106 +++--
package/win/aca/aca_bootRun.ps1 | 64 +--
package/win/aca/aca_check_setup.ps1 | 110 ++---
package/win/aca/aca_common.ps1 | 405 ++++++++----------
package/win/aca/aca_remove_setup.ps1 | 54 +--
package/win/aca/aca_setup.ps1 | 189 +++++---
package/win/aca/aca_win_config.ps1 | 4 +-
package/win/db/db_create.ps1 | 308 ++++++-------
package/win/db/db_drop.ps1 | 14 +-
package/win/pki/pki_chain_gen.ps1 | 358 ++++++++--------
package/win/pki/pki_setup.ps1 | 56 +--
.../create_hirstools_desktop_shortcut.ps1 | 2 +-
package/win/tcg-rim-tool/eventLog.ps1 | 2 +-
package/win/tcg-rim-tool/hirsshell.ps1 | 2 +-
package/win/tcg-rim-tool/rim.ps1 | 2 +-
20 files changed, 966 insertions(+), 880 deletions(-)
create mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/Tpm2ProvisionerStateService.java
rename HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/tpm/{TPM2ProvisionerStateTest.java => TPM2ProvisionerStateServiceTest.java} (60%)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerState.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerState.java
index 6a6a4f72d..c0c2ac584 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerState.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerState.java
@@ -1,6 +1,5 @@
package hirs.attestationca.persist.entity.tpm;
-import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
@@ -15,8 +14,7 @@
import java.util.Date;
/**
- * This class is for saving the Identity Claim and the Nonce between the two passes of the
- * TPM 2.0 Provisioner.
+ * This class is for saving the Identity Claim and the Nonce between the two passes of the TPM 2.0 Provisioner.
*/
@Log4j2
@NoArgsConstructor
@@ -24,6 +22,9 @@
public class TPM2ProvisionerState {
private static final int MAX_BLOB_SIZE = 16777215;
+ @Column(nullable = false)
+ private final Date timestamp = new Date();
+
@Id
private Long firstPartOfNonce;
@@ -34,9 +35,6 @@ public class TPM2ProvisionerState {
@Column(nullable = false, length = MAX_BLOB_SIZE)
private byte[] identityClaim;
- @Column(nullable = false)
- private final Date timestamp = new Date();
-
/**
* Constructor.
*
@@ -69,34 +67,6 @@ public TPM2ProvisionerState(final byte[] nonce, final byte[] identityClaim) {
}
}
- /**
- * Convenience method for finding the {@link TPM2ProvisionerState} associated with the nonce.
- *
- * @param tpm2ProvisionerStateRepository the {@link TPM2ProvisionerStateRepository}
- * to use when looking for the
- * {@link TPM2ProvisionerState}
- * @param nonce the nonce to use as the key for the {@link TPM2ProvisionerState}
- * @return the {@link TPM2ProvisionerState} associated with the nonce;
- * null if a match is not found
- */
- public static TPM2ProvisionerState getTPM2ProvisionerState(
- final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
- final byte[] nonce) {
- try (DataInputStream dis
- = new DataInputStream(new ByteArrayInputStream(nonce))) {
- long firstPartOfNonce = dis.readLong();
- TPM2ProvisionerState stateFound = tpm2ProvisionerStateRepository
- .findByFirstPartOfNonce(firstPartOfNonce);
- if (stateFound != null && Arrays.areEqual(stateFound.getNonce(), nonce)) {
- return stateFound;
- }
- } catch (IOException ioEx) {
- log.error(ioEx.getMessage());
- return null;
- }
- return null;
- }
-
/**
* Get the nonce.
*
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
index cfbc93605..bb270ccf8 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
@@ -5,7 +5,6 @@
import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
import hirs.attestationca.persist.entity.manager.DeviceRepository;
import hirs.attestationca.persist.entity.manager.PolicyRepository;
-import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository;
import hirs.attestationca.persist.entity.tpm.TPM2ProvisionerState;
import hirs.attestationca.persist.entity.userdefined.Device;
import hirs.attestationca.persist.entity.userdefined.PolicySettings;
@@ -58,8 +57,8 @@
public class CertificateRequestProcessorService {
private final SupplyChainValidationService supplyChainValidationService;
private final CredentialManagementService credentialManagementService;
+ private final Tpm2ProvisionerStateService tpm2ProvisionerStateService;
private final DeviceRepository deviceRepository;
- private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
private final PolicyRepository policyRepository;
private final X509Certificate acaCertificate;
private final int certificateValidityInDays;
@@ -68,31 +67,31 @@ public class CertificateRequestProcessorService {
/**
* Constructor.
*
- * @param supplyChainValidationService object that is used to run provisioning
- * @param credentialManagementService credential management service
- * @param deviceRepository database connector for Devices.
- * @param tpm2ProvisionerStateRepository db connector for provisioner state.
- * @param policyRepository db connector for policies.
- * @param privateKey private key used for communication authentication
- * @param acaCertificate object used to create credential
- * @param certificateValidityInDays int for the time in which a certificate is valid.
+ * @param supplyChainValidationService object that is used to run provisioning
+ * @param credentialManagementService credential management service
+ * @param tpm2ProvisionerStateService tpm2 provisioner state service
+ * @param deviceRepository database connector for Devices.
+ * @param policyRepository db connector for policies.
+ * @param privateKey private key used for communication authentication
+ * @param acaCertificate object used to create credential
+ * @param certificateValidityInDays int for the time in which a certificate is valid.
*/
@Autowired
public CertificateRequestProcessorService(final SupplyChainValidationService supplyChainValidationService,
final CredentialManagementService credentialManagementService,
+ final Tpm2ProvisionerStateService tpm2ProvisionerStateService,
final DeviceRepository deviceRepository,
- final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
final PolicyRepository policyRepository,
final PrivateKey privateKey,
@Qualifier("leafACACert") final X509Certificate acaCertificate,
@Value("${aca.certificates.validity}") final int certificateValidityInDays
) {
this.credentialManagementService = credentialManagementService;
+ this.tpm2ProvisionerStateService = tpm2ProvisionerStateService;
this.certificateValidityInDays = certificateValidityInDays;
this.supplyChainValidationService = supplyChainValidationService;
this.deviceRepository = deviceRepository;
this.acaCertificate = acaCertificate;
- this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
this.policyRepository = policyRepository;
this.privateKey = privateKey;
}
@@ -197,7 +196,7 @@ public byte[] processCertificateRequest(final byte[] certificateRequestByteArray
ldevidCertificate);
// We validated the nonce and made use of the identity claim so state can be deleted
- tpm2ProvisionerStateRepository.delete(tpm2ProvisionerState);
+ tpm2ProvisionerStateService.deleteTPM2ProvisionerState(tpm2ProvisionerState);
boolean generateAtt =
credentialManagementService.saveAttestationCertificate(derEncodedAttestationCertificate,
@@ -260,7 +259,7 @@ public byte[] processCertificateRequest(final byte[] certificateRequestByteArray
attestationCertificate);
// We validated the nonce and made use of the identity claim so state can be deleted
- tpm2ProvisionerStateRepository.delete(tpm2ProvisionerState);
+ tpm2ProvisionerStateService.deleteTPM2ProvisionerState(tpm2ProvisionerState);
ProvisionerTpm2.CertificateResponse.Builder certificateResponseBuilder =
ProvisionerTpm2.CertificateResponse.
@@ -409,14 +408,13 @@ private Device retrieveDeviceWithUpdatedTPMInfo(final ProvisionerTpm2.Certificat
* Helper method to unwrap the certificate request sent by the client and verify the
* provided nonce.
*
- * @param request Client Certificate Request containing nonce to complete identity claim
+ * @param certificateRequest Client Certificate Request containing nonce to complete identity claim
* @return the {@link TPM2ProvisionerState} if valid nonce provided / null, otherwise
*/
- private TPM2ProvisionerState getTpm2ProvisionerState(final ProvisionerTpm2.CertificateRequest request) {
- if (request.hasNonce()) {
- byte[] nonce = request.getNonce().toByteArray();
- return TPM2ProvisionerState.getTPM2ProvisionerState(tpm2ProvisionerStateRepository,
- nonce);
+ private TPM2ProvisionerState getTpm2ProvisionerState(final ProvisionerTpm2.CertificateRequest certificateRequest) {
+ if (certificateRequest.hasNonce()) {
+ byte[] nonce = certificateRequest.getNonce().toByteArray();
+ return tpm2ProvisionerStateService.getTPM2ProvisionerState(nonce);
}
return null;
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
index 06047a6e5..4259c1b31 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
@@ -171,7 +171,7 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim ide
// Get Hardware info
HardwareInfo hardwareInfo = getHardwareInfo(provisionedDeviceInfo.getHw());
- // Get TPM info ( todo Currently unimplemented)
+ // Get TPM info (todo Currently unimplemented)
TPMInfo tpmInfo = getTPMInfo(provisionedDeviceInfo);
// Get Network info
@@ -195,7 +195,7 @@ private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim ide
/**
* Helper method that creates a {@link TPMInfo} object using the provided provisioned Device Info.
- * ( todo Currently unimplemented)
+ * (todo Currently unimplemented)
*
* @param provisionedDeviceInfo provisioned Device Info
* @return the {@link TPMInfo} object representing the Device's TPM Info
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
index a55c12e7c..00b0fa6dc 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
@@ -5,7 +5,6 @@
import com.google.protobuf.util.JsonFormat;
import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2;
import hirs.attestationca.persist.entity.manager.PolicyRepository;
-import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository;
import hirs.attestationca.persist.entity.tpm.TPM2ProvisionerState;
import hirs.attestationca.persist.entity.userdefined.Device;
import hirs.attestationca.persist.entity.userdefined.PolicySettings;
@@ -42,29 +41,29 @@ public class IdentityClaimProcessorService {
private final SupplyChainValidationService supplyChainValidationService;
private final CredentialManagementService credentialManagementService;
private final DeviceInfoProcessorService deviceInfoProcessorService;
+ private final Tpm2ProvisionerStateService tpm2ProvisionerStateService;
private final PolicyRepository policyRepository;
- private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
/**
* Constructor.
*
- * @param supplyChainValidationService supply chain validation service
- * @param credentialManagementService certificate processor service
- * @param deviceInfoProcessorService device info processor service
- * @param tpm2ProvisionerStateRepository tpm2 provisioner state repository
- * @param policyRepository policy repository
+ * @param supplyChainValidationService supply chain validation service
+ * @param credentialManagementService certificate processor service
+ * @param deviceInfoProcessorService device info processor service
+ * @param tpm2ProvisionerStateService tpm2 provisioner state service
+ * @param policyRepository policy repository
*/
@Autowired
public IdentityClaimProcessorService(
final SupplyChainValidationService supplyChainValidationService,
final CredentialManagementService credentialManagementService,
final DeviceInfoProcessorService deviceInfoProcessorService,
- final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository,
+ final Tpm2ProvisionerStateService tpm2ProvisionerStateService,
final PolicyRepository policyRepository) {
this.supplyChainValidationService = supplyChainValidationService;
this.credentialManagementService = credentialManagementService;
this.deviceInfoProcessorService = deviceInfoProcessorService;
- this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
+ this.tpm2ProvisionerStateService = tpm2ProvisionerStateService;
this.policyRepository = policyRepository;
}
@@ -125,7 +124,8 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaimByteArray) {
log.info("Sending nonce: {}", strNonce);
log.info("Persisting identity claim of length: {}", identityClaimByteArray.length);
- tpm2ProvisionerStateRepository.save(new TPM2ProvisionerState(nonce, identityClaimByteArray));
+ tpm2ProvisionerStateService.saveTPM2ProvisionerState(
+ new TPM2ProvisionerState(nonce, identityClaimByteArray));
if (policySettings.isIgnoreImaEnabled()) {
pcrQuoteMask = PCR_QUOTE_MASK.replace("10,", "");
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/Tpm2ProvisionerStateService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/Tpm2ProvisionerStateService.java
new file mode 100644
index 000000000..f359d7a56
--- /dev/null
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/Tpm2ProvisionerStateService.java
@@ -0,0 +1,70 @@
+package hirs.attestationca.persist.provision.service;
+
+import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository;
+import hirs.attestationca.persist.entity.tpm.TPM2ProvisionerState;
+import lombok.extern.log4j.Log4j2;
+import org.bouncycastle.util.Arrays;
+import org.springframework.stereotype.Service;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * Service class responsible for handling and processing the TPM2 Provisioner State.
+ */
+@Service
+@Log4j2
+public class Tpm2ProvisionerStateService {
+ private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
+
+ /**
+ * Constructor.
+ *
+ * @param tpm2ProvisionerStateRepository TPM2 Provisioner State Repository
+ */
+ public Tpm2ProvisionerStateService(final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository) {
+ this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
+ }
+
+ /**
+ * Retrieves the {@link TPM2ProvisionerState} object associated with the nonce.
+ *
+ * @param nonce the nonce to use as the key for the {@link TPM2ProvisionerState}
+ * @return the {@link TPM2ProvisionerState} associated with the nonce; null if a match is not found
+ */
+ public TPM2ProvisionerState getTPM2ProvisionerState(final byte[] nonce) {
+ try (DataInputStream dis = new DataInputStream(new ByteArrayInputStream(nonce))) {
+ long firstPartOfNonce = dis.readLong();
+
+ final TPM2ProvisionerState stateFound =
+ tpm2ProvisionerStateRepository.findByFirstPartOfNonce(firstPartOfNonce);
+
+ if (stateFound != null && Arrays.areEqual(stateFound.getNonce(), nonce)) {
+ return stateFound;
+ }
+ } catch (IOException ioEx) {
+ log.error(ioEx.getMessage());
+ }
+
+ return null;
+ }
+
+ /**
+ * Deletes the provided {@link TPM2ProvisionerState} object from the database.
+ *
+ * @param tpm2ProvisionerStateToBeDeleted TPM2 Provisioner State that will be deleted
+ */
+ public void deleteTPM2ProvisionerState(final TPM2ProvisionerState tpm2ProvisionerStateToBeDeleted) {
+ tpm2ProvisionerStateRepository.delete(tpm2ProvisionerStateToBeDeleted);
+ }
+
+ /**
+ * Save the provided {@link TPM2ProvisionerState} object to the database.
+ *
+ * @param tpm2ProvisionerStateToBeSaved TPM2 Provisioner State that will be saved
+ */
+ public void saveTPM2ProvisionerState(final TPM2ProvisionerState tpm2ProvisionerStateToBeSaved) {
+ tpm2ProvisionerStateRepository.save(tpm2ProvisionerStateToBeSaved);
+ }
+}
diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerStateTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerStateServiceTest.java
similarity index 60%
rename from HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerStateTest.java
rename to HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerStateServiceTest.java
index 6ce900c9d..f461e7204 100644
--- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerStateTest.java
+++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/tpm/TPM2ProvisionerStateServiceTest.java
@@ -1,7 +1,13 @@
package hirs.attestationca.persist.entity.tpm;
import hirs.attestationca.persist.entity.manager.TPM2ProvisionerStateRepository;
+import hirs.attestationca.persist.provision.service.Tpm2ProvisionerStateService;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
@@ -12,16 +18,44 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
- * Contains unit tests for {@link TPM2ProvisionerState}.
+ * Contains unit tests for {@link TPM2ProvisionerState} and {@link Tpm2ProvisionerStateService}.
*/
-public class TPM2ProvisionerStateTest {
+public class TPM2ProvisionerStateServiceTest {
private static final Random RANDOM_GENERATOR = new Random();
+ @InjectMocks
+ private Tpm2ProvisionerStateService tpm2ProvisionerStateService;
+
+ @Mock
+ private TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository;
+
+ private AutoCloseable mocks;
+
+ /**
+ * Setups configuration prior to each test method.
+ */
+ @BeforeEach
+ public void setupTests() {
+ // Initializes mocks before each test
+ mocks = MockitoAnnotations.openMocks(this);
+ }
+
+ /**
+ * Closes mocks after the completion of each test method.
+ *
+ * @throws Exception if any issues arise while closing mocks.
+ */
+ @AfterEach
+ public void afterEach() throws Exception {
+ if (mocks != null) {
+ mocks.close();
+ }
+ }
+
/**
* Tests that the values passed to the constructor are equal to the values
* returned by the getters.
@@ -36,7 +70,7 @@ public final void testTPM2ProvisionerState() {
RANDOM_GENERATOR.nextBytes(nonce);
RANDOM_GENERATOR.nextBytes(identityClaim);
- TPM2ProvisionerState state = new TPM2ProvisionerState(nonce, identityClaim);
+ final TPM2ProvisionerState state = new TPM2ProvisionerState(nonce, identityClaim);
assertArrayEquals(nonce, state.getNonce());
assertArrayEquals(identityClaim, state.getIdentityClaim());
@@ -46,7 +80,7 @@ public final void testTPM2ProvisionerState() {
* Test that the constructor throws an {@link IllegalArgumentException} when a null is
* passed in for the nonce.
*
- * @throws IllegalArgumentException this will never happen
+ * @throws IllegalArgumentException if any issues any arise while retrieving the TPM Provisioner State
*/
@Test
public final void testNullNonce() throws IllegalArgumentException {
@@ -54,15 +88,14 @@ public final void testNullNonce() throws IllegalArgumentException {
byte[] identityClaim = new byte[identityClaimSize];
RANDOM_GENERATOR.nextBytes(identityClaim);
- assertThrows(IllegalArgumentException.class, () ->
- new TPM2ProvisionerState(null, identityClaim));
+ assertThrows(IllegalArgumentException.class, () -> new TPM2ProvisionerState(null, identityClaim));
}
/**
* Test that the constructor throws an {@link IllegalArgumentException} when a null is
* passed in for the identity claim.
*
- * @throws IllegalArgumentException this will never happen
+ * @throws IllegalArgumentException if any issues any arise while retrieving the TPM Provisioner State
*/
@Test
public final void testNullIdentityClaim() throws IllegalArgumentException {
@@ -71,15 +104,14 @@ public final void testNullIdentityClaim() throws IllegalArgumentException {
RANDOM_GENERATOR.nextBytes(nonce);
- assertThrows(IllegalArgumentException.class, () ->
- new TPM2ProvisionerState(nonce, null));
+ assertThrows(IllegalArgumentException.class, () -> new TPM2ProvisionerState(nonce, null));
}
/**
* Test that the constructor throws an {@link IllegalArgumentException} when a nonce is
* passed in that is less than 8 bytes.
*
- * @throws IllegalArgumentException this will never happen
+ * @throws IllegalArgumentException if any issues any arise while retrieving the TPM Provisioner State
*/
@Test
public final void testNonceToSmall() throws IllegalArgumentException {
@@ -90,23 +122,17 @@ public final void testNonceToSmall() throws IllegalArgumentException {
RANDOM_GENERATOR.nextBytes(nonce);
RANDOM_GENERATOR.nextBytes(identityClaim);
- assertThrows(IllegalArgumentException.class, () ->
- new TPM2ProvisionerState(nonce, identityClaim));
+ assertThrows(IllegalArgumentException.class, () -> new TPM2ProvisionerState(nonce, identityClaim));
}
-
/**
- * Test that {@link TPM2ProvisionerState#getTPM2ProvisionerState(
- *TPM2ProvisionerStateRepository, byte[])} works.
- * {@link TPM2ProvisionerState#getTPM2ProvisionerState(
- *TPM2ProvisionerStateRepository, byte[])}, null is returned.
+ * Test the {@link Tpm2ProvisionerStateService#getTPM2ProvisionerState(byte[])} function call.
*
- * @throws IOException this will never happen
+ * @throws IOException if any issues any arise while retrieving the TPM Provisioner State
*/
@Test
public final void testGetTPM2ProvisionerStateNominal() throws IOException {
- TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository =
- mock(TPM2ProvisionerStateRepository.class);
+
final int nonceSize = 32;
final int identityClaimSize = 360;
byte[] nonce = new byte[nonceSize];
@@ -118,25 +144,23 @@ public final void testGetTPM2ProvisionerStateNominal() throws IOException {
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(nonce));
Long index = dis.readLong();
dis.close();
- TPM2ProvisionerState value = new TPM2ProvisionerState(nonce, identityClaim);
+
+ final TPM2ProvisionerState value = new TPM2ProvisionerState(nonce, identityClaim);
when(tpm2ProvisionerStateRepository.findByFirstPartOfNonce(index)).thenReturn(value);
- TPM2ProvisionerState tpm2ProvisionerState
- = TPM2ProvisionerState.getTPM2ProvisionerState(tpm2ProvisionerStateRepository, nonce);
+
+ final TPM2ProvisionerState tpm2ProvisionerState = tpm2ProvisionerStateService.getTPM2ProvisionerState(nonce);
assertNotNull(tpm2ProvisionerState);
assertArrayEquals(value.getIdentityClaim(), tpm2ProvisionerState.getIdentityClaim());
}
/**
* Test that if a null is passed as a nonce to
- * {@link TPM2ProvisionerState#getTPM2ProvisionerState(
- *TPM2ProvisionerStateRepository, byte[])}, null is returned.
+ * {@link Tpm2ProvisionerStateService#getTPM2ProvisionerState(byte[])}, null is returned.
*
- * @throws IOException this will never happen
+ * @throws IOException if any issues any arise while retrieving the TPM Provisioner State
*/
@Test
public final void testGetTPM2ProvisionerStateNullNonce() throws IOException {
- TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository =
- mock(TPM2ProvisionerStateRepository.class);
final int nonceSize = 32;
final int identityClaimSize = 360;
byte[] nonce = new byte[nonceSize];
@@ -148,23 +172,21 @@ public final void testGetTPM2ProvisionerStateNullNonce() throws IOException {
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(nonce));
Long index = dis.readLong();
dis.close();
- TPM2ProvisionerState value = new TPM2ProvisionerState(nonce, identityClaim);
+
+ final TPM2ProvisionerState value = new TPM2ProvisionerState(nonce, identityClaim);
when(tpm2ProvisionerStateRepository.findByFirstPartOfNonce(index)).thenReturn(value);
- assertThrows(NullPointerException.class, () ->
- TPM2ProvisionerState.getTPM2ProvisionerState(tpm2ProvisionerStateRepository, null));
+
+ assertThrows(NullPointerException.class, () -> tpm2ProvisionerStateService.getTPM2ProvisionerState(null));
}
/**
* Test that if a nonce that is less than 8 bytes is passed to
- * {@link TPM2ProvisionerState#getTPM2ProvisionerState(
- *TPM2ProvisionerStateRepository, byte[])}, null is returned.
+ * {@link Tpm2ProvisionerStateService#getTPM2ProvisionerState(byte[])}, null is returned.
*
- * @throws IOException this will never happen
+ * @throws IOException if any issues any arise while retrieving the TPM Provisioner State
*/
@Test
public final void testGetTPM2ProvisionerStateNonceTooSmall() throws IOException {
- TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository =
- mock(TPM2ProvisionerStateRepository.class);
final int nonceSize = 32;
final int identityClaimSize = 360;
byte[] nonce = new byte[nonceSize];
@@ -177,14 +199,12 @@ public final void testGetTPM2ProvisionerStateNonceTooSmall() throws IOException
Long index = dis.readLong();
dis.close();
- TPM2ProvisionerState value = new TPM2ProvisionerState(nonce, identityClaim);
+ final int nonce2Size = 7;
+ final TPM2ProvisionerState value = new TPM2ProvisionerState(nonce, identityClaim);
when(tpm2ProvisionerStateRepository.findByFirstPartOfNonce(index)).thenReturn(value);
-
- final int nonce2Size = 7;
- TPM2ProvisionerState tpm2ProvisionerState =
- TPM2ProvisionerState.getTPM2ProvisionerState(tpm2ProvisionerStateRepository,
- new byte[nonce2Size]);
+ final TPM2ProvisionerState tpm2ProvisionerState =
+ tpm2ProvisionerStateService.getTPM2ProvisionerState(new byte[nonce2Size]);
assertNull(tpm2ProvisionerState);
}
diff --git a/package/win/aca/aca_bootRun.ps1 b/package/win/aca/aca_bootRun.ps1
index b28155747..cdc981b9d 100644
--- a/package/win/aca/aca_bootRun.ps1
+++ b/package/win/aca/aca_bootRun.ps1
@@ -1,33 +1,33 @@
param (
- [Alias("p","path")][string]$PathToWarFile,
- [Alias("w","war")][switch]$UseWarFile = $false,
- [Alias("d","debug")][switch]$EnableDebugMode = $false,
- [Alias("h","help")][switch]$ShowHelp = $false
+ [Alias("p", "path")][string]$PathToWarFile,
+ [Alias("w", "war")][switch]$UseWarFile = $false,
+ [Alias("d", "debug")][switch]$EnableDebugMode = $false,
+ [Alias("h", "help")][switch]$ShowHelp = $false
)
if ($ShowHelp) {
- Write-Output " Bootrun script for the HIRS ACA"
- Write-Output " Syntax: powershell -ExecutionPolicy Bypass aca_bootRun.ps1 [-h|-p|-d|-w|-path|-war|-debug|-help]"
- Write-Output " Flag options:"
- Write-Output " [ -p | -path] Path to the HIRS_AttestationCAPortal.war file"
- Write-Output " [ -w | -war ] Use deployed war file"
- Write-Output " [ -d | -debug ] Launch the JVM with a debug port open"
- Write-Output " [ -h | -help ] Print this help menu"
- exit 1
+ Write-Output " Bootrun script for the HIRS ACA"
+ Write-Output " Syntax: powershell -ExecutionPolicy Bypass aca_bootRun.ps1 [-h|-p|-d|-w|-path|-war|-debug|-help]"
+ Write-Output " Flag options:"
+ Write-Output " [ -p | -path] Path to the HIRS_AttestationCAPortal.war file"
+ Write-Output " [ -w | -war ] Use deployed war file"
+ Write-Output " [ -d | -debug ] Launch the JVM with a debug port open"
+ Write-Output " [ -h | -help ] Print this help menu"
+ exit 1
}
-if(!(New-Object Security.Principal.WindowsPrincipal(
- [Security.Principal.WindowsIdentity]::GetCurrent())
- ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
- Write-Output "This script requires root. Please run as root"
- exit 1
+if (!(New-Object Security.Principal.WindowsPrincipal(
+[Security.Principal.WindowsIdentity]::GetCurrent())
+).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
+ Write-Output "This script requires root. Please run as root"
+ exit 1
}
-$ACA_SCRIPTS_HOME=(Split-Path -parent $PSCommandPath)
-$ACA_COMMON_SCRIPT=(Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
-$GRADLE_WRAPPER='./gradlew'
-$DEPLOYED_WAR=$null
-$DEBUG_OPTIONS='-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:9123'
+$ACA_SCRIPTS_HOME = (Split-Path -parent $PSCommandPath)
+$ACA_COMMON_SCRIPT = (Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
+$GRADLE_WRAPPER = './gradlew'
+$DEPLOYED_WAR = $null
+$DEBUG_OPTIONS = '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:9123'
# Load other scripts
. $ACA_COMMON_SCRIPT
@@ -42,41 +42,41 @@ read_aca_properties -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE"
read_spring_properties -file "$global:HIRS_DATA_SPRING_PROP_FILE"
Write-Output "-----------------------------------------------------------" | WriteAndLog
-Write-Output ("Running with these arguments: "+($PSBoundParameters | Out-String)) | WriteAndLog
+Write-Output ("Running with these arguments: " + ($PSBoundParameters | Out-String)) | WriteAndLog
if ($PathToWarFile) {
$DEPLOYED_WAR = $PathToWarFile
}
if (![System.IO.Directory]::Exists($global:HIRS_DATA_CERTIFICATES_HIRS_DIR)) {
- Write-Output "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR directory does not exist. Please run .\aca_setup.ps1 and try again."
- exit 1;
+ Write-Output "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR directory does not exist. Please run .\aca_setup.ps1 and try again."
+ exit 1;
}
if (!$DEPLOYED_WAR) {
if (-not (Test-Path -Path $GRADLE_WRAPPER -PathType Leaf)) {
Write-Output 'This script is expected to be run from the HIRS top level project directory. Exiting.'
- exit 1;
+ exit 1;
}
- $DEPLOYED_WAR='./HIRS_AttestationCAPortal/build/libs/HIRS_AttestationCAPortal.war'
+ $DEPLOYED_WAR = './HIRS_AttestationCAPortal/build/libs/HIRS_AttestationCAPortal.war'
}
-$SPRING_PROP_FILE_FORWARDSLASHES=($global:HIRS_DATA_SPRING_PROP_FILE | ChangeBackslashToForwardSlash)
+$SPRING_PROP_FILE_FORWARDSLASHES = ($global:HIRS_DATA_SPRING_PROP_FILE | ChangeBackslashToForwardSlash)
if ($UseWarFile) {
- Write-Output "Booting the ACA from a war file..." | WriteAndLog
+ Write-Output "Booting the ACA from a war file..." | WriteAndLog
if ($EnableDebugMode) {
Write-Output "... in debug"
java $DEBUG_OPTIONS -jar $DEPLOYED_WAR --spring.config.location=$SPRING_PROP_FILE_FORWARDSLASHES
} else {
- java -jar $DEPLOYED_WAR --spring.config.location=$SPRING_PROP_FILE_FORWARDSLASHES
+ java -jar $DEPLOYED_WAR --spring.config.location=$SPRING_PROP_FILE_FORWARDSLASHES
}
-} else {
+} else {
Write-Output "Booting the ACA from local build..." | WriteAndLog
if ($EnableDebugMode) {
Write-Output "... in debug"
./gradlew bootRun --args="--spring.config.location=$SPRING_PROP_FILE_FORWARDSLASHES" -Pdebug="$DEBUG_OPTIONS"
} else {
- ./gradlew bootRun --args="--spring.config.location=$SPRING_PROP_FILE_FORWARDSLASHES"
+ ./gradlew bootRun --args="--spring.config.location=$SPRING_PROP_FILE_FORWARDSLASHES"
}
}
diff --git a/package/win/aca/aca_check_setup.ps1 b/package/win/aca/aca_check_setup.ps1
index e5a98a4b0..3d584cb13 100644
--- a/package/win/aca/aca_check_setup.ps1
+++ b/package/win/aca/aca_check_setup.ps1
@@ -1,8 +1,8 @@
#This script will check to see if the ACA has already been setup in a Windows environment
param (
- [Alias("v","verbose")][switch]$ShowVerbose = $false,
- [Alias("h","help")][switch]$ShowHelp = $false
+ [Alias("v", "verbose")][switch]$ShowVerbose = $false,
+ [Alias("h", "help")][switch]$ShowHelp = $false
)
if ($ShowHelp) {
@@ -11,32 +11,32 @@ if ($ShowHelp) {
Write-Output " Flag Options:"
Write-Output " [-v | -verbose] Enables verbose output"
Write-Output " [-h | -help] Prints this help message."
- exit 1
+ exit 1
}
-if(!(New-Object Security.Principal.WindowsPrincipal(
- [Security.Principal.WindowsIdentity]::GetCurrent())
- ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
- Write-Host "This script requires root. Please run as root"
- exit 1
+if (!(New-Object Security.Principal.WindowsPrincipal(
+[Security.Principal.WindowsIdentity]::GetCurrent())
+).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
+ Write-Host "This script requires root. Please run as root"
+ exit 1
}
Write-Host "----------------------------------------------------------------------"
Write-Host ""
Write-Host "Checking HIRS ACA setup on this device..."
-$ACA_SCRIPTS_HOME=(Split-Path -parent $PSCommandPath)
-$ACA_COMMON_SCRIPT=(Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
+$ACA_SCRIPTS_HOME = (Split-Path -parent $PSCommandPath)
+$ACA_COMMON_SCRIPT = (Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
# Load other scripts
. $ACA_COMMON_SCRIPT
. $global:HIRS_REL_WIN_DB_MYSQL_UTIL
-$global:ALL_CHECKS_PASSED=$true
-$global:ALL_CERTS_PASSED=$true
+$global:ALL_CHECKS_PASSED = $true
+$global:ALL_CERTS_PASSED = $true
-Function populate_aca_properties_table{
- if(-not (Test-Path $global:HIRS_DATA_ACA_PROPERTIES_FILE)){
+Function populate_aca_properties_table {
+ if (-not (Test-Path $global:HIRS_DATA_ACA_PROPERTIES_FILE)) {
Write-Host "The ACA property files does not exist. Have you run the aca_setup.ps1 script?"
return
}
@@ -50,10 +50,10 @@ Function check_pwds() {
$aca_prop_table = populate_aca_properties_table
- if(-not $aca_prop_table){
+ if (-not $aca_prop_table) {
Write-Host "The ACA properties file does not exist. There are no passwords set for this setup"
- $PWDS_PRESENT=$false
- }else{
+ $PWDS_PRESENT = $false
+ } else {
if (-not $aca_prop_table.ContainsKey($global:ACA_PROPERTIES_PKI_PWD_PROPERTY_NAME) -or $null -eq $aca_prop_table[$global:ACA_PROPERTIES_PKI_PWD_PROPERTY_NAME]) {
Write-Host "ACA pki password not set"
$PWDS_PRESENT = $false
@@ -64,7 +64,7 @@ Function check_pwds() {
$PWDS_PRESENT = $false
}
- if (-not $aca_prop_table.ContainsKey($global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME) -or $null -eq $aca_prop_table[$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME]){
+ if (-not $aca_prop_table.ContainsKey($global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME) -or $null -eq $aca_prop_table[$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME]) {
Write-Host "hirs_db user password not set"
$PWDS_PRESENT = $false
}
@@ -74,7 +74,7 @@ Function check_pwds() {
Write-Host "All ACA passwords were found"
} else {
Write-Host "Error finding the necessary ACA passwords"
- $global:ALL_CHECKS_PASSED=$false
+ $global:ALL_CHECKS_PASSED = $false
}
}
@@ -83,12 +83,12 @@ Function check_pki() {
$aca_prop_table = populate_aca_properties_table
- if(-not (Test-Path $global:HIRS_DATA_CERTIFICATES_HIRS_DIR)){
+ if (-not (Test-Path $global:HIRS_DATA_CERTIFICATES_HIRS_DIR)) {
Write-Host "Directory for pki certificate [$global:HIRS_DATA_CERTIFICATES_HIRS_DIR] does not exist. Have you run the aca_setup.ps1 script?"
- $global:ALL_CHECKS_PASSED=$false
+ $global:ALL_CHECKS_PASSED = $false
return
}
-
+
Push-Location "$global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH" | Out-Null
check_cert -TrustStore "$global:SSL_DB_RSA_CLIENT_CHAIN" -Cert "$global:RSA_HIRS_ROOT"
check_cert -TrustStore "$global:SSL_DB_RSA_CLIENT_CHAIN" -Cert "$global:RSA_HIRS_INTERMEDIATE"
@@ -114,10 +114,10 @@ Function check_pki() {
Pop-Location | Out-Null
# if the aca properties file does not exist
- if(-not $aca_prop_table){
+ if (-not $aca_prop_table) {
Write-Host "Unable to verify the certificates validity using the pki password since the aca properties file does not exist"
- $global:ALL_CHECKS_PASSED=$false
- }else{
+ $global:ALL_CHECKS_PASSED = $false
+ } else {
# verify that the hirs_pki_password and assocaited value exist in the aca properties file
if ($aca_prop_table.ContainsKey($global:ACA_PROPERTIES_PKI_PWD_PROPERTY_NAME) -and $aca_prop_table[$global:ACA_PROPERTIES_PKI_PWD_PROPERTY_NAME]) {
# retrieve the hirs pki password
@@ -129,40 +129,40 @@ Function check_pki() {
# Verify that pki password works with the keystore
keytool -list -keystore $keyStorePath -storepass $pkiPassword | Out-Null
- if($LASTEXITCODE -eq 0){
+ if ($LASTEXITCODE -eq 0) {
Write-Host "The provided HIRS PKI password is correct for the JKS Trust Store File [$keyStorePath]"
- }else{
+ } else {
Write-Host "The provided HIRS PKI password was not correct for the JKS Trust Store File [$keyStorePath]"
$global:ALL_CERTS_PASSED = $false
}
}
}
- if($global:ALL_CERTS_PASSED){
+ if ($global:ALL_CERTS_PASSED) {
Write-Host "All RSA and ECC certificates under the certificates directory [$global:HIRS_DATA_CERTIFICATES_HIRS_DIR] are valid"
- } else{
+ } else {
Write-Host "Error: There was an error while trying to verify the validity of the RSA and ECC certificates under the certificates directory [$global:HIRS_DATA_CERTIFICATES_HIRS_DIR]"
$global:ALL_CHECKS_PASSED = $false
}
-
+
}
Function check_cert() {
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$TrustStore,
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$Cert
)
$result = openssl verify -CAfile $TrustStore $Cert
- if($LASTEXITCODE -ne 0){
- $global:ALL_CHECKS_PASSED=$false
- $global:ALL_CERTS_PASSED=$false
+ if ($LASTEXITCODE -ne 0) {
+ $global:ALL_CHECKS_PASSED = $false
+ $global:ALL_CERTS_PASSED = $false
}
- if($ShowVerbose){
+ if ($ShowVerbose) {
Write-Host "$result"
}
}
@@ -171,42 +171,42 @@ Function check_mysql_setup() {
# check if mysql is running
$DB_STATUS = check_mysql
- if(-not $DB_STATUS){
- Write-Host "MySQL is not currently running. Please start MariaDB Service before running this script."
- $global:ALL_CHECKS_PASSED = $false
- return
+ if (-not $DB_STATUS) {
+ Write-Host "MySQL is not currently running. Please start MariaDB Service before running this script."
+ $global:ALL_CHECKS_PASSED = $false
+ return
}
$aca_prop_table = populate_aca_properties_table
- if(-not $aca_prop_table){
+ if (-not $aca_prop_table) {
Write-Host "The ACA properties file does not exist. There are no passwords set for this setup"
$global:ALL_CHECKS_PASSED = $false
return
}
# Check DB server/client TLS setup
- if((Select-String -Path $DB_CONF -Pattern "HIRS").Count -lt 1){
+ if ((Select-String -Path $DB_CONF -Pattern "HIRS").Count -lt 1) {
Write-Host "Mysql server [$DB_CONF] is NOT configured for Server Side TLS"
- }else{
+ } else {
Write-Host "Mysql server [$DB_CONF] is configured for Server Side TLS"
}
- if($aca_prop_table.ContainsKey($global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME) -and $aca_prop_table[$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME]){
+ if ($aca_prop_table.ContainsKey($global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME) -and $aca_prop_table[$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME]) {
$mysqlPwd = ""
$mysqlPwd = $aca_prop_table[$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME]
mysql -u root --password=$mysqlPwd -e "STATUS;" | Out-Null
- if($LASTEXITCODE -eq 0){
+ if ($LASTEXITCODE -eq 0) {
Write-Host "Mysql admin password for the root user has been verified"
} else {
Write-Host "Mysql admin password for the root user verification failed!"
$global:ALL_CHECKS_PASSED = $false
}
-
- }else{
+
+ } else {
Write-Host "Unable to log into mysql since the aca.properties file does not contain the value associated with the mysql_admin_password key"
$global:ALL_CHECKS_PASSED = $false
}
@@ -217,14 +217,14 @@ Function check_db() {
$aca_prop_table = populate_aca_properties_table
- if(-not $aca_prop_table){
- Write-Host "Unable to create a hash table using the provided aca properties file."
- $global:ALL_CHECKS_PASSED = $false
+ if (-not $aca_prop_table) {
+ Write-Host "Unable to create a hash table using the provided aca properties file."
+ $global:ALL_CHECKS_PASSED = $false
return
- }
+ }
- if($aca_prop_table.ContainsKey($global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME) -and $aca_prop_table[$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME]){
- $mysql_admin_password = $aca_prop_table[$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME]
+ if ($aca_prop_table.ContainsKey($global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME) -and $aca_prop_table[$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME]) {
+ $mysql_admin_password = $aca_prop_table[$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME]
# Check if MySQL server-side TLS is enabled
$sslResult = mysql -u root --password=$mysql_admin_password -e "SHOW VARIABLES LIKE '%have_ssl%'" | Select-String -Pattern "YES"
@@ -251,7 +251,7 @@ Function check_db() {
# Write-Host "Error: The hirs_db database is NOT visible by the hirs_db user"
# $global:ALL_CHECKS_PASSED = $false
# }
- # }
+ # }
}
Function check_fips() {
@@ -289,7 +289,7 @@ check_db
# Check for fips
check_fips
-if($global:ALL_CHECKS_PASSED -eq $true){
+if ($global:ALL_CHECKS_PASSED -eq $true) {
Write-Host "ACA setup checks on Windows have passed!"
} else {
Write-Host "ACA setup checks on Windows have failed."
diff --git a/package/win/aca/aca_common.ps1 b/package/win/aca/aca_common.ps1
index 7b1b5a0fe..6a4011a16 100644
--- a/package/win/aca/aca_common.ps1
+++ b/package/win/aca/aca_common.ps1
@@ -17,83 +17,83 @@
# Other files needed:
# C:/MariaDB 11.1/data/my.ini
# If mysql is installed somewhere else, update DB_CONF below.
-$global:HIRS_SYS_HOME=(Join-Path $Env:ProgramFiles "hirs")
-$global:HIRS_INSTALL_SCRIPTS_DIR=(Join-Path $Env:ProgramFiles "scripts")
-$global:HIRS_INSTALL_SCRIPTS_DB_DIR=(Join-Path $Env:ProgramFiles "db")
-$global:HIRS_DATA_DIR=(Join-Path $Env:ProgramData "hirs")
-$global:HIRS_CONF_DIR=(Join-Path $global:HIRS_DATA_DIR "aca")
-$global:HIRS_DATA_ACA_PROPERTIES_FILE=(Join-Path $global:HIRS_CONF_DIR 'aca.properties')
-$global:HIRS_DATA_SPRING_PROP_FILE=(Join-Path $global:HIRS_CONF_DIR 'application.win.properties')
-$global:HIRS_DATA_CERTIFICATES_DIR=(Join-Path $global:HIRS_DATA_DIR "certificates")
-$global:HIRS_DATA_CERTIFICATES_HIRS_DIR=(Join-Path $global:HIRS_DATA_CERTIFICATES_DIR "HIRS")
-$global:HIRS_DATA_LOG_DIR=(Join-Path $global:HIRS_DATA_DIR "log")
-$global:HIRS_DATA_INSTALL_LOG_NAME=(Join-Path $global:HIRS_DATA_LOG_DIR ("hirs_aca_install_"+(Get-Date -Format "yyyy-MM-dd")+'.log'))
-$global:HIRS_CONF_DEFAULT_PROPERTIES_DIR=(Join-Path $global:HIRS_CONF_DIR "default-properties")
-$global:HIRS_DATA_WIN_VERSION_FILE=(Join-Path $global:HIRS_CONF_DIR 'VERSION')
+$global:HIRS_SYS_HOME = (Join-Path $Env:ProgramFiles "hirs")
+$global:HIRS_INSTALL_SCRIPTS_DIR = (Join-Path $Env:ProgramFiles "scripts")
+$global:HIRS_INSTALL_SCRIPTS_DB_DIR = (Join-Path $Env:ProgramFiles "db")
+$global:HIRS_DATA_DIR = (Join-Path $Env:ProgramData "hirs")
+$global:HIRS_CONF_DIR = (Join-Path $global:HIRS_DATA_DIR "aca")
+$global:HIRS_DATA_ACA_PROPERTIES_FILE = (Join-Path $global:HIRS_CONF_DIR 'aca.properties')
+$global:HIRS_DATA_SPRING_PROP_FILE = (Join-Path $global:HIRS_CONF_DIR 'application.win.properties')
+$global:HIRS_DATA_CERTIFICATES_DIR = (Join-Path $global:HIRS_DATA_DIR "certificates")
+$global:HIRS_DATA_CERTIFICATES_HIRS_DIR = (Join-Path $global:HIRS_DATA_CERTIFICATES_DIR "HIRS")
+$global:HIRS_DATA_LOG_DIR = (Join-Path $global:HIRS_DATA_DIR "log")
+$global:HIRS_DATA_INSTALL_LOG_NAME = (Join-Path $global:HIRS_DATA_LOG_DIR ("hirs_aca_install_" + (Get-Date -Format "yyyy-MM-dd") + '.log'))
+$global:HIRS_CONF_DEFAULT_PROPERTIES_DIR = (Join-Path $global:HIRS_CONF_DIR "default-properties")
+$global:HIRS_DATA_WIN_VERSION_FILE = (Join-Path $global:HIRS_CONF_DIR 'VERSION')
# ACA Property Keys
-$global:ACA_PROPERTIES_PKI_PWD_PROPERTY_NAME="hirs_pki_password"
-$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME="mysql_admin_password"
-$global:ACA_PROPERTIES_HIRS_DB_USERNAME_PROPERTY_NAME="hirs_db_username"
-$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME="hirs_db_password"
+$global:ACA_PROPERTIES_PKI_PWD_PROPERTY_NAME = "hirs_pki_password"
+$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME = "mysql_admin_password"
+$global:ACA_PROPERTIES_HIRS_DB_USERNAME_PROPERTY_NAME = "hirs_db_username"
+$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME = "hirs_db_password"
# Spring Property Keys
-$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME="hibernate.connection.username"
-$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME="hibernate.connection.password"
-$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME="server.ssl.trust-alias"
-$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME="server.ssl.key-alias"
-$global:SPRING_PROPERTIES_SSL_KEY_STORE_PWD_PROPERTY_NAME="server.ssl.key-store-password"
-$global:SPRING_PROPERTIES_SSL_KEY_TRUST_STORE_PWD_PROPERTY_NAME="server.ssl.trust-store-password"
-$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME="aca.certificates.leaf-three-key-alias"
-$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME="aca.certificates.intermediate-key-alias"
-$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME="aca.certificates.root-key-alias"
+$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME = "hibernate.connection.username"
+$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME = "hibernate.connection.password"
+$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME = "server.ssl.trust-alias"
+$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME = "server.ssl.key-alias"
+$global:SPRING_PROPERTIES_SSL_KEY_STORE_PWD_PROPERTY_NAME = "server.ssl.key-store-password"
+$global:SPRING_PROPERTIES_SSL_KEY_TRUST_STORE_PWD_PROPERTY_NAME = "server.ssl.trust-store-password"
+$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME = "aca.certificates.leaf-three-key-alias"
+$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME = "aca.certificates.intermediate-key-alias"
+$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME = "aca.certificates.root-key-alias"
# DB Configuration file
$global:DB_CONF = (Resolve-Path ([System.IO.Path]::Combine($Env:ProgramFiles, 'MariaDB 11.1', 'data', 'my.ini'))).Path
# RSA Certificates Directory
-$global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH=(Join-Path $HIRS_DATA_CERTIFICATES_HIRS_DIR "rsa_3k_sha384_certs")
+$global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH = (Join-Path $HIRS_DATA_CERTIFICATES_HIRS_DIR "rsa_3k_sha384_certs")
# RSA Server Side Certificates (Default)
-$global:SSL_DB_RSA_SRV_CHAIN=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_rsa_3k_sha384_Cert_Chain.pem')
-$global:SSL_DB_RSA_SRV_CERT=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_srv_rsa_3k_sha384.pem')
-$global:SSL_DB_RSA_SRV_KEY=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_srv_rsa_3k_sha384.key')
+$global:SSL_DB_RSA_SRV_CHAIN = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_rsa_3k_sha384_Cert_Chain.pem')
+$global:SSL_DB_RSA_SRV_CERT = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_srv_rsa_3k_sha384.pem')
+$global:SSL_DB_RSA_SRV_KEY = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_srv_rsa_3k_sha384.key')
# RSA Client Side Certificates (Default)
-$global:SSL_DB_RSA_CLIENT_CHAIN=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_rsa_3k_sha384_Cert_Chain.pem')
-$global:SSL_DB_RSA_CLIENT_CERT=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_client_rsa_3k_sha384.pem')
-$global:SSL_DB_RSA_CLIENT_KEY=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_client_rsa_3k_sha384.key')
+$global:SSL_DB_RSA_CLIENT_CHAIN = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_rsa_3k_sha384_Cert_Chain.pem')
+$global:SSL_DB_RSA_CLIENT_CERT = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_client_rsa_3k_sha384.pem')
+$global:SSL_DB_RSA_CLIENT_KEY = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_client_rsa_3k_sha384.key')
# RSA PKI Certificates
-$global:RSA_HIRS_ROOT=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_root_ca_rsa_3k_sha384.pem')
-$global:RSA_HIRS_INTERMEDIATE=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_intermediate_ca_rsa_3k_sha384.pem')
-$global:RSA_HIRS_CA1=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_leaf_ca1_rsa_3k_sha384.pem')
-$global:RSA_HIRS_CA2=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_leaf_ca2_rsa_3k_sha384.pem')
-$global:RSA_HIRS_CA3=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_leaf_ca3_rsa_3k_sha384.pem')
-$global:RSA_RIM_SIGNER=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_rim_signer_rsa_3k_sha384.pem')
-$global:RSA_WEB_TLS_CERT=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_aca_tls_rsa_3k_sha384.pem')
+$global:RSA_HIRS_ROOT = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_root_ca_rsa_3k_sha384.pem')
+$global:RSA_HIRS_INTERMEDIATE = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_intermediate_ca_rsa_3k_sha384.pem')
+$global:RSA_HIRS_CA1 = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_leaf_ca1_rsa_3k_sha384.pem')
+$global:RSA_HIRS_CA2 = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_leaf_ca2_rsa_3k_sha384.pem')
+$global:RSA_HIRS_CA3 = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_leaf_ca3_rsa_3k_sha384.pem')
+$global:RSA_RIM_SIGNER = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_rim_signer_rsa_3k_sha384.pem')
+$global:RSA_WEB_TLS_CERT = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_aca_tls_rsa_3k_sha384.pem')
# ECC Certificates Directory
-$global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH=(Join-Path $HIRS_DATA_CERTIFICATES_HIRS_DIR "ecc_512_sha384_certs")
+$global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH = (Join-Path $HIRS_DATA_CERTIFICATES_HIRS_DIR "ecc_512_sha384_certs")
# ECC Server Side Certificates
-$global:SSL_DB_ECC_SRV_CHAIN=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_ecc_512_sha384_Cert_Chain.pem')
-$global:SSL_DB_ECC_SRV_CERT=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_db_srv_ecc_512_sha384.pem')
-$global:SSL_DB_ECC_SRV_KEY=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_db_srv_ecc_512_sha384.key')
+$global:SSL_DB_ECC_SRV_CHAIN = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_ecc_512_sha384_Cert_Chain.pem')
+$global:SSL_DB_ECC_SRV_CERT = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_db_srv_ecc_512_sha384.pem')
+$global:SSL_DB_ECC_SRV_KEY = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_db_srv_ecc_512_sha384.key')
# ECC Client Side Certificates
-$global:SSL_DB_ECC_CLIENT_CHAIN=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_ecc_512_sha384_Cert_Chain.pem')
-$global:SSL_DB_ECC_CLIENT_CERT=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_db_client_ecc_512_sha384.pem')
-$global:SSL_DB_ECC_CLIENT_KEY=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_db_client_ecc_512_sha384.key')
+$global:SSL_DB_ECC_CLIENT_CHAIN = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_ecc_512_sha384_Cert_Chain.pem')
+$global:SSL_DB_ECC_CLIENT_CERT = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_db_client_ecc_512_sha384.pem')
+$global:SSL_DB_ECC_CLIENT_KEY = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_db_client_ecc_512_sha384.key')
# ECC PKI Certificates
-$global:ECC_HIRS_ROOT=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_root_ca_ecc_512_sha384.pem')
-$global:ECC_HIRS_INTERMEDIATE=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_intermediate_ca_ecc_512_sha384.pem')
-$global:ECC_HIRS_CA1=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_leaf_ca1_ecc_512_sha384.pem')
-$global:ECC_HIRS_CA2=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_leaf_ca2_ecc_512_sha384.pem')
-$global:ECC_HIRS_CA3=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_leaf_ca3_ecc_512_sha384.pem')
-$global:ECC_RIM_SIGNER=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_rim_signer_ecc_512_sha384.pem')
-$global:ECC_WEB_TLS_CERT=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_aca_tls_ecc_512_sha384.pem')
+$global:ECC_HIRS_ROOT = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_root_ca_ecc_512_sha384.pem')
+$global:ECC_HIRS_INTERMEDIATE = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_intermediate_ca_ecc_512_sha384.pem')
+$global:ECC_HIRS_CA1 = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_leaf_ca1_ecc_512_sha384.pem')
+$global:ECC_HIRS_CA2 = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_leaf_ca2_ecc_512_sha384.pem')
+$global:ECC_HIRS_CA3 = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_leaf_ca3_ecc_512_sha384.pem')
+$global:ECC_RIM_SIGNER = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_rim_signer_ecc_512_sha384.pem')
+$global:ECC_WEB_TLS_CERT = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_aca_tls_ecc_512_sha384.pem')
# HIRS Relative directories assumed structure
# package
@@ -119,35 +119,35 @@ $global:ECC_WEB_TLS_CERT=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH
# pki
# pki_chain_gen.ps1
# pki_setup.ps1
-$global:HIRS_REL_WIN_ACA_HOME=(Split-Path -parent $PSCommandPath)
-$global:HIRS_REL_WIN_HOME=(Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME ..)
-$global:HIRS_REL_PACKAGE_HOME=(Join-Path -Resolve $global:HIRS_REL_WIN_HOME ..)
-$global:HIRS_REL_LINUX_HOME=(Join-Path -Resolve $global:HIRS_REL_PACKAGE_HOME 'linux')
-$global:HIRS_REL_SCRIPTS_ACA_HOME=(Join-Path -Resolve $global:HIRS_REL_LINUX_HOME 'aca')
-$global:HIRS_REL_SCRIPTS_LINUX_DB_HOME=(Join-Path -Resolve $global:HIRS_REL_LINUX_HOME 'db')
-$global:HIRS_REL_SCRIPTS_DB_CREATE_SQL=(Join-Path -Resolve $global:HIRS_REL_SCRIPTS_LINUX_DB_HOME 'db_create.sql')
-$global:HIRS_REL_SCRIPTS_DB_SECURE_MYSQL_SQL=(Join-Path -Resolve $global:HIRS_REL_SCRIPTS_LINUX_DB_HOME 'secure_mysql.sql')
-$global:HIRS_REL_SCRIPTS_LINUX_PKI_HOME=(Join-Path -Resolve $global:HIRS_REL_LINUX_HOME 'pki')
-$global:HIRS_REL_SCRIPTS_PKI_CA_CONF=(Join-Path -Resolve $global:HIRS_REL_SCRIPTS_LINUX_PKI_HOME 'ca.conf')
+$global:HIRS_REL_WIN_ACA_HOME = (Split-Path -parent $PSCommandPath)
+$global:HIRS_REL_WIN_HOME = (Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME ..)
+$global:HIRS_REL_PACKAGE_HOME = (Join-Path -Resolve $global:HIRS_REL_WIN_HOME ..)
+$global:HIRS_REL_LINUX_HOME = (Join-Path -Resolve $global:HIRS_REL_PACKAGE_HOME 'linux')
+$global:HIRS_REL_SCRIPTS_ACA_HOME = (Join-Path -Resolve $global:HIRS_REL_LINUX_HOME 'aca')
+$global:HIRS_REL_SCRIPTS_LINUX_DB_HOME = (Join-Path -Resolve $global:HIRS_REL_LINUX_HOME 'db')
+$global:HIRS_REL_SCRIPTS_DB_CREATE_SQL = (Join-Path -Resolve $global:HIRS_REL_SCRIPTS_LINUX_DB_HOME 'db_create.sql')
+$global:HIRS_REL_SCRIPTS_DB_SECURE_MYSQL_SQL = (Join-Path -Resolve $global:HIRS_REL_SCRIPTS_LINUX_DB_HOME 'secure_mysql.sql')
+$global:HIRS_REL_SCRIPTS_LINUX_PKI_HOME = (Join-Path -Resolve $global:HIRS_REL_LINUX_HOME 'pki')
+$global:HIRS_REL_SCRIPTS_PKI_CA_CONF = (Join-Path -Resolve $global:HIRS_REL_SCRIPTS_LINUX_PKI_HOME 'ca.conf')
# WIN ACA powershell scripts
-$global:HIRS_REL_WIN_ACA_BOOTRUN=(Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_bootRun.ps1')
-$global:HIRS_REL_WIN_ACA_COMMON=(Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_common.ps1')
-$global:HIRS_REL_WIN_ACA_SETUP=(Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_setup.ps1')
-$global:HIRS_REL_WIN_ACA_CONFIG=(Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_win_config.ps1')
-$global:HIRS_REL_WIN_ACA_CHECK_SETUP=(Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_check_setup.ps1')
-$global:HIRS_REL_WIN_ACA_REMOVE_SETUP=(Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_remove_setup.ps1')
+$global:HIRS_REL_WIN_ACA_BOOTRUN = (Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_bootRun.ps1')
+$global:HIRS_REL_WIN_ACA_COMMON = (Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_common.ps1')
+$global:HIRS_REL_WIN_ACA_SETUP = (Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_setup.ps1')
+$global:HIRS_REL_WIN_ACA_CONFIG = (Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_win_config.ps1')
+$global:HIRS_REL_WIN_ACA_CHECK_SETUP = (Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_check_setup.ps1')
+$global:HIRS_REL_WIN_ACA_REMOVE_SETUP = (Join-Path -Resolve $global:HIRS_REL_WIN_ACA_HOME 'aca_remove_setup.ps1')
# WIN DB powershell scripts
-$global:HIRS_REL_WIN_DB_HOME=(Join-Path -Resolve $global:HIRS_REL_WIN_HOME 'db')
-$global:HIRS_REL_WIN_DB_CREATE=(Join-Path -Resolve $global:HIRS_REL_WIN_DB_HOME 'db_create.ps1')
-$global:HIRS_REL_WIN_DB_MYSQL_UTIL=(Join-Path -Resolve $global:HIRS_REL_WIN_DB_HOME 'mysql_util.ps1')
-$global:HIRS_REL_WIN_DB_DROP=(Join-Path -Resolve $global:HIRS_REL_WIN_DB_HOME 'db_drop.ps1')
+$global:HIRS_REL_WIN_DB_HOME = (Join-Path -Resolve $global:HIRS_REL_WIN_HOME 'db')
+$global:HIRS_REL_WIN_DB_CREATE = (Join-Path -Resolve $global:HIRS_REL_WIN_DB_HOME 'db_create.ps1')
+$global:HIRS_REL_WIN_DB_MYSQL_UTIL = (Join-Path -Resolve $global:HIRS_REL_WIN_DB_HOME 'mysql_util.ps1')
+$global:HIRS_REL_WIN_DB_DROP = (Join-Path -Resolve $global:HIRS_REL_WIN_DB_HOME 'db_drop.ps1')
# WIN PKI powershell scripts
-$global:HIRS_REL_WIN_PKI_HOME=(Join-Path -Resolve $global:HIRS_REL_WIN_HOME 'pki')
-$global:HIRS_REL_WIN_PKI_CHAIN_GEN=(Join-Path -Resolve $global:HIRS_REL_WIN_PKI_HOME 'pki_chain_gen.ps1')
-$global:HIRS_REL_WIN_PKI_SETUP=(Join-Path -Resolve $global:HIRS_REL_WIN_PKI_HOME 'pki_setup.ps1')
+$global:HIRS_REL_WIN_PKI_HOME = (Join-Path -Resolve $global:HIRS_REL_WIN_HOME 'pki')
+$global:HIRS_REL_WIN_PKI_CHAIN_GEN = (Join-Path -Resolve $global:HIRS_REL_WIN_PKI_HOME 'pki_chain_gen.ps1')
+$global:HIRS_REL_WIN_PKI_SETUP = (Join-Path -Resolve $global:HIRS_REL_WIN_PKI_HOME 'pki_setup.ps1')
$global:HIRS_RELEASE_VERSION_FILE = (Join-Path -Resolve $global:HIRS_REL_PACKAGE_HOME '..\VERSION')
# ACA Properties Files
@@ -164,41 +164,46 @@ $global:HIRS_REL_WIN_PKI_CA_CONF = Join-Path $global:HIRS_REL_WIN_PKI_HOME "ca.c
# Saved values
# $Env:HIRS_MYSQL_ROOT_PWD
# $Env:HIRS_PKI_PWD
-$global:ACA_PROPERTIES=$null
-$global:SPRING_PROPERTIES=$null
+$global:ACA_PROPERTIES = $null
+$global:SPRING_PROPERTIES = $null
# Below are the common utility functions that are used by the other ACA powershell scripts
-Function read_aca_properties () {
+Function read_aca_properties() {
# This converts the ACA properties file into a hash table
# Values are accessed by key like this: $propertyValue=$global:ACA_PROPERTIES.'example.property.key'
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$file
)
if (!$global:ACA_PROPERTIES -and $file -and [System.IO.File]::Exists($file)) {
- $file_content=(Get-Content $file -Raw)
- if ($file_content) { # File is not empty
- $global:ACA_PROPERTIES=(Get-Content -Path $file -Raw | ConvertFrom-StringData)
- } else { # File is empty
+ $file_content = (Get-Content $file -Raw)
+ if ($file_content) {
+ # File is not empty
+ $global:ACA_PROPERTIES = (Get-Content -Path $file -Raw | ConvertFrom-StringData)
+ }
+ else {
+ # File is empty
# Initialize empty hash table
- $global:ACA_PROPERTIES=@{}
+ $global:ACA_PROPERTIES = @{ }
}
- } elseif ($file -and ![System.IO.File]::Exists($file)) {
- $msg="Warning: ACA properties file not found. The path provided was: [$file]"
+ }
+ elseif ($file -and ![System.IO.File]::Exists($file)) {
+ $msg = "Warning: ACA properties file not found. The path provided was: [$file]"
if ($global:LOG_FILE) {
Write-Output "$msg" | WriteAndLog
- } else {
+ }
+ else {
Write-Host "$msg"
}
}
}
-Function add_new_aca_property () {
+Function add_new_aca_property() {
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$file,
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$newKeyAndValue
)
@@ -208,24 +213,25 @@ Function add_new_aca_property () {
exit 1
}
- $msg="Writing KeyValue pair to $file"
+ $msg = "Writing KeyValue pair to $file"
if ($global:LOG_FILE) {
Write-Output "$msg" | WriteAndLog
- } else {
+ }
+ else {
Write-Host "$msg"
}
Write-Host "NOT LOGGED: KeyValue pair [$newKeyAndValue] has been added to file [$file]"
Write-Output "$newKeyAndValue" >> $file
- $global:ACA_PROPERTIES=$null
+ $global:ACA_PROPERTIES = $null
read_aca_properties $file
}
-Function find_property_value(){
+Function find_property_value() {
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$file,
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$key
)
@@ -243,56 +249,63 @@ Function find_property_value(){
$value = $match -replace "^$key=", ""
# If the script was able to find the value that's associated with the provided key
- if($value) {
- Write-Host "NOT LOGGED: The value [$value] has been found to be associated with the key [$key]"
- if($file -eq $global:HIRS_DATA_ACA_PROPERTIES_FILE ) {
- # Reset the global aca property hashmap and reload
- $global:ACA_PROPERTIES = $null
- Write-Output "Resetting and reloading the aca properties table" | WriteAndLog
- read_aca_properties $file
- } elseif($file -eq $global:HIRS_DATA_SPRING_PROP_FILE){
- # Reset the global spring property hashmap and reload
- $global:SPRING_PROPERTIES = $null
- Write-Output "Resetting and reloading the spring properties table" | WriteAndLog
- read_spring_properties -file $file
+ if ($value) {
+ Write-Host "NOT LOGGED: The value [$value] has been found to be associated with the key [$key]"
+ if ($file -eq $global:HIRS_DATA_ACA_PROPERTIES_FILE) {
+ # Reset the global aca property hashmap and reload
+ $global:ACA_PROPERTIES = $null
+ Write-Output "Resetting and reloading the aca properties table" | WriteAndLog
+ read_aca_properties $file
+ }
+ elseif($file -eq $global:HIRS_DATA_SPRING_PROP_FILE) {
+ # Reset the global spring property hashmap and reload
+ $global:SPRING_PROPERTIES = $null
+ Write-Output "Resetting and reloading the spring properties table" | WriteAndLog
+ read_spring_properties -file $file
}
- } else {
+ }
+ else {
Write-Host "NOT LOGGED: There are no values associated with the provided key [$key]"
}
-
+
return $value
}
-Function read_spring_properties () {
+Function read_spring_properties() {
# This converts the application properties file into a hash table
# Values are accessed by key like this: $propertyValue=$global:SPRING_PROPERTIES.'example.property.key'
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$file
)
if (!$global:SPRING_PROPERTIES -and $file -and [System.IO.File]::Exists($file)) {
- $file_content=(Get-Content $file -Raw)
- if ($file_content) { # File is not empty
- $global:SPRING_PROPERTIES=(Get-Content -Path $file -Raw | ConvertFrom-StringData)
- } else { # File is empty
+ $file_content = (Get-Content $file -Raw)
+ if ($file_content) {
+ # File is not empty
+ $global:SPRING_PROPERTIES = (Get-Content -Path $file -Raw | ConvertFrom-StringData)
+ }
+ else {
+ # File is empty
# Initialize empty hash table
- $global:SPRING_PROPERTIES=@{}
+ $global:SPRING_PROPERTIES = @{ }
}
- } elseif ($file -and ![System.IO.File]::Exists($file)) {
- $msg="Warning: Spring properties file not found. The path provided was: [$file]"
+ }
+ elseif ($file -and ![System.IO.File]::Exists($file)) {
+ $msg = "Warning: Spring properties file not found. The path provided was: [$file]"
if ($global:LOG_FILE) {
Write-Output "$msg" | WriteAndLog
- } else {
+ }
+ else {
Write-Host "$msg"
}
}
}
-Function add_new_spring_property () {
+Function add_new_spring_property() {
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$file,
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$newKeyAndValue
)
@@ -302,26 +315,27 @@ Function add_new_spring_property () {
exit 1
}
- $msg="Writing KeyValue pair to $file"
+ $msg = "Writing KeyValue pair to $file"
if ($global:LOG_FILE) {
Write-Output "$msg" | WriteAndLog
- } else {
+ }
+ else {
Write-Host "$msg"
}
Write-Host "NOT LOGGED: KeyValue pair: $newKeyAndValue to file $file"
Write-Output "$newKeyAndValue" >> $file
- $global:SPRING_PROPERTIES=$null
+ $global:SPRING_PROPERTIES = $null
read_spring_properties -file $file
}
-Function remove_spring_property_value_pair(){
- param (
- [Parameter(Mandatory=$true)]
+Function remove_spring_property_value_pair() {
+ param (
+ [Parameter(Mandatory = $true)]
[string]$file,
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$keyToBeDeleted
- )
+ )
if (-not $file -or -not $keyToBeDeleted -or -not (Test-Path $file)) {
Write-Output "Exiting script while attempting to delete a Spring property since the provided file [$file] does not exist and/or
@@ -329,11 +343,11 @@ Function remove_spring_property_value_pair(){
exit 1
}
- # Read all lines
+ # Read all lines
$lines = Get-Content $File
# Filter out lines that start with key=
- $filteredLines = $lines | Where-Object { $_ -notmatch "^\s*$([regex]::Escape($KeyToBeDeleted))=" }
+ $filteredLines = $lines | Where-Object { $_ -notmatch "^\s*$([regex]::Escape($KeyToBeDeleted) )=" }
# Write back to the file (overwrite)
Set-Content -Path $File -Value $filteredLines
@@ -346,94 +360,8 @@ Function remove_spring_property_value_pair(){
read_spring_properties -file $file
}
-Function setup_aca_public_key_algorithm(){
- param(
- [Parameter(Mandatory=$true)]
- [string]$acaAlg
- )
-
- if (-not $acaAlg) {
- Write-Output "Exiting script while attempting to set the ACA's public key algorithm since the provided ACA Public Key Algorithm
- do not exist/have not been supplied" | WriteAndLog
- exit 1
- }
-
- $aca_leaf_cert_val=$null
- $aca_intermediate_cert_val=$null
- $aca_root_cert_val=$null
-
- if($acaAlg -eq "rsa"){
- $aca_leaf_cert_val="HIRS_leaf_ca3_rsa_3k_sha384"
- $aca_intermediate_cert_val="HIRS_intermediate_ca_rsa_3k_sha384"
- $aca_root_cert_val="HIRS_root_ca_rsa_3k_sha384"
- }
- elseif($acaAlg -eq "ecc"){
- $aca_leaf_cert_val="HIRS_leaf_ca3_ecc_512_sha384"
- $aca_intermediate_cert_val="HIRS_intermediate_ca_ecc_512_sha384"
- $aca_root_cert_val="HIRS_root_ca_ecc_512_sha384"
- }
-
- remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME"
- remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME"
- remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME"
-
- if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME")){
- add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME=$aca_leaf_cert_val"
- Write-Output "Stored the $acaAlg ACA Leaf certificate alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
- }
-
- if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME")){
- add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME=$aca_intermediate_cert_val"
- Write-Output "Stored the $acaAlg ACA Intermediate certificate alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
- }
-
- if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME")){
- add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME=$aca_root_cert_val"
- Write-Output "Stored the $acaAlg ACA Root certificate alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
- }
-}
-
-Function setup_tls_config_aliases(){
- param(
- [Parameter(Mandatory=$true)]
- [string]$tlsAlg
- )
-
- if (-not $tlsAlg) {
- Write-Output "Exiting script while attempting to set the config file lines for tomcat ssl aliases since the provided TLS
- do not exist/have not been supplied" | WriteAndLog
- exit 1
- }
-
- $server_ssl_trust_alias_val=$null
- $server_ssl_key_alias_val=$null
-
- if($tlsAlg -eq "rsa"){
- $server_ssl_trust_alias_val="hirs_aca_tls_rsa_3k_sha384"
- $server_ssl_key_alias_val="hirs_aca_tls_rsa_3k_sha384"
- }
- elseif($tlsAlg -eq "ecc"){
- $server_ssl_trust_alias_val="hirs_aca_tls_ecc_512_sha384"
- $server_ssl_key_alias_val="hirs_aca_tls_ecc_512_sha384"
- }
-
- # remove default SSL config lines
- remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME"
- remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME"
-
- if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME")){
- add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME=$server_ssl_trust_alias_val"
- Write-Output "Stored the $tlsAlg SSL Trust Alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
- }
-
- if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME")){
- add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME=$server_ssl_key_alias_val"
- Write-Output "Stored the $tlsAlg SSL Key alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
- }
-}
-
-Function create_random () {
- # Step 1: Generate a string of 100 random numbers concatenated together
+Function create_random() {
+ # Step 1: Generate a string of 100 random numbers concatenated together
$randomData = -join (1..100 | ForEach-Object { Get-Random })
# Step 2: Create a SHA512 hashing object
@@ -449,28 +377,29 @@ Function create_random () {
return -join ($hashBytes | ForEach-Object { $_.ToString("x2") })
}
-Function set_up_log () {
+Function set_up_log() {
if (![System.IO.Directory]::Exists($global:HIRS_DATA_LOG_DIR)) {
New-Item -ItemType Directory -Path $global:HIRS_DATA_LOG_DIR -Force | Out-Null
}
- $global:LOG_FILE=$global:HIRS_DATA_INSTALL_LOG_NAME
-
+ $global:LOG_FILE = $global:HIRS_DATA_INSTALL_LOG_NAME
+
if (-not (Test-Path $global:LOG_FILE)) {
- New-Item -ItemType File -Path $global:LOG_FILE
- } else {
- Write-Output "File already exists: $global:LOG_FILE"
+ New-Item -ItemType File -Path $global:LOG_FILE
+ }
+ else {
+ Write-Output "File already exists: $global:LOG_FILE"
}
}
-Function print_all_variables () {
+Function print_all_variables() {
# intended for debugging
# this will print all variables and their values in the current context
Get-Variable | Out-String
}
-Function WriteAndLog () {
+Function WriteAndLog() {
param(
- [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position=0)]
+ [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
[string]$msg
)
# EXPECTS set_up_log() to be run and $global:LOG_FILE to be defined
@@ -478,18 +407,18 @@ Function WriteAndLog () {
"$msg" >> "$global:LOG_FILE"
}
-Function ChangeBackslashToForwardSlash () {
+Function ChangeBackslashToForwardSlash() {
param(
- [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position=0)]
+ [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
[string]$msg
)
- Write-Output ($msg -replace "\\","/")
+ Write-Output ($msg -replace "\\", "/")
}
-Function ChangeFileBackslashToForwardSlash () {
+Function ChangeFileBackslashToForwardSlash() {
param(
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$file
)
- (Get-Content $file) -replace "\\","/" | Set-Content $file
+ (Get-Content $file) -replace "\\", "/" | Set-Content $file
}
diff --git a/package/win/aca/aca_remove_setup.ps1 b/package/win/aca/aca_remove_setup.ps1
index f9341b3b2..ece037988 100644
--- a/package/win/aca/aca_remove_setup.ps1
+++ b/package/win/aca/aca_remove_setup.ps1
@@ -1,18 +1,18 @@
#This script will check remove all the directories/files/certificates and other miscelleaneous items that were created using the win setup script in a Windows environment
-if(!(New-Object Security.Principal.WindowsPrincipal(
- [Security.Principal.WindowsIdentity]::GetCurrent())
- ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
- Write-Host "This script requires root. Please run as root"
- exit 1
+if (!(New-Object Security.Principal.WindowsPrincipal(
+[Security.Principal.WindowsIdentity]::GetCurrent())
+).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
+ Write-Host "This script requires root. Please run as root"
+ exit 1
}
Write-Host "----------------------------------------------------------------------"
Write-Host ""
Write-Host "Running the aca removal script ... "
-$ACA_SCRIPTS_HOME=(Split-Path -parent $PSCommandPath)
-$ACA_COMMON_SCRIPT=(Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
+$ACA_SCRIPTS_HOME = (Split-Path -parent $PSCommandPath)
+$ACA_COMMON_SCRIPT = (Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
# load other scripts
. $ACA_COMMON_SCRIPT
@@ -20,15 +20,16 @@ $ACA_COMMON_SCRIPT=(Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
Write-Host "Checking if the [$global:HIRS_DATA_DIR] directory exists"
-if(-not (Test-Path -Path $global:HIRS_DATA_DIR)){
- Write-Host "$global:HIRS_DATA_DIR does not exist. Aborting removal"
- exit 1
-} else{
- Write-Host "Directory [$global:HIRS_DATA_DIR] exists"
+if (-not (Test-Path -Path $global:HIRS_DATA_DIR)) {
+ Write-Host "$global:HIRS_DATA_DIR does not exist. Aborting removal"
+ exit 1
+}
+else {
+ Write-Host "Directory [$global:HIRS_DATA_DIR] exists"
}
-Function retrieve_mysql_root_pwd () {
- if(-not (Test-Path $global:HIRS_DATA_ACA_PROPERTIES_FILE)){
+Function retrieve_mysql_root_pwd() {
+ if (-not (Test-Path $global:HIRS_DATA_ACA_PROPERTIES_FILE)) {
Write-Host "The ACA property files does not exist. Aborting removal."
exit 1
}
@@ -36,14 +37,14 @@ Function retrieve_mysql_root_pwd () {
# Convert the contents of the aca properties file into a hash table
$aca_prop_table = Get-Content -Path $global:HIRS_DATA_ACA_PROPERTIES_FILE -Raw | ConvertFrom-StringData
- if(-not $aca_prop_table){
- Write-Host "Unable to create a hash table using the provided aca properties file. Aborting removal."
- exit 1
- }
+ if (-not $aca_prop_table) {
+ Write-Host "Unable to create a hash table using the provided aca properties file. Aborting removal."
+ exit 1
+ }
- if($aca_prop_table.ContainsKey($global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME) -and $aca_prop_table[$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME]){
- return $aca_prop_table[$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME]
- }
+ if ($aca_prop_table.ContainsKey($global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME) -and $aca_prop_table[$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME]) {
+ return $aca_prop_table[$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME]
+ }
}
# check if mariadb is installed
@@ -53,11 +54,12 @@ check_mariadb_install
# retrieve the mysql admin password
$DB_ADMIN_PWD = retrieve_mysql_root_pwd
-if(-not $DB_ADMIN_PWD){
- Write-Host "DB admin password could not be found. Aborting removal."
- exit 1
-} else{
- Write-Host "DB admin password has been found."
+if (-not $DB_ADMIN_PWD) {
+ Write-Host "DB admin password could not be found. Aborting removal."
+ exit 1
+}
+else {
+ Write-Host "DB admin password has been found."
}
# remove the hrs-db and hirs_db user (execute the .\db_drop.ps1 script)
diff --git a/package/win/aca/aca_setup.ps1 b/package/win/aca/aca_setup.ps1
index 5bbaa429d..1dd0c9da1 100644
--- a/package/win/aca/aca_setup.ps1
+++ b/package/win/aca/aca_setup.ps1
@@ -1,11 +1,11 @@
param (
- [Alias("sd","skip-db")][switch]$skipdb = $false,
- [Alias("sp","skip-pki")][switch]$skippki = $false,
- [Alias("u","unattended")][switch]$IsUnattended = $false,
- [Alias("h","help")][switch]$ShowHelp = $false,
- [Alias("aa","aca-alg")][string]$AcaAlg,
- [Alias("ta","ta-alg")][string]$TlsAlg,
- [Alias("da","db-alg")][string]$DbAlg
+ [Alias("sd", "skip-db")][switch]$skipdb = $false,
+ [Alias("sp", "skip-pki")][switch]$skippki = $false,
+ [Alias("u", "unattended")][switch]$IsUnattended = $false,
+ [Alias("h", "help")][switch]$ShowHelp = $false,
+ [Alias("aa", "aca-alg")][string]$AcaAlg,
+ [Alias("ta", "ta-alg")][string]$TlsAlg,
+ [Alias("da", "db-alg")][string]$DbAlg
)
if ($ShowHelp) {
@@ -20,14 +20,14 @@ if ($ShowHelp) {
Write-Host " [-aa | -aca-alg] Sets the ACA's default algorithm (rsa, ecc, or mldsa) for Attestation Certificates."
Write-Host " [-ta | -tls-alg] Sets the ACA's default algorithm (rsa, ecc, or mldsa) for TLS on the ACA portal."
Write-Host " [-da | -db-alg] Sets the ACA's default algorithm (rsa, ecc, or mldsa) for use with MariaDB."
- exit 1
+ exit 1
}
-if(!(New-Object Security.Principal.WindowsPrincipal(
- [Security.Principal.WindowsIdentity]::GetCurrent())
- ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
- Write-Host "This script requires root. Please run as root"
- exit 1
+if (!(New-Object Security.Principal.WindowsPrincipal(
+[Security.Principal.WindowsIdentity]::GetCurrent())
+).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
+ Write-Host "This script requires root. Please run as root"
+ exit 1
}
# Set default algorithms to "RSA" if none provided
@@ -65,14 +65,14 @@ if ($validAlgs -notcontains $DbAlg) {
exit 1
}
-$ACA_SCRIPTS_HOME=(Split-Path -parent $PSCommandPath)
-$ACA_COMMON_SCRIPT=(Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
+$ACA_SCRIPTS_HOME = (Split-Path -parent $PSCommandPath)
+$ACA_COMMON_SCRIPT = (Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
$COMP_JSON = (Resolve-Path ([System.IO.Path]::Combine(
- $ACA_SCRIPTS_HOME, '..', '..', '..', 'HIRS_AttestationCA', 'src', 'main', 'resources', 'component-class.json'))).Path
-$VENDOR_TABLE=(Resolve-Path ([System.IO.Path]::Combine(
- $ACA_SCRIPTS_HOME, '..', '..', '..', 'HIRS_Utils', 'src', 'main', 'resources', 'vendor-table.json'))).Path
-$SPRING_PROPERTIES_FILE=(Resolve-Path ([System.IO.Path]::Combine(
- $ACA_SCRIPTS_HOME, '..', '..', '..', 'HIRS_AttestationCAPortal', 'src', 'main', 'resources', 'application.win.properties'))).Path
+ $ACA_SCRIPTS_HOME, '..', '..', '..', 'HIRS_AttestationCA', 'src', 'main', 'resources', 'component-class.json'))).Path
+$VENDOR_TABLE = (Resolve-Path ([System.IO.Path]::Combine(
+ $ACA_SCRIPTS_HOME, '..', '..', '..', 'HIRS_Utils', 'src', 'main', 'resources', 'vendor-table.json'))).Path
+$SPRING_PROPERTIES_FILE = (Resolve-Path ([System.IO.Path]::Combine(
+ $ACA_SCRIPTS_HOME, '..', '..', '..', 'HIRS_AttestationCAPortal', 'src', 'main', 'resources', 'application.win.properties'))).Path
# Load other scripts
. $ACA_COMMON_SCRIPT
@@ -80,18 +80,18 @@ $SPRING_PROPERTIES_FILE=(Resolve-Path ([System.IO.Path]::Combine(
# Set up log
set_up_log
-Write-Output "HIRS ACA Setup initiated on $(Get-Date -Format 'yyyy-MM-dd')" | WriteAndLog
+Write-Output "HIRS ACA Setup initiated on $( Get-Date -Format 'yyyy-MM-dd' )" | WriteAndLog
Write-Output "-----------------------------------------------------------" | WriteAndLog
Write-Output "ACA setup log file is $global:LOG_FILE" | WriteAndLog
-Write-Output ("Running with these arguments: "+($PSBoundParameters | Out-String)) | WriteAndLog
+Write-Output ("Running with these arguments: " + ($PSBoundParameters | Out-String)) | WriteAndLog
Write-Output "Setting up the VERSION file that the bootRun can use" | WriteAndLog
# Check if git is available
if (Get-Command git -ErrorAction SilentlyContinue) {
# Check if we're inside a git working tree
- $isInsideWorkTree = git rev-parse --is-inside-work-tree 2>$null
+ $isInsideWorkTree = git rev-parse --is-inside-work-tree 2> $null
if ($LASTEXITCODE -eq 0 -and $isInsideWorkTree.Trim() -eq "true") {
# Read the VERSION file
@@ -102,7 +102,7 @@ if (Get-Command git -ErrorAction SilentlyContinue) {
$gitHash = git rev-parse --short HEAD
- $jarVersion = "$($version.Trim()).$timestamp.$($gitHash.Trim())"
+ $jarVersion = "$($version.Trim() ).$timestamp.$($gitHash.Trim() )"
if (-not (Test-Path $global:HIRS_DATA_WIN_VERSION_FILE)) {
New-Item -ItemType File -Path $global:HIRS_DATA_WIN_VERSION_FILE -Force | Out-Null
@@ -123,9 +123,10 @@ Copy-Item $SPRING_PROPERTIES_FILE $global:HIRS_DATA_SPRING_PROP_FILE
# create it, if it doesn't exist
if (-not (Test-Path $global:HIRS_DATA_ACA_PROPERTIES_FILE)) {
New-Item -ItemType File -Path $global:HIRS_DATA_ACA_PROPERTIES_FILE
-} else {
+}
+else {
Write-Output "File already exists: $global:HIRS_DATA_ACA_PROPERTIES_FILE" | WriteAndLog
-}
+}
read_aca_properties $global:HIRS_DATA_ACA_PROPERTIES_FILE
@@ -134,46 +135,138 @@ read_aca_properties $global:HIRS_DATA_ACA_PROPERTIES_FILE
# create it, if it doesn't exist
if (-not (Test-Path $global:HIRS_DATA_SPRING_PROP_FILE)) {
New-Item -ItemType File -Path $global:HIRS_DATA_SPRING_PROP_FILE
-} else {
+}
+else {
Write-Output "File already exists: $global:HIRS_DATA_SPRING_PROP_FILE" | WriteAndLog
}
-
+
read_spring_properties -file "$global:HIRS_DATA_SPRING_PROP_FILE"
# Runs the pki_setup script (along with the other scripts under the PKI folder)
if (!$skippki) {
- if (!$Env:HIRS_PKI_PWD) {
- $HIRS_PKI_PWD=(create_random)
- # NOTE: Writing to the environment variable did not work within the container
- # This password will be stored in the ACA properties file.
- Write-Output "Using randomly generated password for the PKI key password" | WriteAndLog
- Write-Host "NOT LOGGED: Using pki password=$HIRS_PKI_PWD"
- } else {
- $HIRS_PKI_PWD=$Env:HIRS_PKI_PWD
- Write-Output "Using system supplied password for the PKI key password" | WriteAndLog
- }
- pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_PKI_SETUP -LOG_FILE "$global:LOG_FILE" -PKI_PASS "$HIRS_PKI_PWD"
- if ($LastExitCode -eq 0) {
+ if (!$Env:HIRS_PKI_PWD) {
+ $HIRS_PKI_PWD = (create_random)
+ # NOTE: Writing to the environment variable did not work within the container
+ # This password will be stored in the ACA properties file.
+ Write-Output "Using randomly generated password for the PKI key password" | WriteAndLog
+ Write-Host "NOT LOGGED: Using pki password=$HIRS_PKI_PWD"
+ }
+ else {
+ $HIRS_PKI_PWD = $Env:HIRS_PKI_PWD
+ Write-Output "Using system supplied password for the PKI key password" | WriteAndLog
+ }
+ pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_PKI_SETUP -LOG_FILE "$global:LOG_FILE" -PKI_PASS "$HIRS_PKI_PWD"
+ if ($LastExitCode -eq 0) {
Write-Output "ACA PKI setup complete" | WriteAndLog
- } else {
+ }
+ else {
Write-Output "Error setting up ACA PKI" | WriteAndLog
exit 1
}
-} else {
- Write-Output ("ACA PKI setup cannot be run because there are command line argument(s): "+($PSBoundParameters.Keys | Where-Object { $_ -match 'skip-pki|sp' } )) | WriteAndLog
+}
+else {
+ Write-Output ("ACA PKI setup cannot be run because there are command line argument(s): " + ($PSBoundParameters.Keys | Where-Object { $_ -match 'skip-pki|sp' })) | WriteAndLog
}
# Runs the create_db script (along with the other scripts under the DB folder)
if (!$skipdb) {
- pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_DB_CREATE -LOG_FILE "$global:LOG_FILE" -UNATTENDED:$IsUnattended -DB_ALG "$DbAlg"
- if ($LastExitCode -eq 0) {
+ pwsh -ExecutionPolicy Bypass $global:HIRS_REL_WIN_DB_CREATE -LOG_FILE "$global:LOG_FILE" -UNATTENDED:$IsUnattended -DB_ALG "$DbAlg"
+ if ($LastExitCode -eq 0) {
Write-Output "ACA database setup complete" | WriteAndLog
- } else {
+ }
+ else {
Write-Output "Error setting up ACA DB" | WriteAndLog
exit 1
}
-} else {
- Write-Output ("ACA Database setup cannot be run because there are command line argument(s): "+($PSBoundParameters.Keys | Where-Object { $_ -match 'skip-db|sd'})) | WriteAndLog
+}
+else {
+ Write-Output ("ACA Database setup cannot be run because there are command line argument(s): " + ($PSBoundParameters.Keys | Where-Object { $_ -match 'skip-db|sd' })) | WriteAndLog
+}
+
+Function setup_aca_public_key_algorithm() {
+ param(
+ [Parameter(Mandatory = $true)]
+ [string]$acaAlg
+ )
+
+ if (-not $acaAlg) {
+ Write-Output "Exiting script while attempting to set the ACA's public key algorithm since the provided ACA Public Key Algorithm
+ do not exist/have not been supplied" | WriteAndLog
+ exit 1
+ }
+
+ $aca_leaf_cert_val = $null
+ $aca_intermediate_cert_val = $null
+ $aca_root_cert_val = $null
+
+ if ($acaAlg -eq "rsa") {
+ $aca_leaf_cert_val = "HIRS_leaf_ca3_rsa_3k_sha384"
+ $aca_intermediate_cert_val = "HIRS_intermediate_ca_rsa_3k_sha384"
+ $aca_root_cert_val = "HIRS_root_ca_rsa_3k_sha384"
+ }
+ elseif($acaAlg -eq "ecc") {
+ $aca_leaf_cert_val = "HIRS_leaf_ca3_ecc_512_sha384"
+ $aca_intermediate_cert_val = "HIRS_intermediate_ca_ecc_512_sha384"
+ $aca_root_cert_val = "HIRS_root_ca_ecc_512_sha384"
+ }
+
+ remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME"
+ remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME"
+ remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME"
+
+ if (-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME")) {
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_ACA_LEAF_CERTIFICATE_ALIAS_NAME=$aca_leaf_cert_val"
+ Write-Output "Stored the $acaAlg ACA Leaf certificate alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ }
+
+ if (-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME")) {
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_ACA_INTERMEDIATE_CERTIFICATE_ALIAS_NAME=$aca_intermediate_cert_val"
+ Write-Output "Stored the $acaAlg ACA Intermediate certificate alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ }
+
+ if (-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME")) {
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_ACA_ROOT_CERTIFICATE_ALIAS_NAME=$aca_root_cert_val"
+ Write-Output "Stored the $acaAlg ACA Root certificate alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ }
+}
+
+Function setup_tls_config_aliases() {
+ param(
+ [Parameter(Mandatory = $true)]
+ [string]$tlsAlg
+ )
+
+ if (-not $tlsAlg) {
+ Write-Output "Exiting script while attempting to set the config file lines for tomcat ssl aliases since the provided TLS
+ do not exist/have not been supplied" | WriteAndLog
+ exit 1
+ }
+
+ $server_ssl_trust_alias_val = $null
+ $server_ssl_key_alias_val = $null
+
+ if ($tlsAlg -eq "rsa") {
+ $server_ssl_trust_alias_val = "hirs_aca_tls_rsa_3k_sha384"
+ $server_ssl_key_alias_val = "hirs_aca_tls_rsa_3k_sha384"
+ }
+ elseif($tlsAlg -eq "ecc") {
+ $server_ssl_trust_alias_val = "hirs_aca_tls_ecc_512_sha384"
+ $server_ssl_key_alias_val = "hirs_aca_tls_ecc_512_sha384"
+ }
+
+ # remove default SSL config lines
+ remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME"
+ remove_spring_property_value_pair -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME"
+
+ if (-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME")) {
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_SSL_TRUST_ALIAS_PROPERTY_NAME=$server_ssl_trust_alias_val"
+ Write-Output "Stored the $tlsAlg SSL Trust Alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ }
+
+ if (-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME")) {
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_SSL_KEY_ALIAS_PROPERTY_NAME=$server_ssl_key_alias_val"
+ Write-Output "Stored the $tlsAlg SSL Key alias property name and value in the Spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ }
}
# Update properties file based upon algorithm choices
diff --git a/package/win/aca/aca_win_config.ps1 b/package/win/aca/aca_win_config.ps1
index 62dc9b6f9..df0bc88d2 100644
--- a/package/win/aca/aca_win_config.ps1
+++ b/package/win/aca/aca_win_config.ps1
@@ -1,8 +1,8 @@
# This script is intended to only be run from within a cloned copy of the HIRS repository from GitHub. It is not meant to be deployed.
# This script swaps configuration files for Windows into place.
-$ACA_SCRIPTS_HOME=(Split-Path -parent $PSCommandPath)
-$ACA_COMMON_SCRIPT=(Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
+$ACA_SCRIPTS_HOME = (Split-Path -parent $PSCommandPath)
+$ACA_COMMON_SCRIPT = (Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
# load common script
. $ACA_COMMON_SCRIPT
diff --git a/package/win/db/db_create.ps1 b/package/win/db/db_create.ps1
index 4bc0abf19..d06721088 100644
--- a/package/win/db/db_create.ps1
+++ b/package/win/db/db_create.ps1
@@ -8,15 +8,15 @@
################################################################################
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$LOG_FILE,
- [switch]$UNATTENDED = $false,
- [Parameter(Mandatory=$true)]
- [string]$DB_ALG
+ [switch]$UNATTENDED = $false,
+ [Parameter(Mandatory = $true)]
+ [string]$DB_ALG
)
-$ACA_SCRIPTS_HOME=(Split-Path -parent $PSCommandPath)
-$ACA_COMMON_SCRIPT=(Join-Path "$ACA_SCRIPTS_HOME" .. aca aca_common.ps1)
+$ACA_SCRIPTS_HOME = (Split-Path -parent $PSCommandPath)
+$ACA_COMMON_SCRIPT = (Join-Path "$ACA_SCRIPTS_HOME" .. aca aca_common.ps1)
# Load other scripts
. $ACA_COMMON_SCRIPT
@@ -30,10 +30,10 @@ read_spring_properties -file "$global:HIRS_DATA_SPRING_PROP_FILE"
# Parameter check
if (-not (Test-Path -Path $LOG_FILE)) {
- New-Item -ItemType File -Path $LOG_FILE
- $global:LOG_FILE=$LOG_FILE
+ New-Item -ItemType File -Path $LOG_FILE
+ $global:LOG_FILE = $LOG_FILE
} else {
- set_up_log
+ set_up_log
}
if (-not (Test-Path -Path $global:HIRS_DATA_ACA_PROPERTIES_FILE)) {
@@ -58,194 +58,198 @@ check_mariadb_install -p
# Check if the the ACA is running inside a Docker container
check_for_container -p
-Function check_mysql_root_pwd () {
- $DB_ADMIN_PWD=""
+Function check_mysql_root_pwd() {
+ $DB_ADMIN_PWD = ""
# Check if DB root password needs to be retrieved from the system environment variable or existing property file
if (!$Env:HIRS_MYSQL_ROOT_PWD) {
Write-Output "Using randomly generated password for the DB admin" | WriteAndLog
- # Attempt to find the mysql password from the aca property file
- $DB_ADMIN_PWD=find_property_value -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME"
-
- # if the value associated with the mysql_admin_password key is empty
- if(!$DB_ADMIN_PWD) {
- Write-Output "No DB Admin password has been found in the properties file [$global:HIRS_DATA_ACA_PROPERTIES_FILE]. The script will now create and set the password for the root user." | WriteAndLog
-
- # Create a 32 character random password
- $DB_ADMIN_PWD=(create_random)
-
- Write-Host "NOT LOGGED: DB Admin password will be set to [$DB_ADMIN_PWD]. Please make note of it for future uses of MYSQL."
-
- # Check if unattended flag is set if not then prompt user for permission to store mysql root password
- if (!$UNATTENDED) {
- $confirm=Read-Host 'Do you wish to save this password to the aca.properties file?'
- if (($confirm -eq "y") -or ($confirm -eq "yes")) { # case-insensitive
- add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME=$DB_ADMIN_PWD"
- Write-Output "A new MYSQL password for the root user has been saved locally." | WriteAndLog
- } else {
- Write-Output "MYSQL password for the root user has not been saved locally" | WriteAndLog
- }
- } else { # unattended install
- add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME=$DB_ADMIN_PWD"
- Write-Output "A new MYSQL password for the root user has been saved locally." | WriteAndLog
- }
- mysqladmin --user=root password "$DB_ADMIN_PWD"
- }
- } else {
- $DB_ADMIN_PWD=$Env:HIRS_MYSQL_ROOT_PWD
+ # Attempt to find the mysql password from the aca property file
+ $DB_ADMIN_PWD = find_property_value -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME"
+
+ # if the value associated with the mysql_admin_password key is empty
+ if (!$DB_ADMIN_PWD) {
+ Write-Output "No DB Admin password has been found in the properties file [$global:HIRS_DATA_ACA_PROPERTIES_FILE]. The script will now create and set the password for the root user." | WriteAndLog
+
+ # Create a 32 character random password
+ $DB_ADMIN_PWD = (create_random)
+
+ Write-Host "NOT LOGGED: DB Admin password will be set to [$DB_ADMIN_PWD]. Please make note of it for future uses of MYSQL."
+
+ # Check if unattended flag is set if not then prompt user for permission to store mysql root password
+ if (!$UNATTENDED) {
+ $confirm = Read-Host 'Do you wish to save this password to the aca.properties file?'
+ if (($confirm -eq "y") -or ($confirm -eq "yes")) {
+ # case-insensitive
+ add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME=$DB_ADMIN_PWD"
+ Write-Output "A new MYSQL password for the root user has been saved locally." | WriteAndLog
+ } else {
+ Write-Output "MYSQL password for the root user has not been saved locally" | WriteAndLog
+ }
+ } else {
+ # unattended install
+ add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_MYSQL_ADMIN_PWD_PROPERTY_NAME=$DB_ADMIN_PWD"
+ Write-Output "A new MYSQL password for the root user has been saved locally." | WriteAndLog
+ }
+ mysqladmin --user=root password "$DB_ADMIN_PWD"
+ }
+ } else {
+ $DB_ADMIN_PWD = $Env:HIRS_MYSQL_ROOT_PWD
Write-Output "Using system variable supplied password" | WriteAndLog
- }
+ }
# Make sure root password is correct
mysql -u root -p"$DB_ADMIN_PWD" -e 'quit' 2>&1 | WriteAndLog
- if ($LastExitCode -eq 0) {
+ if ($LastExitCode -eq 0) {
Write-Output "The supplied MYSQL password for the root user has been verified" | WriteAndLog
} else {
Write-Output "The supplied MYSQL password for the root user was incorrect" | WriteAndLog
Write-Output "********** ACA Mysql setup aborted ********" | WriteAndLog
exit 1
- }
+ }
- return $DB_ADMIN_PWD
+ return $DB_ADMIN_PWD
}
-Function set_mysql_tls () {
- param (
- [Parameter(Mandatory=$true)]
+Function set_mysql_tls() {
+ param (
+ [Parameter(Mandatory = $true)]
[string]$ALG
)
# Check DB server setup. If ssl params dont exist then we need to add them.
- if (!(Get-Content $global:DB_CONF | Select-String "ssl")) {
-
- Write-Output "Updating $global:DB_CONF with $ALG ssl parameters..." | WriteAndLog
- if($ALG -eq "rsa"){
- # Add RSA TLS files to my.ini- Assumes [client] section at the end, and no [server] section
- Write-Output "ssl_ca=$SSL_DB_RSA_CLIENT_CHAIN" >> $global:DB_CONF
- Write-Output "ssl_cert=$SSL_DB_RSA_CLIENT_CERT" >> $global:DB_CONF
- Write-Output "ssl_key=$SSL_DB_RSA_CLIENT_KEY" >> $global:DB_CONF
- Write-Output "[server]" >> $global:DB_CONF
- Write-Output "ssl_ca=$global:SSL_DB_RSA_SRV_CHAIN" >> $global:DB_CONF
- Write-Output "ssl_cert=$global:SSL_DB_RSA_SRV_CERT" >> $global:DB_CONF
- Write-Output "ssl_key=$global:SSL_DB_RSA_SRV_KEY" >> $global:DB_CONF
- }
- elseif ($AlG -eq "ecc") {
- # Add ECC TLS files to my.ini- Assumes [client] section at the end, and no [server] section
- Write-Output "ssl_ca=$SSL_DB_ECC_CLIENT_CHAIN" >> $global:DB_CONF
- Write-Output "ssl_cert=$SSL_DB_ECC_CLIENT_CERT" >> $global:DB_CONF
- Write-Output "ssl_key=$SSL_DB_ECC_CLIENT_KEY" >> $global:DB_CONF
- Write-Output "[server]" >> $global:DB_CONF
- Write-Output "ssl_ca=$global:SSL_DB_ECC_SRV_CHAIN" >> $global:DB_CONF
- Write-Output "ssl_cert=$global:SSL_DB_ECC_SRV_CERT" >> $global:DB_CONF
- Write-Output "ssl_key=$global:SSL_DB_ECC_SRV_KEY" >> $global:DB_CONF
- }
-
- ChangeFileBackslashToForwardSlash -file $global:DB_CONF
- } else {
+ if (!(Get-Content $global:DB_CONF | Select-String "ssl")) {
+
+ Write-Output "Updating $global:DB_CONF with $ALG ssl parameters..." | WriteAndLog
+ if ($ALG -eq "rsa") {
+ # Add RSA TLS files to my.ini- Assumes [client] section at the end, and no [server] section
+ Write-Output "ssl_ca=$SSL_DB_RSA_CLIENT_CHAIN" >> $global:DB_CONF
+ Write-Output "ssl_cert=$SSL_DB_RSA_CLIENT_CERT" >> $global:DB_CONF
+ Write-Output "ssl_key=$SSL_DB_RSA_CLIENT_KEY" >> $global:DB_CONF
+ Write-Output "[server]" >> $global:DB_CONF
+ Write-Output "ssl_ca=$global:SSL_DB_RSA_SRV_CHAIN" >> $global:DB_CONF
+ Write-Output "ssl_cert=$global:SSL_DB_RSA_SRV_CERT" >> $global:DB_CONF
+ Write-Output "ssl_key=$global:SSL_DB_RSA_SRV_KEY" >> $global:DB_CONF
+ }
+ elseif ($AlG -eq "ecc") {
+ # Add ECC TLS files to my.ini- Assumes [client] section at the end, and no [server] section
+ Write-Output "ssl_ca=$SSL_DB_ECC_CLIENT_CHAIN" >> $global:DB_CONF
+ Write-Output "ssl_cert=$SSL_DB_ECC_CLIENT_CERT" >> $global:DB_CONF
+ Write-Output "ssl_key=$SSL_DB_ECC_CLIENT_KEY" >> $global:DB_CONF
+ Write-Output "[server]" >> $global:DB_CONF
+ Write-Output "ssl_ca=$global:SSL_DB_ECC_SRV_CHAIN" >> $global:DB_CONF
+ Write-Output "ssl_cert=$global:SSL_DB_ECC_SRV_CERT" >> $global:DB_CONF
+ Write-Output "ssl_key=$global:SSL_DB_ECC_SRV_KEY" >> $global:DB_CONF
+ }
+
+ ChangeFileBackslashToForwardSlash -file $global:DB_CONF
+ } else {
Write-Output "$global:DB_CONF contains existing entry for ssl. Skipping this step ..." | WriteAndLog
- }
+ }
}
# Process HIRS DB USER
-Function set_hirs_db_pwd () {
+Function set_hirs_db_pwd() {
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$DB_ADMIN_PWD
)
- if (!$DB_ADMIN_PWD) {
- Write-Output "Exiting script since this function has been called without supplying the database admin password" | WriteAndLog
- exit 1
- }
-
- $HIRS_DB_USER_EXISTS = check_hirs_db_user -DB_ADMIN_PWD:"$DB_ADMIN_PWD"
-
- if($HIRS_DB_USER_EXISTS -ne 1){
- $HIRS_DB_PASS=""
-
- #Check if the HIRS DB user password is being retrieved from the system environment ...
- if ($Env:HIRS_DB_PWD) {
- $HIRS_DB_PASS=$Env:HIRS_DB_PWD
- Write-Output "Using hirs_db password found in the environment variable HIRS_DB_PWD" | WriteAndLog
- } else{ #or if we are setting it to a random value
- $HIRS_DB_PASS=(create_random)
- Write-Output "Using randomly generated password for the HIRS_DB key password" | WriteAndLog
- }
-
- if(-not (find_property_value -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_HIRS_DB_USERNAME_PROPERTY_NAME")){
- add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_HIRS_DB_USERNAME_PROPERTY_NAME=hirs_db"
- Write-Output "Stored hirs_db username in the ACA properties file [$global:HIRS_DATA_ACA_PROPERTIES_FILE]" | WriteAndLog
- }
-
- if(-not (find_property_value -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME")){
- add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME=$HIRS_DB_PASS"
- Write-Output "Stored hirs_db password in the ACA properties file [$global:HIRS_DATA_ACA_PROPERTIES_FILE]" | WriteAndLog
- }
-
- if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME")){
- add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME=hirs_db"
- Write-Output "Stored the hibernate connection username in the spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
- }
-
- if(-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME")){
- add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME=$HIRS_DB_PASS"
- Write-Output "Stored the hibernate connection password property in the spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
- }
- }
- else {
- Write-Output "hirs_db user already exists. Skipping this step." | WriteAndLog
- }
+ if (!$DB_ADMIN_PWD) {
+ Write-Output "Exiting script since this function has been called without supplying the database admin password" | WriteAndLog
+ exit 1
+ }
+
+ $HIRS_DB_USER_EXISTS = check_hirs_db_user -DB_ADMIN_PWD:"$DB_ADMIN_PWD"
+
+ if ($HIRS_DB_USER_EXISTS -ne 1) {
+ $HIRS_DB_PASS = ""
+
+ #Check if the HIRS DB user password is being retrieved from the system environment ...
+ if ($Env:HIRS_DB_PWD) {
+ $HIRS_DB_PASS = $Env:HIRS_DB_PWD
+ Write-Output "Using hirs_db password found in the environment variable HIRS_DB_PWD" | WriteAndLog
+ } else {
+ #or if we are setting it to a random value
+ $HIRS_DB_PASS = (create_random)
+ Write-Output "Using randomly generated password for the HIRS_DB key password" | WriteAndLog
+ }
+
+ if (-not (find_property_value -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_HIRS_DB_USERNAME_PROPERTY_NAME")) {
+ add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_HIRS_DB_USERNAME_PROPERTY_NAME=hirs_db"
+ Write-Output "Stored hirs_db username in the ACA properties file [$global:HIRS_DATA_ACA_PROPERTIES_FILE]" | WriteAndLog
+ }
+
+ if (-not (find_property_value -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME")) {
+ add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME=$HIRS_DB_PASS"
+ Write-Output "Stored hirs_db password in the ACA properties file [$global:HIRS_DATA_ACA_PROPERTIES_FILE]" | WriteAndLog
+ }
+
+ if (-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME")) {
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_USERNAME_PROPERTY_NAME=hirs_db"
+ Write-Output "Stored the hibernate connection username in the spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ }
+
+ if (-not (find_property_value -file "$global:HIRS_DATA_SPRING_PROP_FILE" -key "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME")) {
+ add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_HIBERNATE_CONNECTION_PWD_PROPERTY_NAME=$HIRS_DB_PASS"
+ Write-Output "Stored the hibernate connection password property in the spring properties file [$global:HIRS_DATA_SPRING_PROP_FILE]" | WriteAndLog
+ }
+ }
+ else {
+ Write-Output "hirs_db user already exists. Skipping this step." | WriteAndLog
+ }
}
# Create a hirs_db with client side TLS enabled
-Function create_hirs_db_with_tls () {
+Function create_hirs_db_with_tls() {
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$DB_ADMIN_PWD
)
- if (!$DB_ADMIN_PWD) {
- Write-Output "Exiting script since this function has been called without supplying the database admin password" | WriteAndLog
- exit 1
- }
-
- $HIRS_DB_EXISTS = check_hirs_db -DB_ADMIN_PWD "$DB_ADMIN_PWD"
-
- #if the hirs_db has already been created, skip this step
- if($HIRS_DB_EXISTS -eq 1){
- Write-Output "hirs_db already exists. Skipping this step" | WriteAndLog
- } else { #othewrise create the hirs_db
- $HIRS_PASS=find_property_value -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME"
-
- if(!$HIRS_PASS){
- Write-Output "Exiting script since the property file does not have the hirs_db password" | WriteAndLog
- exit 1
- }
-
- Write-Output "Creating hirs_db database" | WriteAndLog
- mysql -u root -p"$DB_ADMIN_PWD" -e "source $global:HIRS_REL_SCRIPTS_DB_CREATE_SQL"
- mysql -u root -p"$DB_ADMIN_PWD" -e "source $global:HIRS_REL_SCRIPTS_DB_SECURE_MYSQL_SQL"
- mysql -u root -p"$DB_ADMIN_PWD" -e "ALTER USER 'hirs_db'@'localhost' IDENTIFIED BY '$HIRS_PASS'; FLUSH PRIVILEGES;"
- Write-Output "Finished creating the hirs_db database and setting the hirs_db pwd using the contents of the file [$global:HIRS_DATA_ACA_PROPERTIES_FILE]"
- }
+ if (!$DB_ADMIN_PWD) {
+ Write-Output "Exiting script since this function has been called without supplying the database admin password" | WriteAndLog
+ exit 1
+ }
+
+ $HIRS_DB_EXISTS = check_hirs_db -DB_ADMIN_PWD "$DB_ADMIN_PWD"
+
+ #if the hirs_db has already been created, skip this step
+ if ($HIRS_DB_EXISTS -eq 1) {
+ Write-Output "hirs_db already exists. Skipping this step" | WriteAndLog
+ } else {
+ #othewrise create the hirs_db
+ $HIRS_PASS = find_property_value -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -key "$global:ACA_PROPERTIES_HIRS_DB_PWD_PROPERTY_NAME"
+
+ if (!$HIRS_PASS) {
+ Write-Output "Exiting script since the property file does not have the hirs_db password" | WriteAndLog
+ exit 1
+ }
+
+ Write-Output "Creating hirs_db database" | WriteAndLog
+ mysql -u root -p"$DB_ADMIN_PWD" -e "source $global:HIRS_REL_SCRIPTS_DB_CREATE_SQL"
+ mysql -u root -p"$DB_ADMIN_PWD" -e "source $global:HIRS_REL_SCRIPTS_DB_SECURE_MYSQL_SQL"
+ mysql -u root -p"$DB_ADMIN_PWD" -e "ALTER USER 'hirs_db'@'localhost' IDENTIFIED BY '$HIRS_PASS'; FLUSH PRIVILEGES;"
+ Write-Output "Finished creating the hirs_db database and setting the hirs_db pwd using the contents of the file [$global:HIRS_DATA_ACA_PROPERTIES_FILE]"
+ }
}
-Function create_hibernate_url () {
+Function create_hibernate_url() {
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$ALG
)
if ($ALG -eq "RSA") {
- $CERT_CHAIN=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_rsa_3k_sha384_Cert_Chain.pem')
- $CLIENT_DB_P12=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_client_rsa_3k_sha384.p12')
+ $CERT_CHAIN = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_rsa_3k_sha384_Cert_Chain.pem')
+ $CLIENT_DB_P12 = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_RSA_PATH 'HIRS_db_client_rsa_3k_sha384.p12')
} elseif ($ALG -eq "ECC") {
- $CERT_CHAIN=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_ecc_512_sha384_Cert_Chain.pem')
- $CLIENT_DB_P12=(Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_db_client_ecc_512_sha384.p12')
+ $CERT_CHAIN = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_ecc_512_sha384_Cert_Chain.pem')
+ $CLIENT_DB_P12 = (Join-Path $global:HIRS_DATA_CERTIFICATES_HIRS_ECC_PATH 'HIRS_db_client_ecc_512_sha384.p12')
}
- $CONNECTOR_URL="hibernate.connection.url=jdbc:mariadb://localhost:3306/hirs_db?autoReconnect=true&user="+$global:ACA_PROPERTIES.'hirs_db_username'+"&password="+$global:ACA_PROPERTIES.'hirs_db_password'+"&sslMode=VERIFY_CA&serverSslCert=$CERT_CHAIN&keyStoreType=PKCS12&keyStorePassword="+$global:ACA_PROPERTIES.'hirs_pki_password'+"&keyStore=$CLIENT_DB_P12" | ChangeBackslashToForwardSlash
+ $CONNECTOR_URL = "hibernate.connection.url=jdbc:mariadb://localhost:3306/hirs_db?autoReconnect=true&user=" + $global:ACA_PROPERTIES.'hirs_db_username' + "&password=" + $global:ACA_PROPERTIES.'hirs_db_password' + "&sslMode=VERIFY_CA&serverSslCert=$CERT_CHAIN&keyStoreType=PKCS12&keyStorePassword=" + $global:ACA_PROPERTIES.'hirs_pki_password' + "&keyStore=$CLIENT_DB_P12" | ChangeBackslashToForwardSlash
# Save connector information to the application win properties file
add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$CONNECTOR_URL"
@@ -258,7 +262,7 @@ set_mysql_tls -ALG "$DB_ALG"
start_mysqlsd -p
# Check for the MariaDB ADMIN password and set the MariaDB password for the root user
-$DB_ADMIN_PWD=check_mysql_root_pwd
+$DB_ADMIN_PWD = check_mysql_root_pwd
# Set the password for the hirs_db user in the aca properties and spring properties files
set_hirs_db_pwd -DB_ADMIN_PWD "$DB_ADMIN_PWD"
diff --git a/package/win/db/db_drop.ps1 b/package/win/db/db_drop.ps1
index 2f8583e0e..83dfe0ab2 100644
--- a/package/win/db/db_drop.ps1
+++ b/package/win/db/db_drop.ps1
@@ -1,21 +1,21 @@
# Helper ps1 script to the aca_remove_setup that drops the hirs_db database
param(
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string] $DB_ADMIN_PWD
)
-if(!(New-Object Security.Principal.WindowsPrincipal(
- [Security.Principal.WindowsIdentity]::GetCurrent())
- ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
- Write-Host "This script requires root. Please run as root"
- exit 1
+if (!(New-Object Security.Principal.WindowsPrincipal(
+[Security.Principal.WindowsIdentity]::GetCurrent())
+).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
+ Write-Host "This script requires root. Please run as root"
+ exit 1
}
Write-Host "Dropping the hirs_db database"
$ACA_SCRIPTS_HOME = Join-Path -Path (Split-Path -Parent $PSCommandPath) -ChildPath "..\aca"
-$ACA_COMMON_SCRIPT=(Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
+$ACA_COMMON_SCRIPT = (Join-Path $ACA_SCRIPTS_HOME 'aca_common.ps1')
# load other scripts
. $ACA_COMMON_SCRIPT
diff --git a/package/win/pki/pki_chain_gen.ps1 b/package/win/pki/pki_chain_gen.ps1
index d583b6388..2a9206a43 100644
--- a/package/win/pki/pki_chain_gen.ps1
+++ b/package/win/pki/pki_chain_gen.ps1
@@ -15,22 +15,22 @@
# A KeyStore and Trust Store are created for by Java Applications. Both will use the supplied password.
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$ACTOR,
- [Parameter(Mandatory=$true)]
- [string]$ASYM_ALG,
- [Parameter(Mandatory=$true)]
- [string]$ASYM_SIZE,
- [Parameter(Mandatory=$true)]
- [string]$HASH_ALG,
- [Parameter(Mandatory=$true)]
- [string]$PASS,
- [Parameter(Mandatory=$true)]
- [string]$LOG_FILE
+ [Parameter(Mandatory = $true)]
+ [string]$ASYM_ALG,
+ [Parameter(Mandatory = $true)]
+ [string]$ASYM_SIZE,
+ [Parameter(Mandatory = $true)]
+ [string]$HASH_ALG,
+ [Parameter(Mandatory = $true)]
+ [string]$PASS,
+ [Parameter(Mandatory = $true)]
+ [string]$LOG_FILE
)
-$ACA_SCRIPTS_HOME=(Split-Path -parent $PSCommandPath)
-$ACA_COMMON_SCRIPT=(Join-Path $ACA_SCRIPTS_HOME '..' 'aca' 'aca_common.ps1')
+$ACA_SCRIPTS_HOME = (Split-Path -parent $PSCommandPath)
+$ACA_COMMON_SCRIPT = (Join-Path $ACA_SCRIPTS_HOME '..' 'aca' 'aca_common.ps1')
# Load other scripts
. $ACA_COMMON_SCRIPT
@@ -40,90 +40,90 @@ read_aca_properties $global:HIRS_DATA_ACA_PROPERTIES_FILE
# Parameter check
if (!$ACTOR -or !$ASYM_ALG -or !$ASYM_SIZE -or !$HASH_ALG -or ($ACTOR -eq "-h") -or ($ACTOR -eq "--help")) {
- Write-Output "parameter missing to pki_chain_gen.sh, exiting pki setup" | WriteAndLog
- exit 1;
+ Write-Output "parameter missing to pki_chain_gen.sh, exiting pki setup" | WriteAndLog
+ exit 1;
}
if ($LOG_FILE) {
- $global:LOG_FILE=$LOG_FILE
+ $global:LOG_FILE = $LOG_FILE
} else {
- set_up_log
+ set_up_log
}
-$ACTOR_ALT=("$ACTOR" -replace " ","_")
-$ROOT_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR test root ca"
-$INT_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR test intermediate ca"
-$LEAF_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR test ca"
-$SIGNER_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR test signer"
-$SERVER_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR aca"
-$TRUSTSTORE="$global:HIRS_DATA_CERTIFICATES_DIR\$ACTOR_ALT\TrustStore.jks"
-$TRUSTSTORE_P12="$global:HIRS_DATA_CERTIFICATES_DIR\$ACTOR_ALT\TrustStore.p12"
-$KEYSTORE="$global:HIRS_DATA_CERTIFICATES_DIR\$ACTOR_ALT\KeyStore.jks"
+$ACTOR_ALT = ("$ACTOR" -replace " ", "_")
+$ROOT_DN = "/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR test root ca"
+$INT_DN = "/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR test intermediate ca"
+$LEAF_DN = "/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR test ca"
+$SIGNER_DN = "/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR test signer"
+$SERVER_DN = "/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$ACTOR aca"
+$TRUSTSTORE = "$global:HIRS_DATA_CERTIFICATES_DIR\$ACTOR_ALT\TrustStore.jks"
+$TRUSTSTORE_P12 = "$global:HIRS_DATA_CERTIFICATES_DIR\$ACTOR_ALT\TrustStore.p12"
+$KEYSTORE = "$global:HIRS_DATA_CERTIFICATES_DIR\$ACTOR_ALT\KeyStore.jks"
if (($ASYM_ALG -ne "rsa") -and ($ASYM_ALG -ne "ecc")) {
- Write-Output "$ASYM_ALG is an unsupported assymetric algorithm, exiting pki setup" | WriteAndLog
- exit 1;
+ Write-Output "$ASYM_ALG is an unsupported assymetric algorithm, exiting pki setup" | WriteAndLog
+ exit 1;
}
switch ($ASYM_SIZE) {
- 256 {
- $KSIZE="256"
- $ECC_NAME="secp256k1"
- Break
- }
+ 256 {
+ $KSIZE = "256"
+ $ECC_NAME = "secp256k1"
+ Break
+ }
384 {
- $KSIZE="384"
- $ECC_NAME="secp384r1"
- Break
- }
+ $KSIZE = "384"
+ $ECC_NAME = "secp384r1"
+ Break
+ }
512 {
- $KSIZE="512"
- $ECC_NAME="secp521r1"
- Break
- }
+ $KSIZE = "512"
+ $ECC_NAME = "secp521r1"
+ Break
+ }
2048 {
- $KSIZE="2k"
- Break
- }
+ $KSIZE = "2k"
+ Break
+ }
3072 {
- $KSIZE="3k"
- Break
- }
+ $KSIZE = "3k"
+ Break
+ }
4096 {
- $KSIZE="4k"
- Break
- }
+ $KSIZE = "4k"
+ Break
+ }
Default {
Write-Output "$ASYM_SIZE is an unsupported key size, exiting pki setup" | WriteAndLog
exit 1
- }
+ }
}
# Use algorithm and key size to create unique file paths and Distinguished names
-$NAME="$ACTOR $ASYM_ALG $KSIZE $HASH_ALG"
-$CERT_FOLDER="$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"+"_certs"
-$PKI_ROOT="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_"+"root_ca_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
-$PKI_INT="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_intermediate_ca_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
-$PKI_CA1="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_leaf_ca1_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
-$PKI_CA2="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_leaf_ca2_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
-$PKI_CA3="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_leaf_ca3_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
-$RIM_SIGNER="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_rim_signer_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
-$TLS_SERVER="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_aca_tls_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
-$DB_SERVER="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_db_srv_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
-$DB_CLIENT="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_db_client"+"_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"
-$TRUST_STORE_FILE="$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT"+"_"+"$ASYM_ALG"+"_"+"$KSIZE"+"_"+"$HASH_ALG"+"_Cert_Chain.pem"
-
-$ROOT_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME test root ca"
-$INT_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME test intermediate ca"
-$LEAF_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME test ca"
-$SIGNER_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME test signer"
-$TLS_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME portal"
-$DB_SRV_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME DB Server"
-$DB_CLIENT_DN="/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME DB Client"
+$NAME = "$ACTOR $ASYM_ALG $KSIZE $HASH_ALG"
+$CERT_FOLDER = "$ASYM_ALG" + "_" + "$KSIZE" + "_" + "$HASH_ALG" + "_certs"
+$PKI_ROOT = "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT" + "_" + "root_ca_" + "$ASYM_ALG" + "_" + "$KSIZE" + "_" + "$HASH_ALG"
+$PKI_INT = "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT" + "_intermediate_ca_" + "$ASYM_ALG" + "_" + "$KSIZE" + "_" + "$HASH_ALG"
+$PKI_CA1 = "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT" + "_leaf_ca1_" + "$ASYM_ALG" + "_" + "$KSIZE" + "_" + "$HASH_ALG"
+$PKI_CA2 = "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT" + "_leaf_ca2_" + "$ASYM_ALG" + "_" + "$KSIZE" + "_" + "$HASH_ALG"
+$PKI_CA3 = "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT" + "_leaf_ca3_" + "$ASYM_ALG" + "_" + "$KSIZE" + "_" + "$HASH_ALG"
+$RIM_SIGNER = "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT" + "_rim_signer_" + "$ASYM_ALG" + "_" + "$KSIZE" + "_" + "$HASH_ALG"
+$TLS_SERVER = "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT" + "_aca_tls_" + "$ASYM_ALG" + "_" + "$KSIZE" + "_" + "$HASH_ALG"
+$DB_SERVER = "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT" + "_db_srv_" + "$ASYM_ALG" + "_" + "$KSIZE" + "_" + "$HASH_ALG"
+$DB_CLIENT = "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT" + "_db_client" + "_" + "$ASYM_ALG" + "_" + "$KSIZE" + "_" + "$HASH_ALG"
+$TRUST_STORE_FILE = "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\$CERT_FOLDER\$ACTOR_ALT" + "_" + "$ASYM_ALG" + "_" + "$KSIZE" + "_" + "$HASH_ALG" + "_Cert_Chain.pem"
+
+$ROOT_DN = "/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME test root ca"
+$INT_DN = "/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME test intermediate ca"
+$LEAF_DN = "/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME test ca"
+$SIGNER_DN = "/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME test signer"
+$TLS_DN = "/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME portal"
+$DB_SRV_DN = "/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME DB Server"
+$DB_CLIENT_DN = "/C=US/ST=MD/L=Columbia/O=$ACTOR/CN=$NAME DB Client"
# Add check for existing folder and halt if it exists
-if ([System.IO.Directory]::Exists("$ACTOR_ALT/$CERT_FOLDER")) {
- Write-Output "Folder for $CERT_FOLDER exists, exiting..." | WriteAndLog
- exit 1
+if ( [System.IO.Directory]::Exists("$ACTOR_ALT/$CERT_FOLDER")) {
+ Write-Output "Folder for $CERT_FOLDER exists, exiting..." | WriteAndLog
+ exit 1
}
# Intialize sub folders
@@ -147,31 +147,31 @@ if (-not (Test-Path "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\openssl-san.cnf"))
}
if (![System.IO.File]::Exists("$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\ca\serial.txt")) {
- Write-Output "01" > "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\ca\serial.txt" | WriteAndLog
+ Write-Output "01" > "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\ca\serial.txt" | WriteAndLog
}
# Function to add Cert to Truststore and key to Keystore
-Function add_to_stores () {
+Function add_to_stores() {
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$CERT_PATH
)
- $ALIAS=[System.IO.Path]::GetFileName($CERT_PATH) # Use filename without path as an alias
- Write-Output "$CERT_PATH key objects will use the alias `"$ALIAS`" in trust stores." | WriteAndLog
- Write-Output "Exporting key and certificate to PKCS12." | WriteAndLog
+ $ALIAS = [System.IO.Path]::GetFileName($CERT_PATH) # Use filename without path as an alias
+ Write-Output "$CERT_PATH key objects will use the alias `"$ALIAS`" in trust stores." | WriteAndLog
+ Write-Output "Exporting key and certificate to PKCS12." | WriteAndLog
# Add the cert and key to the key store.. make a p12 file to import into te keystore
openssl pkcs12 -export -in "$CERT_PATH.pem" -inkey "$CERT_PATH.key" -out "tmpkey.p12" -passin "pass:$PASS" -macalg SHA256 -keypbe AES-256-CBC -certpbe AES-256-CBC -passout "pass:$PASS" 2>&1 | WriteAndLog
- Write-Output "Adding $ALIAS to the $KEYSTORE" | WriteAndLog
- # Use the p12 file to import into a java keystore via keytool
+ Write-Output "Adding $ALIAS to the $KEYSTORE" | WriteAndLog
+ # Use the p12 file to import into a java keystore via keytool
keytool -importkeystore -srckeystore "tmpkey.p12" -destkeystore $KEYSTORE -srcstoretype pkcs12 -srcstorepass $PASS -deststoretype jks -deststorepass $PASS -noprompt -alias 1 -destalias "$ALIAS" 2>&1 | WriteAndLog
- Write-Output "Adding $ALIAS to the $TRUSTSTORE" | WriteAndLog
- # Import the cert into a java trust store via keytool
+ Write-Output "Adding $ALIAS to the $TRUSTSTORE" | WriteAndLog
+ # Import the cert into a java trust store via keytool
keytool -import -keystore $TRUSTSTORE -storepass $PASS -file "$CERT_PATH.pem" -noprompt -alias "$ALIAS" 2>&1 | WriteAndLog
# Remove the temp p1 file.
- Write-Output "Cleaning up after storing $ALIAS" | WriteAndLog
- Remove-Item "tmpkey.p12"
-}
+ Write-Output "Cleaning up after storing $ALIAS" | WriteAndLog
+ Remove-Item "tmpkey.p12"
+}
# Function to create an Intermediate Key, CSR, and Certificate
# PARMS:
@@ -179,136 +179,136 @@ Function add_to_stores () {
# 2. Issuer Key File Name
# 3. Subject Distinguished Name String
-Function create_cert () {
+Function create_cert() {
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$CERT_PATH,
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$ISSUER,
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$SUBJ_DN,
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$EXTENSION
)
-
- $ISSUER_KEY="$ISSUER.key"
- $ISSUER_CERT="$ISSUER.pem"
- $ALIAS=[System.IO.Path]::GetFileName($CERT_PATH) # Use filename without path as an alias
- Write-Output "Creating key pair and CSR with DN=`"$SUBJ_DN`"." | WriteAndLog
- Write-Output " Key pair will be saved at location $CERT_PATH\" | WriteAndLog
- Write-Output " Key will use $ASYM_ALG $ASYM_SIZE and HASH Alg $HASH_ALG" | WriteAndLog
- Write-Output " Certificate will be issued by $ISSUER_CERT and its key $ISSUER_KEY." | WriteAndLog
- Write-Output " Key objects will use the alias `"$ALIAS`" in trust stores." | WriteAndLog
+
+ $ISSUER_KEY = "$ISSUER.key"
+ $ISSUER_CERT = "$ISSUER.pem"
+ $ALIAS = [System.IO.Path]::GetFileName($CERT_PATH) # Use filename without path as an alias
+ Write-Output "Creating key pair and CSR with DN=`"$SUBJ_DN`"." | WriteAndLog
+ Write-Output " Key pair will be saved at location $CERT_PATH\" | WriteAndLog
+ Write-Output " Key will use $ASYM_ALG $ASYM_SIZE and HASH Alg $HASH_ALG" | WriteAndLog
+ Write-Output " Certificate will be issued by $ISSUER_CERT and its key $ISSUER_KEY." | WriteAndLog
+ Write-Output " Key objects will use the alias `"$ALIAS`" in trust stores." | WriteAndLog
# Database doesnt support encypted key so create DB without passwords
- if ("$SUBJ_DN" -match "DB") {
- Write-Output "This key is intended for use with the database." | WriteAndLog
- if ("$ASYM_ALG" -eq "rsa") {
+ if ("$SUBJ_DN" -match "DB") {
+ Write-Output "This key is intended for use with the database." | WriteAndLog
+ if ("$ASYM_ALG" -eq "rsa") {
openssl genrsa -out "$CERT_PATH.key" "$ASYM_SIZE" 2>&1 | WriteAndLog
openssl req -new -key "$CERT_PATH.key" -out "$CERT_PATH.csr" -subj "$SUBJ_DN" 2>&1 | WriteAndLog
- } else {
- openssl ecparam -genkey -name "$ECC_NAME" -out "$CERT_PATH.key" 2>&1 | WriteAndLog
- openssl req -new -key "$CERT_PATH.key" -out "$CERT_PATH.csr" -$HASH_ALG -subj "$SUBJ_DN" 2>&1 | WriteAndLog
- }
- } else {
- if ("$ASYM_ALG" -eq "rsa") {
+ } else {
+ openssl ecparam -genkey -name "$ECC_NAME" -out "$CERT_PATH.key" 2>&1 | WriteAndLog
+ openssl req -new -key "$CERT_PATH.key" -out "$CERT_PATH.csr" -$HASH_ALG -subj "$SUBJ_DN" 2>&1 | WriteAndLog
+ }
+ } else {
+ if ("$ASYM_ALG" -eq "rsa") {
openssl req -newkey rsa:"$ASYM_SIZE" -keyout "$CERT_PATH.key" -out "$CERT_PATH.csr" -subj "$SUBJ_DN" -passout "pass:$PASS" 2>&1 | WriteAndLog
- } else {
- openssl genpkey -algorithm "EC" -pkeyopt ec_paramgen_curve:P-521 -aes256 --pass "pass:$PASS" -out "$CERT_PATH.key" 2>&1 | WriteAndLog
- openssl req -new -key "$CERT_PATH.key" -passin "pass:$PASS" -out "$CERT_PATH.csr" -$HASH_ALG -subj "$SUBJ_DN" 2>&1 | WriteAndLog
- }
- }
-
- Write-Output "Sending CSR to the CA." | WriteAndLog
- Push-Location "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR" | WriteAndLog
- openssl ca -config ca.conf -keyfile "$ISSUER_KEY" -md $HASH_ALG -cert "$ISSUER_CERT" -extensions "$EXTENSION" -out "$CERT_PATH.pem" -in "$CERT_PATH.csr" -passin "pass:$PASS" -batch -notext 2>&1 | WriteAndLog
- Pop-Location | WriteAndLog
+ } else {
+ openssl genpkey -algorithm "EC" -pkeyopt ec_paramgen_curve:P-521 -aes256 --pass "pass:$PASS" -out "$CERT_PATH.key" 2>&1 | WriteAndLog
+ openssl req -new -key "$CERT_PATH.key" -passin "pass:$PASS" -out "$CERT_PATH.csr" -$HASH_ALG -subj "$SUBJ_DN" 2>&1 | WriteAndLog
+ }
+ }
+
+ Write-Output "Sending CSR to the CA." | WriteAndLog
+ Push-Location "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR" | WriteAndLog
+ openssl ca -config ca.conf -keyfile "$ISSUER_KEY" -md $HASH_ALG -cert "$ISSUER_CERT" -extensions "$EXTENSION" -out "$CERT_PATH.pem" -in "$CERT_PATH.csr" -passin "pass:$PASS" -batch -notext 2>&1 | WriteAndLog
+ Pop-Location | WriteAndLog
# Increment the cert serial number
- $SERIAL=(Get-Content "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\ca\serial.txt")
+ $SERIAL = (Get-Content "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR\ca\serial.txt")
Write-Output "Cert Serial Number = $SERIAL" | WriteAndLog
- Write-Output "Exporting key and certificate to PKCS12." | WriteAndLog
- # Add the cert and key to the key store. make a p12 file to import into te keystore
- openssl pkcs12 -export -in "$CERT_PATH.pem" -inkey "$CERT_PATH.key" -out "tmpkey.p12" -passin "pass:$PASS" -macalg SHA256 -keypbe AES-256-CBC -certpbe AES-256-CBC -passout "pass:$PASS" 2>&1 | WriteAndLog
- Write-Output "Adding $ALIAS to $KEYSTORE" | WriteAndLog
- # Use the p12 file to import into a java keystore via keytool
- keytool -importkeystore -srckeystore "tmpkey.p12" -destkeystore $KEYSTORE -srcstoretype pkcs12 -srcstorepass $PASS -deststoretype jks -deststorepass $PASS -noprompt -alias 1 -destalias "$ALIAS" 2>&1 | WriteAndLog
+ Write-Output "Exporting key and certificate to PKCS12." | WriteAndLog
+ # Add the cert and key to the key store. make a p12 file to import into te keystore
+ openssl pkcs12 -export -in "$CERT_PATH.pem" -inkey "$CERT_PATH.key" -out "tmpkey.p12" -passin "pass:$PASS" -macalg SHA256 -keypbe AES-256-CBC -certpbe AES-256-CBC -passout "pass:$PASS" 2>&1 | WriteAndLog
+ Write-Output "Adding $ALIAS to $KEYSTORE" | WriteAndLog
+ # Use the p12 file to import into a java keystore via keytool
+ keytool -importkeystore -srckeystore "tmpkey.p12" -destkeystore $KEYSTORE -srcstoretype pkcs12 -srcstorepass $PASS -deststoretype jks -deststorepass $PASS -noprompt -alias 1 -destalias "$ALIAS" 2>&1 | WriteAndLog
# Import the cert into a java trust store via keytool
- Write-Output "Adding $ALIAS to $TRUSTSTORE" | WriteAndLog
- keytool -import -keystore $TRUSTSTORE -storepass $PASS -file "$CERT_PATH.pem" -noprompt -alias "$ALIAS" 2>&1 | WriteAndLog
- Write-Output "Cleaning up after storing $ALIAS" | WriteAndLog
- # Remove the temp p12 file.
+ Write-Output "Adding $ALIAS to $TRUSTSTORE" | WriteAndLog
+ keytool -import -keystore $TRUSTSTORE -storepass $PASS -file "$CERT_PATH.pem" -noprompt -alias "$ALIAS" 2>&1 | WriteAndLog
+ Write-Output "Cleaning up after storing $ALIAS" | WriteAndLog
+ # Remove the temp p12 file.
Remove-Item "tmpkey.p12"# remove csr file
Remove-Item "$CERT_PATH.csr"
}
-Function create_cert_chain () {
+Function create_cert_chain() {
- # Create an intermediate CA, Sign with Root CA
- create_cert "$PKI_INT" "$PKI_ROOT" "$INT_DN" "ca_extensions"
+ # Create an intermediate CA, Sign with Root CA
+ create_cert "$PKI_INT" "$PKI_ROOT" "$INT_DN" "ca_extensions"
- # Create a Leaf CA (CA1), Sign with intermediate CA
- create_cert "$PKI_CA1" "$PKI_INT" ("$LEAF_DN"+1) "ca_extensions"
+ # Create a Leaf CA (CA1), Sign with intermediate CA
+ create_cert "$PKI_CA1" "$PKI_INT" ("$LEAF_DN" + 1) "ca_extensions"
- # Create a Leaf CA (CA2), Sign with intermediate CA
- create_cert "$PKI_CA2" "$PKI_INT" ("$LEAF_DN"+2) "ca_extensions"
+ # Create a Leaf CA (CA2), Sign with intermediate CA
+ create_cert "$PKI_CA2" "$PKI_INT" ("$LEAF_DN" + 2) "ca_extensions"
- # Create a Leaf CA (CA3), Sign with intermediate CA
- create_cert "$PKI_CA3" "$PKI_INT" ("$LEAF_DN"+3) "ca_extensions"
+ # Create a Leaf CA (CA3), Sign with intermediate CA
+ create_cert "$PKI_CA3" "$PKI_INT" ("$LEAF_DN" + 3) "ca_extensions"
- # Create a RIM Signer
- create_cert "$RIM_SIGNER" "$PKI_CA2" "$SIGNER_DN" "signer_extensions"
+ # Create a RIM Signer
+ create_cert "$RIM_SIGNER" "$PKI_CA2" "$SIGNER_DN" "signer_extensions"
- # Create a ACA Sever Cert for TLS use
- create_cert "$TLS_SERVER" "$PKI_CA3" "$TLS_DN" "server_extensions"
+ # Create a ACA Sever Cert for TLS use
+ create_cert "$TLS_SERVER" "$PKI_CA3" "$TLS_DN" "server_extensions"
- # Create a DB Sever Cert for TLS use
- create_cert "$DB_SERVER" "$PKI_CA3" "$DB_SRV_DN" "server_extensions"
+ # Create a DB Sever Cert for TLS use
+ create_cert "$DB_SERVER" "$PKI_CA3" "$DB_SRV_DN" "server_extensions"
- # Create a ACA Sever Cert for TLS use
- create_cert "$DB_CLIENT" "$PKI_CA3" "$DB_CLIENT_DN" "server_extensions"
+ # Create a ACA Sever Cert for TLS use
+ create_cert "$DB_CLIENT" "$PKI_CA3" "$DB_CLIENT_DN" "server_extensions"
Write-Output "Creating concatenated PEM file." | WriteAndLog
- # Create Cert trust store by adding the Intermediate and root certs
- Get-Content "$PKI_CA1.pem", "$PKI_CA2.pem", "$PKI_CA3.pem", "$PKI_INT.pem", "$PKI_ROOT.pem" | Set-Content "$TRUST_STORE_FILE"
+ # Create Cert trust store by adding the Intermediate and root certs
+ Get-Content "$PKI_CA1.pem", "$PKI_CA2.pem", "$PKI_CA3.pem", "$PKI_INT.pem", "$PKI_ROOT.pem" | Set-Content "$TRUST_STORE_FILE"
Write-Output "Verifying the concatenated PEM file works." | WriteAndLog
- # Checking signer cert using trust store...
- openssl verify -CAfile "$TRUST_STORE_FILE" "$RIM_SIGNER.pem" | WriteAndLog
+ # Checking signer cert using trust store...
+ openssl verify -CAfile "$TRUST_STORE_FILE" "$RIM_SIGNER.pem" | WriteAndLog
Write-Output "Creating a PKCS12 file for the database client." | WriteAndLog
- # Make JKS files for the mysql DB connector. P12 first then JKS...
- openssl pkcs12 -export -in "$DB_CLIENT.pem" -inkey "$DB_CLIENT.key" -macalg SHA256 -keypbe AES-256-CBC -certpbe AES-256-CBC -passin "pass:$PASS" -passout "pass:$PASS" -name "mysqlclientkey" -out "$DB_CLIENT.p12" 2>&1 | WriteAndLog
+ # Make JKS files for the mysql DB connector. P12 first then JKS...
+ openssl pkcs12 -export -in "$DB_CLIENT.pem" -inkey "$DB_CLIENT.key" -macalg SHA256 -keypbe AES-256-CBC -certpbe AES-256-CBC -passin "pass:$PASS" -passout "pass:$PASS" -name "mysqlclientkey" -out "$DB_CLIENT.p12" 2>&1 | WriteAndLog
Write-Output "Converting the database client PKCS12 file to JKS." | WriteAndLog
- keytool -importkeystore -srckeystore "$DB_CLIENT.p12" -srcstoretype PKCS12 -srcstorepass $PASS -destkeystore "$DB_CLIENT.jks" -deststoretype jks -deststorepass $PASS 2>&1 | WriteAndLog
+ keytool -importkeystore -srckeystore "$DB_CLIENT.p12" -srcstoretype PKCS12 -srcstorepass $PASS -destkeystore "$DB_CLIENT.jks" -deststoretype jks -deststorepass $PASS 2>&1 | WriteAndLog
}
if ("$ASYM_ALG" -eq "rsa") {
- # Create Root CA key pair and self signed cert
- Write-Output "Generating RSA Root CA ...." | WriteAndLog
- openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -aes256 --pass "pass:$PASS" -out "$PKI_ROOT.key" 2>&1 | WriteAndLog
-
- # Create a self signed CA certificate
- Push-Location "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR" | WriteAndLog
- openssl req -new -config ca.conf -x509 -days 3650 -key "$PKI_ROOT.key" -subj "$ROOT_DN" -extensions ca_extensions -out "$PKI_ROOT.pem" -passin "pass:$PASS" 2>&1 | WriteAndLog
- Pop-Location | WriteAndLog
- # Add the CA root cert to the Trust and Key stores
- add_to_stores "$PKI_ROOT"
- # Create an intermediate CA, 2 Leaf CAs, and Signer Certs
- create_cert_chain
+ # Create Root CA key pair and self signed cert
+ Write-Output "Generating RSA Root CA ...." | WriteAndLog
+ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -aes256 --pass "pass:$PASS" -out "$PKI_ROOT.key" 2>&1 | WriteAndLog
+
+ # Create a self signed CA certificate
+ Push-Location "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR" | WriteAndLog
+ openssl req -new -config ca.conf -x509 -days 3650 -key "$PKI_ROOT.key" -subj "$ROOT_DN" -extensions ca_extensions -out "$PKI_ROOT.pem" -passin "pass:$PASS" 2>&1 | WriteAndLog
+ Pop-Location | WriteAndLog
+ # Add the CA root cert to the Trust and Key stores
+ add_to_stores "$PKI_ROOT"
+ # Create an intermediate CA, 2 Leaf CAs, and Signer Certs
+ create_cert_chain
}
if ("$ASYM_ALG" -eq "ecc") {
- # Create Root CA key pair and self signed cert
- Write-Output "Generating Ecc Root CA ...." | WriteAndLog
- openssl genpkey -algorithm "EC" -pkeyopt ec_paramgen_curve:P-521 -aes256 --pass "pass:$PASS" -out "$PKI_ROOT.key" 2>&1 | WriteAndLog
-
- # Create a self signed CA certificate
- Push-Location "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR" | WriteAndLog
- openssl req -new -config ca.conf -x509 -days 3650 -key "$PKI_ROOT.key" -subj "$ROOT_DN" -extensions ca_extensions -out "$PKI_ROOT.pem" -passin "pass:$PASS" 2>&1 | WriteAndLog
- Pop-Location | WriteAndLog
- # Add the CA root cert to the Trust and Key stores
- add_to_stores "$PKI_ROOT"
- # Create an intermediate CA, 2 Leaf CAs, and Signer Certs
- create_cert_chain
+ # Create Root CA key pair and self signed cert
+ Write-Output "Generating Ecc Root CA ...." | WriteAndLog
+ openssl genpkey -algorithm "EC" -pkeyopt ec_paramgen_curve:P-521 -aes256 --pass "pass:$PASS" -out "$PKI_ROOT.key" 2>&1 | WriteAndLog
+
+ # Create a self signed CA certificate
+ Push-Location "$global:HIRS_DATA_CERTIFICATES_HIRS_DIR" | WriteAndLog
+ openssl req -new -config ca.conf -x509 -days 3650 -key "$PKI_ROOT.key" -subj "$ROOT_DN" -extensions ca_extensions -out "$PKI_ROOT.pem" -passin "pass:$PASS" 2>&1 | WriteAndLog
+ Pop-Location | WriteAndLog
+ # Add the CA root cert to the Trust and Key stores
+ add_to_stores "$PKI_ROOT"
+ # Create an intermediate CA, 2 Leaf CAs, and Signer Certs
+ create_cert_chain
}
\ No newline at end of file
diff --git a/package/win/pki/pki_setup.ps1 b/package/win/pki/pki_setup.ps1
index ea7453fa2..e5ccbdee5 100644
--- a/package/win/pki/pki_setup.ps1
+++ b/package/win/pki/pki_setup.ps1
@@ -7,14 +7,14 @@
############################################################################################
param (
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory = $true)]
[string]$LOG_FILE,
- [Parameter(Mandatory=$true)]
- [string]$PKI_PASS
+ [Parameter(Mandatory = $true)]
+ [string]$PKI_PASS
)
-$ACA_SCRIPTS_HOME=(Split-Path -parent $PSCommandPath)
-$ACA_COMMON_SCRIPT=(Join-Path "$ACA_SCRIPTS_HOME" .. aca aca_common.ps1)
+$ACA_SCRIPTS_HOME = (Split-Path -parent $PSCommandPath)
+$ACA_COMMON_SCRIPT = (Join-Path "$ACA_SCRIPTS_HOME" .. aca aca_common.ps1)
# Load other scripts
. $ACA_COMMON_SCRIPT
@@ -27,50 +27,50 @@ read_spring_properties -file "$global:HIRS_DATA_SPRING_PROP_FILE"
# Parameter check
if (-not (Test-Path -Path $LOG_FILE)) {
- New-Item -ItemType File -Path $LOG_FILE
- $global:LOG_FILE=$LOG_FILE
+ New-Item -ItemType File -Path $LOG_FILE
+ $global:LOG_FILE = $LOG_FILE
} else {
- set_up_log
+ set_up_log
}
if (!$PKI_PASS) {
- if ($Env:HIRS_PKI_PWD) {
- $PKI_PASS=$Env:HIRS_PKI_PWD
- } else {
- $PKI_PASS=(create_random)
- Write-Output "Using randomly generated password for the PKI key password" | WriteAndLog
- }
+ if ($Env:HIRS_PKI_PWD) {
+ $PKI_PASS = $Env:HIRS_PKI_PWD
+ } else {
+ $PKI_PASS = (create_random)
+ Write-Output "Using randomly generated password for the PKI key password" | WriteAndLog
+ }
}
New-Item -ItemType Directory -Path $global:HIRS_CONF_DIR -Force | Out-Null
Write-Output "APP_HOME is $ACA_SCRIPTS_HOME" | WriteAndLog
# Check for sudo or root user
-if(!(New-Object Security.Principal.WindowsPrincipal(
- [Security.Principal.WindowsIdentity]::GetCurrent())
- ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
- Write-Output "This script requires root. Please run as root" | WriteAndLog
- exit 1
+if (!(New-Object Security.Principal.WindowsPrincipal(
+[Security.Principal.WindowsIdentity]::GetCurrent())
+).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
+ Write-Output "This script requires root. Please run as root" | WriteAndLog
+ exit 1
}
# Create Cert Chains
if (![System.IO.Directory]::Exists($global:HIRS_DATA_CERTIFICATES_DIR)) {
- if ([System.IO.Directory]::Exists($global:HIRS_REL_WIN_PKI_HOME)) {
- $PKI_SETUP_DIR=$global:HIRS_REL_WIN_PKI_HOME
- } else {
- $PKI_SETUP_DIR=$ACA_SCRIPTS_HOME
- }
- Write-Output "PKI_SETUP_DIR is $PKI_SETUP_DIR" | WriteAndLog
+ if ( [System.IO.Directory]::Exists($global:HIRS_REL_WIN_PKI_HOME)) {
+ $PKI_SETUP_DIR = $global:HIRS_REL_WIN_PKI_HOME
+ } else {
+ $PKI_SETUP_DIR = $ACA_SCRIPTS_HOME
+ }
+ Write-Output "PKI_SETUP_DIR is $PKI_SETUP_DIR" | WriteAndLog
New-Item -ItemType Directory -Path $global:HIRS_DATA_CERTIFICATES_DIR -Force | Out-Null
Copy-Item $PKI_SETUP_DIR\ca.conf $global:HIRS_DATA_CERTIFICATES_DIR
- pwsh -ExecutionPolicy Bypass $PKI_SETUP_DIR/pki_chain_gen.ps1 "HIRS" "rsa" "3072" "sha384" "$PKI_PASS" "$global:LOG_FILE"
+ pwsh -ExecutionPolicy Bypass $PKI_SETUP_DIR/pki_chain_gen.ps1 "HIRS" "rsa" "3072" "sha384" "$PKI_PASS" "$global:LOG_FILE"
pwsh -ExecutionPolicy Bypass $PKI_SETUP_DIR/pki_chain_gen.ps1 "HIRS" "ecc" "512" "sha384" "$PKI_PASS" "$global:LOG_FILE"
# Save the password to the ACA properties file.
- add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_PKI_PWD_PROPERTY_NAME=$PKI_PASS"
-
+ add_new_aca_property -file "$global:HIRS_DATA_ACA_PROPERTIES_FILE" -newKeyAndValue "$global:ACA_PROPERTIES_PKI_PWD_PROPERTY_NAME=$PKI_PASS"
+
# Save connector information to the application properties file.
add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_SSL_KEY_STORE_PWD_PROPERTY_NAME=$PKI_PASS"
add_new_spring_property -file "$global:HIRS_DATA_SPRING_PROP_FILE" -newKeyAndValue "$global:SPRING_PROPERTIES_SSL_KEY_TRUST_STORE_PWD_PROPERTY_NAME=$PKI_PASS"
diff --git a/package/win/tcg-rim-tool/create_hirstools_desktop_shortcut.ps1 b/package/win/tcg-rim-tool/create_hirstools_desktop_shortcut.ps1
index 17332995c..5c01aefe7 100644
--- a/package/win/tcg-rim-tool/create_hirstools_desktop_shortcut.ps1
+++ b/package/win/tcg-rim-tool/create_hirstools_desktop_shortcut.ps1
@@ -7,5 +7,5 @@ $Shortcut = $WshShell.CreateShortcut("$Home\Desktop\HIRS_tools.lnk")
$Shortcut.TargetPath = "powershell.exe"
$ScriptPath = "$PWD\hirsshell.ps1"
$Shortcut.Arguments = "-ExecutionPolicy Bypass -File `"$ScriptPath`""
-$Shortcut.WorkingDirectory = "$PWD"
+$Shortcut.WorkingDirectory = "$PWD"
$Shortcut.Save()
diff --git a/package/win/tcg-rim-tool/eventLog.ps1 b/package/win/tcg-rim-tool/eventLog.ps1
index 552289c73..f976eff04 100644
--- a/package/win/tcg-rim-tool/eventLog.ps1
+++ b/package/win/tcg-rim-tool/eventLog.ps1
@@ -1,7 +1,7 @@
# Script to run the tcg_rim_tool in java
$JavaParams = @{
- FilePath = 'java'
+ FilePath = 'java'
ArgumentList = @(
'-jar "{0}"' -f "$PWD\tcg_eventlog_tool/tcg_eventlog_tool.jar"
"$args"
diff --git a/package/win/tcg-rim-tool/hirsshell.ps1 b/package/win/tcg-rim-tool/hirsshell.ps1
index 854e7ce20..c5db209a9 100644
--- a/package/win/tcg-rim-tool/hirsshell.ps1
+++ b/package/win/tcg-rim-tool/hirsshell.ps1
@@ -9,5 +9,5 @@ $StartInfo.Arguments = "-NoExit -Command
Write-Output 'for usage type: rim -h';
Write-Output 'for eventlog usage type: elt -h'
Set-Location -Path $PWD;
- function prompt {'HIRS > '};"
+ function prompt {'HIRS > '};"
[System.Diagnostics.Process]::Start($StartInfo)
diff --git a/package/win/tcg-rim-tool/rim.ps1 b/package/win/tcg-rim-tool/rim.ps1
index 986e2917f..7b71f6b7e 100644
--- a/package/win/tcg-rim-tool/rim.ps1
+++ b/package/win/tcg-rim-tool/rim.ps1
@@ -1,7 +1,7 @@
# Script to run the tcg_rim_tool in java
$JavaParams = @{
- FilePath = 'java'
+ FilePath = 'java'
ArgumentList = @(
'-jar "{0}"' -f "$PWD\tcg_rim_tool/tcg_rim_tool.jar"
"$args"
From 51d284d04a095ee1386798a89b0f968d5671d610 Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Tue, 17 Mar 2026 17:38:05 -0400
Subject: [PATCH 21/25] v3.1_issue_1127: Forgot to add autowired annotation to
the Tpm2ProvisionerStateService class, moved validation services to the
validation service package. Started working on creating a credential blob
using two ecc keys. Almost at the finish line.
---
.../provision/helper/ProvisionUtils.java | 251 ++++++++++++++++--
.../CertificateRequestProcessorService.java | 1 +
.../IdentityClaimProcessorService.java | 1 +
.../service/Tpm2ProvisionerStateService.java | 2 +
.../ReferenceManifestDetailsPageService.java | 3 +-
.../validation/FirmwareScvValidator.java | 1 -
.../SupplyChainValidationService.java | 5 +-
.../ValidationService.java | 4 +-
8 files changed, 239 insertions(+), 29 deletions(-)
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/{provision/service => validation}/SupplyChainValidationService.java (98%)
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/{service => validation}/ValidationService.java (99%)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index 5b9331a7f..41039d773 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -14,6 +14,7 @@
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyAgreement;
import javax.crypto.Mac;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
@@ -28,14 +29,18 @@
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
+import java.security.spec.ECPoint;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.RSAPublicKeySpec;
@@ -342,8 +347,8 @@ public static ByteString tpm20MakeCredential(final PublicKey endorsementPublicKe
*
* Equivalent to calling tpm2_makecredential using tpm2_tools.
*
- * @param endorsementRSAKey endorsement key in the identity claim
- * @param attestationRSAKey attestation key in the identity claim
+ * @param endorsementRSAKey endorsement RSA key in the identity claim
+ * @param attestationRSAKey attestation RSA key in the identity claim
* @param secret a nonce
* @return the encrypted blob forming the identity claim challenge
*/
@@ -381,10 +386,9 @@ public static ByteString tpm20MakeCredentialUsingRSA(final RSAPublicKey endorsem
byte[] hmacKey = cryptKDFa(seed, "INTEGRITY", null, HMAC_KEY_LENGTH_BYTES);
// use two bytes to add a size prefix on secret
- ByteBuffer b;
- b = ByteBuffer.allocate(2);
- b.putShort((short) (secret.length));
- byte[] secretLength = b.array();
+ ByteBuffer lengthBuffer = ByteBuffer.allocate(2);
+ lengthBuffer.putShort((short) (secret.length));
+ byte[] secretLength = lengthBuffer.array();
byte[] secretBytes = new byte[secret.length + 2];
System.arraycopy(secretLength, 0, secretBytes, 0, 2);
System.arraycopy(secret, 0, secretBytes, 2, secret.length);
@@ -405,9 +409,9 @@ public static ByteString tpm20MakeCredentialUsingRSA(final RSAPublicKey endorsem
System.arraycopy(akName, 0, message, encSecret.length, akName.length);
integrityHmac.update(message);
byte[] integrity = integrityHmac.doFinal();
- b = ByteBuffer.allocate(2);
- b.putShort((short) (HMAC_SIZE_LENGTH_BYTES + HMAC_KEY_LENGTH_BYTES + encSecret.length));
- byte[] topSize = b.array();
+ lengthBuffer = ByteBuffer.allocate(2);
+ lengthBuffer.putShort((short) (HMAC_SIZE_LENGTH_BYTES + HMAC_KEY_LENGTH_BYTES + encSecret.length));
+ byte[] topSize = lengthBuffer.array();
// return ordered blob of assembled credentials
byte[] bytesToReturn = assembleCredential(topSize, integrity, encSecret, encSeed);
@@ -423,7 +427,6 @@ public static ByteString tpm20MakeCredentialUsingRSA(final RSAPublicKey endorsem
}
/**
- * todo
* Performs the first step of the TPM 2.0 identity claim process using the ECC public key algorithm:
*
* - Takes an ek, ak, and secret and generates a seed that is used to generate AES and HMAC keys.
@@ -439,18 +442,208 @@ public static ByteString tpm20MakeCredentialUsingRSA(final RSAPublicKey endorsem
*
* Equivalent to calling tpm2_makecredential using tpm2_tools.
*
- * @param endorsementECCKey endorsement key in the identity claim
- * @param attestationECCKey attestation key in the identity claim
+ * @param endorsementECCKey endorsement ECC key in the identity claim
+ * @param attestationECCKey attestation ECC key in the identity claim
* @param secret a nonce
* @return the encrypted blob forming the identity claim challenge
*/
public static ByteString tpm20MakeCredentialUsingECC(final ECPublicKey endorsementECCKey,
final ECPublicKey attestationECCKey,
final byte[] secret) {
+ try {
+ // --- Step 1: Generate ephemeral ECC key pair for encryption ---
+
+ // This temporary key pair is used for ECC "encryption" via ECDH.
+ // Only the TPM with the corresponding private EK can recover the shared secret.
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
+
+ // Initialize the key pair generator with the same curve parameters as the TPM's EK.
+ // This ensures ECDH works correctly between the ephemeral key and the EK.
+ kpg.initialize(endorsementECCKey.getParams());
+
+ // Generate the ephemeral key pair (random, unique for this credential)
+ KeyPair ephKeyPair = kpg.generateKeyPair();
+
+ // Extract the private key from the ephemeral pair
+ // This will stay secret and is used to compute the ECDH shared secret with the EK public key.
+ ECPrivateKey ephemeralPrivateKey = (ECPrivateKey) ephKeyPair.getPrivate();
+
+ // Extract the public key from the ephemeral pair
+ // This will be sent to the TPM so it can also compute the shared secret using its private EK.
+ ECPublicKey ephemeralPublicKey = (ECPublicKey) ephKeyPair.getPublic();
+
+ // Encode ephemeral and endorsement keys as bytes for KDF context
+ byte[] ephemeralPublicKeyBytes = convertECPublicKeyToBytes(ephemeralPublicKey);
+
+ // --- Step 2: Compute ECDH shared secret Z ---
+
+ KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH");
+ keyAgreement.init(ephemeralPrivateKey);
+
+ // Combine your ephemeral private key with the TPM's Endorsement Key public key
+ // This performs the elliptic curve math needed to derive the shared secret
+ keyAgreement.doPhase(endorsementECCKey, true);
+
+ // Generate the shared secret bytes (traditionally called 'Z' in the spec)
+ byte[] sharedSecret = keyAgreement.generateSecret();
+
+ // --- Step 3: Derive AES and HMAC keys using cryptKDFa ---
+
+ byte[] aesKey = cryptKDFa(sharedSecret, "STORAGE", ephemeralPublicKeyBytes, AES_KEY_LENGTH_BYTES);
+ byte[] hmacKey = cryptKDFa(sharedSecret, "INTEGRITY", null, HMAC_KEY_LENGTH_BYTES);
+
+ // --- Step 4: Encrypt the secret using AES-GCM ---
+
+ final int aesBlockSizeBytes = 16;
+ final byte[] zeroIv = new byte[aesBlockSizeBytes];
+ IvParameterSpec ivSpec = new IvParameterSpec(zeroIv);
+
+ Cipher aesCipher = Cipher.getInstance("AES/CFB/NoPadding");
+ SecretKeySpec aesKeySpec = new SecretKeySpec(aesKey, "AES");
+ aesCipher.init(Cipher.ENCRYPT_MODE, aesKeySpec, ivSpec);
+
+ // ---- ADD LENGTH PREFIX (REQUIRED) ----
+
+ // Allocate 2 bytes to store secret length
+ ByteBuffer lengthBuffer = ByteBuffer.allocate(2);
+ lengthBuffer.putShort((short) secret.length);
+ byte[] lengthBytes = lengthBuffer.array();
+
+ // Create new array: [length (2 bytes) | secret]
+ byte[] secretWithLength = new byte[2 + secret.length];
+ System.arraycopy(lengthBytes, 0, secretWithLength, 0, 2);
+ System.arraycopy(secret, 0, secretWithLength, 2, secret.length);
- throw new UnsupportedOperationException("");
+ // Encrypt the combined array
+ byte[] encryptedSecret = aesCipher.doFinal(secretWithLength);
+
+ // Encrypt the credential value
+
+ //todo
+
+ // --- Step 5: Compute HMAC over (encryptedSecret || akName) ---
+ // Generate the AK name (this uniquely identifies the attestation key)
+ // TPM uses this to ensure the credential is tied to the correct AK
+ //byte[] akName = generateAkName(attestationECCKey);
+//
+ //// Create HMAC instance using SHA-256 (matches your KDF and TPM expectations)
+ //Mac hmac = Mac.getInstance("HmacSHA256");
+ //SecretKeySpec hmacKeySpec = new SecretKeySpec(hmacKey, "HmacSHA256");
+ //hmac.init(hmacKeySpec);
+ //hmac.update(encryptedSecret);
+ //hmac.update(akName);
+//
+ //// Compute final HMAC value
+ //byte[] hmacValue = hmac.doFinal();
+//
+//
+ //byte[] bytesToReturn = assembleCredential(topSize, hmacValue, encryptedSecret, encSeed);
+ //return ByteString.copyFrom(bytesToReturn);
+
+ throw new UnsupportedOperationException("");
+
+ } catch (BadPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException
+ | InvalidKeyException | InvalidAlgorithmParameterException
+ | NoSuchPaddingException e) {
+ throw new IdentityProcessingException(
+ "Encountered error while making the identity claim challenge for the provided RSA public keys: "
+ + e.getMessage(), e);
+ }
}
+ /**
+ * Converts an EC public key point into a fixed-length uncompressed byte array.
+ * This format is required for TPM key derivation functions (KDFe).
+ *
+ * Format: 0x04 || X || Y
+ *
+ *
+ *
+ * TPM ECC operations (like making a credential) require the public point to be
+ * encoded as a deterministic byte array. Both sides (client and TPM) must
+ * compute the same bytes for the ECDH key derivation to work.
+ *
+ * @param publicKey The EC public key to encode.
+ * @return Byte array representing the uncompressed EC point.
+ */
+ public static byte[] convertECPublicKeyToBytes(final ECPublicKey publicKey) {
+ // Get the raw EC point (X, Y coordinates)
+ ECPoint ecPoint = publicKey.getW();
+
+ // Constants for calculation
+ // Example: 521 bits + 7 = 528 → 528 / 8 = 66 bytes
+ final int fieldSizeInBytes = getFieldSizeInBytes(publicKey);
+
+ // Convert X and Y coordinates to fixed-length byte arrays
+ byte[] xBytes = convertBigIntegerToFixedLength(ecPoint.getAffineX(), fieldSizeInBytes);
+ byte[] yBytes = convertBigIntegerToFixedLength(ecPoint.getAffineY(), fieldSizeInBytes);
+
+ // Constants for encoding the EC point
+ final byte uncompressedPointPrefix = 0x04; // Indicates this is an uncompressed point (X and Y)
+ final int numCoordinates = 2; // X + Y
+
+ // Allocate the byte array for the encoded point. Total length = 1 byte prefix + X bytes + Y bytes
+ int encodedPointLength = 1 + (numCoordinates * fieldSizeInBytes);
+ byte[] encodedPointByteArray = new byte[encodedPointLength];
+
+ // Set the uncompressed point prefix at the first byte
+ encodedPointByteArray[0] = uncompressedPointPrefix;
+
+ // Copy X coordinate bytes into the array
+ System.arraycopy(xBytes, 0, encodedPointByteArray, 1, fieldSizeInBytes);
+
+ // Copy Y coordinate bytes immediately after X
+ System.arraycopy(yBytes, 0, encodedPointByteArray, 1 + fieldSizeInBytes, fieldSizeInBytes);
+
+ return encodedPointByteArray;
+ }
+
+ /**
+ * Calculates the number of bytes required for each coordinate (X or Y).
+ *
+ * @param eccPublicKey {@link ECPublicKey}
+ * @return {@link ECPublicKey}'s field size in bytes
+ */
+ public static int getFieldSizeInBytes(final ECPublicKey eccPublicKey) {
+ // Standard: 8 bits in a byte
+ final int bitsPerByte = 8;
+
+ // Add 7 to bits before dividing by 8 to round up
+ final int roundUpOffset = 7;
+
+ // The field size of the curve is in bits (e.g., P-256 = 256 bits)
+ // TPM expects each coordinate to be **fixed-length**, even if the number would normally take fewer bytes
+ return (eccPublicKey.getParams().getCurve().getField().getFieldSize()
+ + roundUpOffset) / bitsPerByte;
+ }
+
+ /**
+ * Converts a BigInteger to a fixed-length byte array. Pads with leading zeros if necessary or trims extra bytes
+ * if needed.
+ *
+ * @param value The BigInteger to convert.
+ * @param length Desired byte length of the output array.
+ * @return Byte array of exact length representing the BigInteger.
+ */
+ public static byte[] convertBigIntegerToFixedLength(final BigInteger value, final int length) {
+ byte[] rawBytes = value.toByteArray(); // default BigInteger encoding
+ byte[] fixedLengthBytes = new byte[length];
+
+ if (rawBytes.length == length) {
+ // Already the correct size, just return
+ return rawBytes;
+ } else if (rawBytes.length > length) {
+ // Trim leading byte(s) (sometimes BigInteger adds a sign byte)
+ System.arraycopy(rawBytes, rawBytes.length - length, fixedLengthBytes, 0, length);
+ } else {
+ // Pad with leading zeros to reach the correct length
+ System.arraycopy(rawBytes, 0, fixedLengthBytes, length - rawBytes.length, rawBytes.length);
+ }
+
+ return fixedLengthBytes;
+ }
+
+
/**
* Assembles a credential blob.
*
@@ -541,24 +734,28 @@ public static byte[] generateAkName(final byte[] akModulus) throws NoSuchAlgorit
* @throws NoSuchAlgorithmException Wrong crypto algorithm selected
* @throws InvalidKeyException Invalid key used
*/
-
- public static byte[] cryptKDFa(final byte[] seed, final String label, final byte[] context,
- final int sizeInBytes)
+ public static byte[] cryptKDFa(final byte[] seed, final String label, final byte[] context, final int sizeInBytes)
throws NoSuchAlgorithmException, InvalidKeyException {
+ // --- Step 1: Set up the counter (always 1 for this simplified version) ---
final int capacity = 4;
ByteBuffer b = ByteBuffer.allocate(capacity);
b.putInt(1);
byte[] counter = b.array();
- // get the label
+
+ // --- Step 2: Ensure label ends with null byte (\0) as per TPM spec ---
String labelWithEnding = label;
if (label.charAt(label.length() - 1) != '\u0000') {
labelWithEnding = label + "\0";
}
byte[] labelBytes = labelWithEnding.getBytes(StandardCharsets.UTF_8);
+
+ // --- Step 3: Prepare size of desired output in bits ---
final int byteOffset = 8;
b = ByteBuffer.allocate(capacity);
b.putInt(sizeInBytes * byteOffset);
byte[] desiredSizeInBits = b.array();
+
+ // --- Step 4: Compute total length of the message to HMAC ---
int sizeOfMessage = byteOffset + labelBytes.length;
if (context != null) {
sizeOfMessage += context.length;
@@ -567,23 +764,37 @@ public static byte[] cryptKDFa(final byte[] seed, final String label, final byte
int marker = 0;
final int markerLength = 4;
+
+ // --- Step 5: Copy counter into message ---
System.arraycopy(counter, 0, message, marker, markerLength);
marker += markerLength;
+
+ // --- Step 6: Copy label into message ---
System.arraycopy(labelBytes, 0, message, marker, labelBytes.length);
marker += labelBytes.length;
+
+ // --- Step 5: Copy counter into message ---
if (context != null) {
System.arraycopy(context, 0, message, marker, context.length);
marker += context.length;
}
+
+ // --- Step 8: Copy desired size in bits at the end of message ---
System.arraycopy(desiredSizeInBits, 0, message, marker, markerLength);
- Mac hmac;
- byte[] toReturn = new byte[sizeInBytes];
- hmac = Mac.getInstance("HmacSHA256");
+ // --- Step 9: Initialize HMAC-SHA256 with the seed as key ---
+ Mac hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec hmacKey = new SecretKeySpec(seed, hmac.getAlgorithm());
hmac.init(hmacKey);
+
+ // --- Step 10: Feed the constructed message into HMAC ---
hmac.update(message);
+
+ // --- Step 11: Compute HMAC output ---
byte[] hmacResult = hmac.doFinal();
+
+ // --- Step 12: Copy required number of bytes to return array ---
+ byte[] toReturn = new byte[sizeInBytes];
System.arraycopy(hmacResult, 0, toReturn, 0, sizeInBytes);
return toReturn;
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
index bb270ccf8..243c93b05 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java
@@ -17,6 +17,7 @@
import hirs.attestationca.persist.exceptions.CertificateProcessingException;
import hirs.attestationca.persist.provision.helper.IssuedCertificateAttributeHelper;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
+import hirs.attestationca.persist.validation.SupplyChainValidationService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ArrayUtils;
import org.bouncycastle.asn1.x500.X500Name;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
index 00b0fa6dc..21ad55ca0 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java
@@ -15,6 +15,7 @@
import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
import hirs.attestationca.persist.enums.AppraisalStatus;
import hirs.attestationca.persist.provision.helper.ProvisionUtils;
+import hirs.attestationca.persist.validation.SupplyChainValidationService;
import hirs.utils.HexUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ArrayUtils;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/Tpm2ProvisionerStateService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/Tpm2ProvisionerStateService.java
index f359d7a56..ba38c64e7 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/Tpm2ProvisionerStateService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/Tpm2ProvisionerStateService.java
@@ -4,6 +4,7 @@
import hirs.attestationca.persist.entity.tpm.TPM2ProvisionerState;
import lombok.extern.log4j.Log4j2;
import org.bouncycastle.util.Arrays;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.ByteArrayInputStream;
@@ -23,6 +24,7 @@ public class Tpm2ProvisionerStateService {
*
* @param tpm2ProvisionerStateRepository TPM2 Provisioner State Repository
*/
+ @Autowired
public Tpm2ProvisionerStateService(final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository) {
this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository;
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ReferenceManifestDetailsPageService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ReferenceManifestDetailsPageService.java
index 00da5a5e1..2500e10cb 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ReferenceManifestDetailsPageService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ReferenceManifestDetailsPageService.java
@@ -14,6 +14,7 @@
import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest;
import hirs.attestationca.persist.validation.SupplyChainCredentialValidator;
import hirs.attestationca.persist.validation.SupplyChainValidatorException;
+import hirs.attestationca.persist.validation.ValidationService;
import hirs.utils.SwidResource;
import hirs.utils.rim.ReferenceManifestValidator;
import hirs.utils.tpm.eventlog.TCGEventLog;
@@ -131,7 +132,7 @@ private void getEventSummary(final HashMap data,
contentStr = tpe.getEventContentStr();
// check for specific events
if (contentStr.contains("CRTM")
- || contentStr.contains("IBB")) {
+ || contentStr.contains("IBB")) {
coveredEvents.put("crtm", true);
} else if (contentStr.contains(UefiConstants.UEFI_FIRMWARE_BLOB_LABEL)) {
coveredEvents.put("firmwareBlob", true);
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java
index 6b5cae0d8..29861713e 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/FirmwareScvValidator.java
@@ -11,7 +11,6 @@
import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements;
import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue;
import hirs.attestationca.persist.enums.AppraisalStatus;
-import hirs.attestationca.persist.service.ValidationService;
import hirs.utils.SwidResource;
import hirs.utils.rim.ReferenceManifestValidator;
import hirs.utils.tpm.eventlog.TCGEventLog;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/SupplyChainValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainValidationService.java
similarity index 98%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/SupplyChainValidationService.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainValidationService.java
index b2a5374ce..79828bb49 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/SupplyChainValidationService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainValidationService.java
@@ -1,4 +1,4 @@
-package hirs.attestationca.persist.provision.service;
+package hirs.attestationca.persist.validation;
import hirs.attestationca.persist.DBManagerException;
import hirs.attestationca.persist.entity.ArchivableEntity;
@@ -24,9 +24,6 @@
import hirs.attestationca.persist.entity.userdefined.rim.EventLogMeasurements;
import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest;
import hirs.attestationca.persist.enums.AppraisalStatus;
-import hirs.attestationca.persist.service.ValidationService;
-import hirs.attestationca.persist.validation.PcrValidator;
-import hirs.attestationca.persist.validation.SupplyChainCredentialValidator;
import lombok.extern.log4j.Log4j2;
import org.apache.logging.log4j.Level;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/ValidationService.java
similarity index 99%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/ValidationService.java
index 34cac2220..b1066136c 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/ValidationService.java
@@ -1,4 +1,4 @@
-package hirs.attestationca.persist.service;
+package hirs.attestationca.persist.validation;
import hirs.attestationca.persist.entity.ArchivableEntity;
import hirs.attestationca.persist.entity.manager.CACredentialRepository;
@@ -18,8 +18,6 @@
import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo;
import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
import hirs.attestationca.persist.enums.AppraisalStatus;
-import hirs.attestationca.persist.validation.CredentialValidator;
-import hirs.attestationca.persist.validation.FirmwareScvValidator;
import hirs.utils.BouncyCastleUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.logging.log4j.Level;
From 582911ecae7ae338ed1af0107a0abfd03bd2eddd Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Tue, 17 Mar 2026 17:43:46 -0400
Subject: [PATCH 22/25] v3.1_issue_1127: This should fix the build error on
github.
---
.../persist/provision/helper/ProvisionUtils.java | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index 41039d773..3b94d0deb 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -490,7 +490,7 @@ public static ByteString tpm20MakeCredentialUsingECC(final ECPublicKey endorseme
// --- Step 3: Derive AES and HMAC keys using cryptKDFa ---
byte[] aesKey = cryptKDFa(sharedSecret, "STORAGE", ephemeralPublicKeyBytes, AES_KEY_LENGTH_BYTES);
- byte[] hmacKey = cryptKDFa(sharedSecret, "INTEGRITY", null, HMAC_KEY_LENGTH_BYTES);
+ //byte[] hmacKey = cryptKDFa(sharedSecret, "INTEGRITY", null, HMAC_KEY_LENGTH_BYTES);
// --- Step 4: Encrypt the secret using AES-GCM ---
@@ -503,7 +503,7 @@ public static ByteString tpm20MakeCredentialUsingECC(final ECPublicKey endorseme
aesCipher.init(Cipher.ENCRYPT_MODE, aesKeySpec, ivSpec);
// ---- ADD LENGTH PREFIX (REQUIRED) ----
-
+ //todo
// Allocate 2 bytes to store secret length
ByteBuffer lengthBuffer = ByteBuffer.allocate(2);
lengthBuffer.putShort((short) secret.length);
@@ -515,12 +515,11 @@ public static ByteString tpm20MakeCredentialUsingECC(final ECPublicKey endorseme
System.arraycopy(secret, 0, secretWithLength, 2, secret.length);
// Encrypt the combined array
- byte[] encryptedSecret = aesCipher.doFinal(secretWithLength);
+ //byte[] encryptedSecret = aesCipher.doFinal(secretWithLength);
// Encrypt the credential value
- //todo
-
+
// --- Step 5: Compute HMAC over (encryptedSecret || akName) ---
// Generate the AK name (this uniquely identifies the attestation key)
// TPM uses this to ensure the credential is tied to the correct AK
@@ -533,7 +532,7 @@ public static ByteString tpm20MakeCredentialUsingECC(final ECPublicKey endorseme
//hmac.update(encryptedSecret);
//hmac.update(akName);
//
- //// Compute final HMAC value
+ // Compute final HMAC value
//byte[] hmacValue = hmac.doFinal();
//
//
@@ -542,7 +541,7 @@ public static ByteString tpm20MakeCredentialUsingECC(final ECPublicKey endorseme
throw new UnsupportedOperationException("");
- } catch (BadPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException
+ } catch (NoSuchAlgorithmException
| InvalidKeyException | InvalidAlgorithmParameterException
| NoSuchPaddingException e) {
throw new IdentityProcessingException(
From d567049e1b5b0cdc6674328c2096c355eb80e97f Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Wed, 18 Mar 2026 18:04:04 -0400
Subject: [PATCH 23/25] v3.1_issue_1127: Finished the make credential using ecc
keys func in provision utils. Can remove WIP from PR.
---
.../provision/helper/ProvisionUtils.java | 109 ++++++++++--------
1 file changed, 59 insertions(+), 50 deletions(-)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index 3b94d0deb..dcbe690da 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -413,7 +413,7 @@ public static ByteString tpm20MakeCredentialUsingRSA(final RSAPublicKey endorsem
lengthBuffer.putShort((short) (HMAC_SIZE_LENGTH_BYTES + HMAC_KEY_LENGTH_BYTES + encSecret.length));
byte[] topSize = lengthBuffer.array();
- // return ordered blob of assembled credentials
+ // return ordered blob of assembled credential
byte[] bytesToReturn = assembleCredential(topSize, integrity, encSecret, encSeed);
return ByteString.copyFrom(bytesToReturn);
@@ -462,15 +462,15 @@ public static ByteString tpm20MakeCredentialUsingECC(final ECPublicKey endorseme
kpg.initialize(endorsementECCKey.getParams());
// Generate the ephemeral key pair (random, unique for this credential)
- KeyPair ephKeyPair = kpg.generateKeyPair();
+ KeyPair ephemeralKeyPair = kpg.generateKeyPair();
// Extract the private key from the ephemeral pair
// This will stay secret and is used to compute the ECDH shared secret with the EK public key.
- ECPrivateKey ephemeralPrivateKey = (ECPrivateKey) ephKeyPair.getPrivate();
+ ECPrivateKey ephemeralPrivateKey = (ECPrivateKey) ephemeralKeyPair.getPrivate();
// Extract the public key from the ephemeral pair
// This will be sent to the TPM so it can also compute the shared secret using its private EK.
- ECPublicKey ephemeralPublicKey = (ECPublicKey) ephKeyPair.getPublic();
+ ECPublicKey ephemeralPublicKey = (ECPublicKey) ephemeralKeyPair.getPublic();
// Encode ephemeral and endorsement keys as bytes for KDF context
byte[] ephemeralPublicKeyBytes = convertECPublicKeyToBytes(ephemeralPublicKey);
@@ -489,60 +489,65 @@ public static ByteString tpm20MakeCredentialUsingECC(final ECPublicKey endorseme
// --- Step 3: Derive AES and HMAC keys using cryptKDFa ---
+ // Derive AES key for encrypting the secret
byte[] aesKey = cryptKDFa(sharedSecret, "STORAGE", ephemeralPublicKeyBytes, AES_KEY_LENGTH_BYTES);
- //byte[] hmacKey = cryptKDFa(sharedSecret, "INTEGRITY", null, HMAC_KEY_LENGTH_BYTES);
+
+ // Derive HMAC key for authenticating the encrypted secret
+ byte[] hmacKey = cryptKDFa(sharedSecret, "INTEGRITY", null, HMAC_KEY_LENGTH_BYTES);
// --- Step 4: Encrypt the secret using AES-GCM ---
final int aesBlockSizeBytes = 16;
- final byte[] zeroIv = new byte[aesBlockSizeBytes];
- IvParameterSpec ivSpec = new IvParameterSpec(zeroIv);
+ final byte[] defaultIv = new byte[aesBlockSizeBytes];
+ IvParameterSpec ivSpec = new IvParameterSpec(defaultIv);
Cipher aesCipher = Cipher.getInstance("AES/CFB/NoPadding");
- SecretKeySpec aesKeySpec = new SecretKeySpec(aesKey, "AES");
- aesCipher.init(Cipher.ENCRYPT_MODE, aesKeySpec, ivSpec);
+ SecretKeySpec aesSecretKeySpec = new SecretKeySpec(aesKey, "AES");
+ aesCipher.init(Cipher.ENCRYPT_MODE, aesSecretKeySpec, ivSpec);
- // ---- ADD LENGTH PREFIX (REQUIRED) ----
- //todo
- // Allocate 2 bytes to store secret length
+ // --- Add 2-byte length prefix to the secret ---
+ // TPM expects the secret length encoded before the actual secret
ByteBuffer lengthBuffer = ByteBuffer.allocate(2);
lengthBuffer.putShort((short) secret.length);
byte[] lengthBytes = lengthBuffer.array();
- // Create new array: [length (2 bytes) | secret]
+ // Combine length prefix + secret into a single array
byte[] secretWithLength = new byte[2 + secret.length];
System.arraycopy(lengthBytes, 0, secretWithLength, 0, 2);
System.arraycopy(secret, 0, secretWithLength, 2, secret.length);
- // Encrypt the combined array
- //byte[] encryptedSecret = aesCipher.doFinal(secretWithLength);
+ // Encrypt the combined array using AES
+ byte[] encryptedSecret = aesCipher.doFinal(secretWithLength);
- // Encrypt the credential value
+ // --- Step 5: Compute HMAC over (encryptedSecret || akName) ---
+ // Generate the Attestation Key (AK) name (unique identifier for the AK)
+ byte[] akName = generateAkName(attestationECCKey.getEncoded());
- // --- Step 5: Compute HMAC over (encryptedSecret || akName) ---
- // Generate the AK name (this uniquely identifies the attestation key)
- // TPM uses this to ensure the credential is tied to the correct AK
- //byte[] akName = generateAkName(attestationECCKey);
-//
- //// Create HMAC instance using SHA-256 (matches your KDF and TPM expectations)
- //Mac hmac = Mac.getInstance("HmacSHA256");
- //SecretKeySpec hmacKeySpec = new SecretKeySpec(hmacKey, "HmacSHA256");
- //hmac.init(hmacKeySpec);
- //hmac.update(encryptedSecret);
- //hmac.update(akName);
-//
- // Compute final HMAC value
- //byte[] hmacValue = hmac.doFinal();
-//
-//
- //byte[] bytesToReturn = assembleCredential(topSize, hmacValue, encryptedSecret, encSeed);
- //return ByteString.copyFrom(bytesToReturn);
-
- throw new UnsupportedOperationException("");
+ // Create HMAC instance using SHA-256 (matches your KDF and TPM expectations)
+ Mac hmac = Mac.getInstance("HmacSHA256");
+ SecretKeySpec hmacSecretKeySpec = new SecretKeySpec(hmacKey, hmac.getAlgorithm());
+ hmac.init(hmacSecretKeySpec);
+
+ // Combine encrypted secret and AK name into one message buffer
+ byte[] hmacMessage = new byte[encryptedSecret.length + akName.length];
+ System.arraycopy(encryptedSecret, 0, hmacMessage, 0, encryptedSecret.length);
+ System.arraycopy(akName, 0, hmacMessage, encryptedSecret.length, akName.length);
+
+ // Compute the final HMAC
+ hmac.update(hmacMessage);
+ byte[] hmacValue = hmac.doFinal();
+
+ lengthBuffer = ByteBuffer.allocate(2);
+ lengthBuffer.putShort((short) (HMAC_SIZE_LENGTH_BYTES + HMAC_KEY_LENGTH_BYTES + encryptedSecret.length));
+ byte[] topSize = lengthBuffer.array();
+ // return ordered blob of assembled credential
+ byte[] bytesToReturn = assembleCredential(topSize, hmacValue, encryptedSecret, ephemeralPublicKeyBytes);
+ return ByteString.copyFrom(bytesToReturn);
} catch (NoSuchAlgorithmException
- | InvalidKeyException | InvalidAlgorithmParameterException
+ | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException |
+ BadPaddingException
| NoSuchPaddingException e) {
throw new IdentityProcessingException(
"Encountered error while making the identity claim challenge for the provided RSA public keys: "
@@ -642,7 +647,6 @@ public static byte[] convertBigIntegerToFixedLength(final BigInteger value, fina
return fixedLengthBytes;
}
-
/**
* Assembles a credential blob.
*
@@ -700,23 +704,28 @@ public static byte[] assembleCredential(final byte[] topSize,
}
/**
- * Determines the AK name from the AK Modulus.
+ * Generates a byte array representation of the AK name from the Attestation Key bytes.
*
- * @param akModulus modulus of an attestation key
+ * @param attestationKeyBytes attestation key
* @return the ak name byte array
* @throws NoSuchAlgorithmException Underlying SHA256 method used a bad algorithm
*/
- public static byte[] generateAkName(final byte[] akModulus) throws NoSuchAlgorithmException {
+ public static byte[] generateAkName(final byte[] attestationKeyBytes) throws NoSuchAlgorithmException {
byte[] namePrefix = HexUtils.hexStringToByteArray(AK_NAME_PREFIX);
byte[] hashPrefix = HexUtils.hexStringToByteArray(AK_NAME_HASH_PREFIX);
- byte[] toHash = new byte[hashPrefix.length + akModulus.length];
- System.arraycopy(hashPrefix, 0, toHash, 0, hashPrefix.length);
- System.arraycopy(akModulus, 0, toHash, hashPrefix.length, akModulus.length);
- byte[] nameHash = sha256hash(toHash);
- byte[] toReturn = new byte[namePrefix.length + nameHash.length];
- System.arraycopy(namePrefix, 0, toReturn, 0, namePrefix.length);
- System.arraycopy(nameHash, 0, toReturn, namePrefix.length, nameHash.length);
- return toReturn;
+
+ // Combine hashPrefix + akModulus
+ ByteBuffer buffer = ByteBuffer.allocate(hashPrefix.length + attestationKeyBytes.length);
+ buffer.put(hashPrefix);
+ buffer.put(attestationKeyBytes);
+ byte[] nameHash = sha256hash(buffer.array());
+
+ // Combine namePrefix + nameHash
+ buffer = ByteBuffer.allocate(namePrefix.length + nameHash.length);
+ buffer.put(namePrefix);
+ buffer.put(nameHash);
+
+ return buffer.array();
}
/**
@@ -772,7 +781,7 @@ public static byte[] cryptKDFa(final byte[] seed, final String label, final byte
System.arraycopy(labelBytes, 0, message, marker, labelBytes.length);
marker += labelBytes.length;
- // --- Step 5: Copy counter into message ---
+ // --- Step 7: Copy context into message ---
if (context != null) {
System.arraycopy(context, 0, message, marker, context.length);
marker += context.length;
From e63a30e616da4dce78568c280795db19a4bf5733 Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Thu, 19 Mar 2026 13:55:59 -0400
Subject: [PATCH 24/25] v3.1_issue_1127: Corrected some checkstyle errors,
added a new package that holds the rest controller, fixed other minor issues.
---
.ci/system-tests/sys_test_common.sh | 6 ++--
...ionCertificateAuthorityRestController.java | 8 ++---
.../provision/controllers/package-info.java | 4 +++
.../provision/helper/ProvisionUtils.java | 29 ++++++++++---------
...tationCertificateAuthorityServiceImpl.java | 6 ++--
.../service/DeviceInfoProcessorService.java | 12 ++++----
.../provision/service/package-info.java | 3 ++
7 files changed, 39 insertions(+), 29 deletions(-)
rename HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/{ => controllers}/AttestationCertificateAuthorityRestController.java (89%)
create mode 100644 HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/controllers/package-info.java
diff --git a/.ci/system-tests/sys_test_common.sh b/.ci/system-tests/sys_test_common.sh
index 95603b994..a31313432 100644
--- a/.ci/system-tests/sys_test_common.sh
+++ b/.ci/system-tests/sys_test_common.sh
@@ -13,11 +13,11 @@ tpm2_container=hirs-provisioner1-tpm2
checkContainerStatus() {
container_name=$1
container_id="$(docker ps -aqf "name=$container_name")"
- container_status="$(docker inspect "$container_id" --format='{{.State.Status}}')"
+ container_status="$(docker inspect $container_id --format='{{.State.Status}}')"
echo "Container id is $container_id and the status is $container_status"
if [ "$container_status" != "running" ]; then
- container_exit_code="$(docker inspect "$container_id" --format='{{.State.ExitCode}}')"
+ container_exit_code="$(docker inspect $container_id --format='{{.State.ExitCode}}')"
echo "Container Exit Code: $container_exit_code"
docker info
exit 1;
@@ -146,6 +146,6 @@ setAppsettings() {
# write_to_logs
writeToLogs() {
line=$1
- echo "$line";
+ echo $line;
docker exec -i $aca_container /bin/bash -c "cd .. && echo '$line' >> /var/log/hirs/HIRS_AttestationCA_Portal.log"
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/controllers/AttestationCertificateAuthorityRestController.java
similarity index 89%
rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java
rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/controllers/AttestationCertificateAuthorityRestController.java
index 346df7117..a815ca61c 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AttestationCertificateAuthorityRestController.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/controllers/AttestationCertificateAuthorityRestController.java
@@ -1,4 +1,4 @@
-package hirs.attestationca.persist.provision;
+package hirs.attestationca.persist.provision.controllers;
import hirs.attestationca.persist.provision.service.AttestationCertificateAuthorityService;
import lombok.extern.log4j.Log4j2;
@@ -41,7 +41,7 @@ public AttestationCertificateAuthorityRestController(
@ResponseBody
@PostMapping(value = "/identity-claim-tpm2/process", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim) {
- return this.attestationCertificateAuthorityService.processIdentityClaimTpm2(identityClaim);
+ return attestationCertificateAuthorityService.processIdentityClaimTpm2(identityClaim);
}
/**
@@ -55,7 +55,7 @@ public byte[] processIdentityClaimTpm2(@RequestBody final byte[] identityClaim)
@ResponseBody
@PostMapping(value = "/request-certificate-tpm2", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public byte[] processCertificateRequest(@RequestBody final byte[] certificateRequest) {
- return this.attestationCertificateAuthorityService.processCertificateRequest(certificateRequest);
+ return attestationCertificateAuthorityService.processCertificateRequest(certificateRequest);
}
/**
@@ -66,6 +66,6 @@ public byte[] processCertificateRequest(@RequestBody final byte[] certificateReq
@ResponseBody
@GetMapping("/public-key")
public byte[] getLeafACACertPublicKey() {
- return this.attestationCertificateAuthorityService.getLeafACACertPublicKey();
+ return attestationCertificateAuthorityService.getLeafACACertPublicKey();
}
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/controllers/package-info.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/controllers/package-info.java
new file mode 100644
index 000000000..31e20d1b4
--- /dev/null
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/controllers/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Package includes all the REST controllers used in the provisioning process.
+ */
+package hirs.attestationca.persist.provision.controllers;
\ No newline at end of file
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
index dcbe690da..b2470e2b9 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/ProvisionUtils.java
@@ -183,7 +183,7 @@ public static PublicKey parsePublicKeyFromPublicDataSegment(final byte[] publicA
* @param byteArray byte array
* @return public key algorithm
*/
- public static PublicKeyAlgorithm extractPublicKeyAlgorithmFromByteArray(byte[] byteArray) {
+ public static PublicKeyAlgorithm extractPublicKeyAlgorithmFromByteArray(final byte[] byteArray) {
// Return UNKNOWN if there are not enough bytes for comparison
if (byteArray == null || byteArray.length < 2) {
@@ -441,6 +441,11 @@ public static ByteString tpm20MakeCredentialUsingRSA(final RSAPublicKey endorsem
* to validate an identity claim.
*
* Equivalent to calling tpm2_makecredential using tpm2_tools.
+ *
+ * todo:
+ * DISCLAIMER: This method will need to be tested properly with a Provisioner that has been updated to handle
+ * multiple types of public keys. This UTILS class is becoming too large and will also need to be refactored
+ * to handle more algorithms like MLDSA.
*
* @param endorsementECCKey endorsement ECC key in the identity claim
* @param attestationECCKey attestation ECC key in the identity claim
@@ -538,6 +543,8 @@ public static ByteString tpm20MakeCredentialUsingECC(final ECPublicKey endorseme
hmac.update(hmacMessage);
byte[] hmacValue = hmac.doFinal();
+ // --- Step 6: Compute Top Size and Assemble Credential Blob ---
+
lengthBuffer = ByteBuffer.allocate(2);
lengthBuffer.putShort((short) (HMAC_SIZE_LENGTH_BYTES + HMAC_KEY_LENGTH_BYTES + encryptedSecret.length));
byte[] topSize = lengthBuffer.array();
@@ -545,13 +552,10 @@ public static ByteString tpm20MakeCredentialUsingECC(final ECPublicKey endorseme
// return ordered blob of assembled credential
byte[] bytesToReturn = assembleCredential(topSize, hmacValue, encryptedSecret, ephemeralPublicKeyBytes);
return ByteString.copyFrom(bytesToReturn);
- } catch (NoSuchAlgorithmException
- | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException |
- BadPaddingException
- | NoSuchPaddingException e) {
- throw new IdentityProcessingException(
- "Encountered error while making the identity claim challenge for the provided RSA public keys: "
- + e.getMessage(), e);
+ } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException
+ | IllegalBlockSizeException | BadPaddingException | NoSuchPaddingException e) {
+ throw new IdentityProcessingException("Encountered error while making the identity claim challenge for"
+ + " the provided ECC public keys: " + e.getMessage(), e);
}
}
@@ -579,8 +583,8 @@ public static byte[] convertECPublicKeyToBytes(final ECPublicKey publicKey) {
final int fieldSizeInBytes = getFieldSizeInBytes(publicKey);
// Convert X and Y coordinates to fixed-length byte arrays
- byte[] xBytes = convertBigIntegerToFixedLength(ecPoint.getAffineX(), fieldSizeInBytes);
- byte[] yBytes = convertBigIntegerToFixedLength(ecPoint.getAffineY(), fieldSizeInBytes);
+ byte[] xBytes = convertBigIntegerToByteArray(ecPoint.getAffineX(), fieldSizeInBytes);
+ byte[] yBytes = convertBigIntegerToByteArray(ecPoint.getAffineY(), fieldSizeInBytes);
// Constants for encoding the EC point
final byte uncompressedPointPrefix = 0x04; // Indicates this is an uncompressed point (X and Y)
@@ -617,8 +621,7 @@ public static int getFieldSizeInBytes(final ECPublicKey eccPublicKey) {
// The field size of the curve is in bits (e.g., P-256 = 256 bits)
// TPM expects each coordinate to be **fixed-length**, even if the number would normally take fewer bytes
- return (eccPublicKey.getParams().getCurve().getField().getFieldSize()
- + roundUpOffset) / bitsPerByte;
+ return (eccPublicKey.getParams().getCurve().getField().getFieldSize() + roundUpOffset) / bitsPerByte;
}
/**
@@ -629,7 +632,7 @@ public static int getFieldSizeInBytes(final ECPublicKey eccPublicKey) {
* @param length Desired byte length of the output array.
* @return Byte array of exact length representing the BigInteger.
*/
- public static byte[] convertBigIntegerToFixedLength(final BigInteger value, final int length) {
+ public static byte[] convertBigIntegerToByteArray(final BigInteger value, final int length) {
byte[] rawBytes = value.toByteArray(); // default BigInteger encoding
byte[] fixedLengthBytes = new byte[length];
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java
index 30ecbe4bd..64e9b9456 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java
@@ -34,7 +34,7 @@ public AttestationCertificateAuthorityServiceImpl(
* @return processed identity claim response
*/
public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
- return this.identityClaimProcessorService.processIdentityClaimTpm2(identityClaim);
+ return identityClaimProcessorService.processIdentityClaimTpm2(identityClaim);
}
/**
@@ -44,7 +44,7 @@ public byte[] processIdentityClaimTpm2(final byte[] identityClaim) {
* @return processed certificate request response
*/
public byte[] processCertificateRequest(final byte[] certificateRequest) {
- return this.certificateRequestProcessorService.processCertificateRequest(certificateRequest);
+ return certificateRequestProcessorService.processCertificateRequest(certificateRequest);
}
/**
@@ -53,6 +53,6 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) {
* @return encoded public key of the leaf certificate
*/
public byte[] getLeafACACertPublicKey() {
- return this.certificateRequestProcessorService.getLeafACACertificatePublicKey();
+ return certificateRequestProcessorService.getLeafACACertificatePublicKey();
}
}
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
index 4259c1b31..5c4bd7868 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java
@@ -101,8 +101,8 @@ public Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim identityClai
// store device and device info report.
Device device = null;
- if (deviceInfoReport.getNetworkInfo() != null &&
- !StringUtils.isBlank(deviceInfoReport.getNetworkInfo().getHostname())) {
+ if (deviceInfoReport.getNetworkInfo() != null
+ && !StringUtils.isBlank(deviceInfoReport.getNetworkInfo().getHostname())) {
device = deviceRepository.findByName(deviceInfoReport.getNetworkInfo().getHostname());
}
@@ -422,7 +422,7 @@ private void updateBaseRIMSUsingDeviceInfo(final String defaultClientName,
private void updateSupportRIMSUsingDeviceInfo(final String defaultClientName,
final ProvisionerTpm2.DeviceInfo provisionedDeviceInfo) {
final String deviceHostName = provisionedDeviceInfo.getNw().getHostname();
- final int NUM_OF_VARIABLES = 5;
+ final int numOfVariables = 5;
log.info("Device {} sent Support RIM files", deviceHostName);
@@ -453,7 +453,7 @@ private void updateSupportRIMSUsingDeviceInfo(final String defaultClientName,
replacementSupportRIM.setPlatformModel(provisionedDeviceInfo.getHw().getProductName());
replacementSupportRIM.setFileName(String.format("%s_[%s].rimel", defaultClientName,
replacementSupportRIM.getHexDecHash().substring(
- replacementSupportRIM.getHexDecHash().length() - NUM_OF_VARIABLES)));
+ replacementSupportRIM.getHexDecHash().length() - numOfVariables)));
replacementSupportRIM.setDeviceName(deviceHostName);
referenceManifestRepository.save(replacementSupportRIM);
} else if (supportRim.isArchived()) {
@@ -578,8 +578,8 @@ private void generateDigestRecords(final String manufacturer, final String model
}
}
- if (baseSupportRim != null &&
- referenceDigestValueRepository.findBySupportRimHash(baseSupportRim.getHexDecHash()).isEmpty()) {
+ if (baseSupportRim != null
+ && referenceDigestValueRepository.findBySupportRimHash(baseSupportRim.getHexDecHash()).isEmpty()) {
try {
TCGEventLog eventLog = new TCGEventLog(baseSupportRim.getRimBytes());
ReferenceDigestValue rdv;
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/package-info.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/package-info.java
index 98904bcb1..d3d0d852b 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/package-info.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/package-info.java
@@ -1 +1,4 @@
+/**
+ * This package includes services that are used to assist with the provisioning process.
+ */
package hirs.attestationca.persist.provision.service;
From 68b1a7f518acfc061950c689bf0b1da8fac5f67b Mon Sep 17 00:00:00 2001
From: ThatSilentCoder <184309164+ThatSilentCoder@users.noreply.github.com>
Date: Fri, 20 Mar 2026 11:29:16 -0400
Subject: [PATCH 25/25] v3.1_issue_1127: Addressed checkstyle warnings
---
.../persist/entity/manager/CACredentialRepository.java | 7 ++++---
.../entity/manager/IDevIDCertificateRepository.java | 3 ++-
.../entity/manager/IssuedCertificateRepository.java | 3 ++-
.../entity/manager/PlatformCertificateRepository.java | 3 ++-
.../entity/manager/ReferenceManifestRepository.java | 6 ++++--
.../attestationca/persist/enums/PublicKeyAlgorithm.java | 3 +--
.../persist/provision/controllers/package-info.java | 2 +-
7 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/CACredentialRepository.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/CACredentialRepository.java
index cd65b0e97..93bfe269b 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/CACredentialRepository.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/CACredentialRepository.java
@@ -22,8 +22,8 @@
public interface CACredentialRepository extends JpaRepository {
/**
- * Query that retrieves a count of {@link CertificateAuthorityCredential} objects in the database filtered by the provided
- * archive flag.
+ * Query that retrieves a count of {@link CertificateAuthorityCredential} objects in the database filtered by the
+ * provided archive flag.
*
* @param archiveFlag archive flag
* @return a count of {@link CertificateAuthorityCredential} objects
@@ -31,7 +31,8 @@ public interface CACredentialRepository extends JpaRepository {
/**
- * Query that retrieves a count of {@link IDevIDCertificate} objects in the database filtered by the provided archive flag.
+ * Query that retrieves a count of {@link IDevIDCertificate} objects in the database filtered by the provided
+ * archive flag.
*
* @param archiveFlag archive flag
* @return a count of {@link IDevIDCertificate} objects
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/IssuedCertificateRepository.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/IssuedCertificateRepository.java
index b5fc8f2b5..f1ed74c2d 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/IssuedCertificateRepository.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/IssuedCertificateRepository.java
@@ -22,7 +22,8 @@
public interface IssuedCertificateRepository extends JpaRepository {
/**
- * Query that retrieves a count of {@link IssuedAttestationCertificate} objects in the database filtered by the provided archive flag.
+ * Query that retrieves a count of {@link IssuedAttestationCertificate} objects in the database filtered by the
+ * provided archive flag.
*
* @param archiveFlag archive flag
* @return a count of {@link IssuedAttestationCertificate} objects
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/PlatformCertificateRepository.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/PlatformCertificateRepository.java
index e41094389..6513ebbfa 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/PlatformCertificateRepository.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/PlatformCertificateRepository.java
@@ -22,7 +22,8 @@
public interface PlatformCertificateRepository extends JpaRepository {
/**
- * Query that retrieves a count of {@link PlatformCredential} objects in the database filtered by the provided archive flag.
+ * Query that retrieves a count of {@link PlatformCredential} objects in the database filtered by the provided
+ * archive flag.
*
* @param archiveFlag archive flag
* @return a count of {@link PlatformCredential} objects
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/ReferenceManifestRepository.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/ReferenceManifestRepository.java
index f66e88ccf..9ef2de034 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/ReferenceManifestRepository.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/ReferenceManifestRepository.java
@@ -104,7 +104,8 @@ public interface ReferenceManifestRepository extends JpaRepository findByArchiveFlag(boolean archiveFlag);
/**
- * Query that retrieves a count of {@link ReferenceManifest} objects in the database filtered by the provided archive flag.
+ * Query that retrieves a count of {@link ReferenceManifest} objects in the database filtered by the provided
+ * archive flag.
*
* @param archiveFlag archive flag
* @return a count of {@link ReferenceManifest} objects
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
index 4e43467db..3b3ca781f 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/PublicKeyAlgorithm.java
@@ -46,7 +46,7 @@ public enum PublicKeyAlgorithm {
* The name of the algorithm.
*/
private final String algorithmName;
-
+
/**
* Retrieves the enum by the algorithm ID.
*
@@ -62,4 +62,3 @@ public static PublicKeyAlgorithm fromId(final int algorithmId) {
return UNKNOWN; // If no match found, return UNKNOWN
}
}
-
diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/controllers/package-info.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/controllers/package-info.java
index 31e20d1b4..01fe465f2 100644
--- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/controllers/package-info.java
+++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/controllers/package-info.java
@@ -1,4 +1,4 @@
/**
* Package includes all the REST controllers used in the provisioning process.
*/
-package hirs.attestationca.persist.provision.controllers;
\ No newline at end of file
+package hirs.attestationca.persist.provision.controllers;