diff --git a/.ci/system-tests/sys_test_common.sh b/.ci/system-tests/sys_test_common.sh index a31313432..843a1bcc2 100644 --- a/.ci/system-tests/sys_test_common.sh +++ b/.ci/system-tests/sys_test_common.sh @@ -60,7 +60,7 @@ docker exec -i $aca_container mysql -u root -proot -D hirs_db -e "Update PolicyS 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 ComponentInfo;truncate ComponentResult;truncate Device;truncate DeviceInfoReport; 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/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/AttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java deleted file mode 100644 index 2a5cb4580..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/AttestationCertificateAuthority.java +++ /dev/null @@ -1,140 +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 lombok.extern.log4j.Log4j2; - -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 { - - /** - * Container wired ACA private key. - */ - private final PrivateKey privateKey; - - /** - * Container wired ACA certificate. - */ - private final X509Certificate acaCertificate; - - /** - * 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 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 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.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 - */ - 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 - */ - byte[] processCertificateRequest(final byte[] certificateRequest) { - 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/CriteriaModifier.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/CriteriaModifier.java deleted file mode 100644 index 8c42b3837..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/CriteriaModifier.java +++ /dev/null @@ -1,17 +0,0 @@ -package hirs.attestationca.persist; - -import jakarta.persistence.criteria.CriteriaQuery; - -/** - * Allows a user of the DBManager to modify the criteria object before processing. - * - * @param the parameter type - */ -public interface CriteriaModifier { - /** - * Allows a client to modify the criteria object by reference. - * - * @param criteria The hibernate criteria builder object - */ - void modify(CriteriaQuery criteria); -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/OrderedListQuerier.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/OrderedListQuerier.java deleted file mode 100644 index 63e935156..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/OrderedListQuerier.java +++ /dev/null @@ -1,65 +0,0 @@ -package hirs.attestationca.persist; - -import java.util.Map; - -/** - * Interface defining methods for getting ordered lists from a data source. Includes - * properties for sorting, paging, and searching. - * - * @param the record type, T. - */ -public interface OrderedListQuerier { - - /** - * Returns a list of all Ts that are ordered by a column and - * direction (ASC, DESC) that is provided by the user. This method helps - * support the server-side processing in the JQuery DataTables. - * - * @param clazz class type of Ts to search for (may be null to - * use Class<T>) - * @param columnToOrder Column to be ordered - * @param ascending direction of sort - * @param firstResult starting point of first result in set - * @param maxResults total number we want returned for display in table - * @param search string of criteria to be matched to visible columns - * @param searchableColumns Map of String and boolean values with column - * headers and whether they should be searched. Boolean is true if field provides - * a typical String that can be searched by Hibernate without transformation. - * @return FilteredRecordsList object with query data - * @throws DBManagerException if unable to create the list - */ - FilteredRecordsList getOrderedList( - Class clazz, String columnToOrder, - boolean ascending, int firstResult, - int maxResults, String search, - Map searchableColumns) - throws DBManagerException; - - - /** - * Returns a list of all Ts that are ordered by a column and - * direction (ASC, DESC) that is provided by the user. This method helps - * support the server-side processing in the JQuery DataTables. For entities that support - * soft-deletes, the returned list does not contain Ts that have been soft-deleted. - * - * @param clazz class type of Ts to search for (may be null to - * use Class<T>) - * @param columnToOrder Column to be ordered - * @param ascending direction of sort - * @param firstResult starting point of first result in set - * @param maxResults total number we want returned for display in table - * @param search string of criteria to be matched to visible columns - * @param searchableColumns Map of String and boolean values with column - * headers and whether they should be searched. Boolean is true if field provides - * a typical String that can be searched by Hibernate without transformation. - * @param criteriaModifier a way to modify the criteria used in the query - * @return FilteredRecordsList object with query data - * @throws DBManagerException if unable to create the list - */ - FilteredRecordsList getOrderedList( - Class clazz, String columnToOrder, - boolean ascending, int firstResult, - int maxResults, String search, - Map searchableColumns, CriteriaModifier criteriaModifier) - throws DBManagerException; -} 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 ab00ced11..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulAttestationCertificateAuthority.java +++ /dev/null @@ -1,135 +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 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.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 - implements RestfulInterface { - - /** - * Constructor. - * - * @param supplyChainValidationService scp service - * @param privateKey the ACA private key - * @param acaCertificate the ACA certificate - * @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 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, 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) { - 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/CACredentialRepository.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/CACredentialRepository.java index cd65b0e97..7d45a78d3 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 - * The {@link EndorsementCredentialRepository} interface extends {@link JpaRepository} to provide basic CRUD operations, - * including save, find, delete, and query methods. Custom query methods can be defined + * The {@link EndorsementCertificateRepository} interface extends {@link JpaRepository} to provide + * basic CRUD operations, including save, find, delete, and query methods. Custom query methods can be defined * using Spring Data JPA's query method naming conventions or with the Query annotation. *

*/ @Repository -public interface EndorsementCredentialRepository extends JpaRepository { +public interface EndorsementCertificateRepository extends JpaRepository { /** * Query that retrieves a count of {@link EndorsementCredential} objects in the database filtered by the diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/IDevIDCertificateRepository.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/IDevIDCertificateRepository.java index cbe22df5b..e06d7db27 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/IDevIDCertificateRepository.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/manager/IDevIDCertificateRepository.java @@ -21,7 +21,8 @@ public interface IDevIDCertificateRepository 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/service/util/DataTablesColumn.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/DataTablesColumn.java similarity index 95% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/util/DataTablesColumn.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/DataTablesColumn.java index cb7d43296..b3c0b47ed 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/util/DataTablesColumn.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/DataTablesColumn.java @@ -1,4 +1,4 @@ -package hirs.attestationca.persist.service.util; +package hirs.attestationca.persist.entity.userdefined; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/DownloadFile.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/DownloadFile.java similarity index 88% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/DownloadFile.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/DownloadFile.java index 0a7df9903..27735a804 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/util/DownloadFile.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/DownloadFile.java @@ -1,4 +1,4 @@ -package hirs.attestationca.persist.util; +package hirs.attestationca.persist.entity.userdefined; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/FilteredRecordsList.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/FilteredRecordsList.java similarity index 92% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/FilteredRecordsList.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/FilteredRecordsList.java index 0fedb9946..da8136337 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/FilteredRecordsList.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/FilteredRecordsList.java @@ -1,4 +1,4 @@ -package hirs.attestationca.persist; +package hirs.attestationca.persist.entity.userdefined; import lombok.Data; import lombok.EqualsAndHashCode; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ConformanceCredential.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ConformanceCredential.java deleted file mode 100644 index 963f869f5..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/certificate/ConformanceCredential.java +++ /dev/null @@ -1,66 +0,0 @@ -package hirs.attestationca.persist.entity.userdefined.certificate; - -import hirs.attestationca.persist.entity.userdefined.Certificate; -import jakarta.persistence.Entity; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -import java.io.IOException; -import java.nio.file.Path; - -/** - * This class persists Conformance credentials by extending the base Certificate - * class with fields unique to Conformance credentials. - */ -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Entity -public class ConformanceCredential extends Certificate { - -// /** -// * This class enables the retrieval of ConformanceCredentials by their attributes. -// */ -// public static class Selector extends CertificateSelector { -// /** -// * Construct a new CertificateSelector that will use the given {@link CertificateManager} to -// * retrieve one or many ConformanceCredentials. -// * -// * @param certificateManager the certificate manager to be used to retrieve certificates -// */ -// public Selector(final CertificateManager certificateManager) { -// super(certificateManager, ConformanceCredential.class); -// } -// } - -// /** -// * Get a Selector for use in retrieving ConformanceCredentials. -// * -// * @param certMan the CertificateManager to be used to retrieve persisted certificates -// * @return a ConformanceCredential.Selector instance to use for retrieving certificates -// */ -// public static Selector select(final CertificateManager certMan) { -// return new Selector(certMan); -// } - - /** - * Construct a new ConformanceCredential given its binary contents. The given certificate - * should represent either an X509 certificate or X509 attribute certificate. - * - * @param certificateBytes the contents of a certificate file - * @throws IOException if there is a problem extracting information from the certificate - */ - public ConformanceCredential(final byte[] certificateBytes) throws IOException { - super(certificateBytes); - } - - /** - * Construct a new ConformanceCredential by parsing the file at the given path. The given - * certificate should represent either an X509 certificate or X509 attribute certificate. - * - * @param certificatePath the path on disk to a certificate - * @throws IOException if there is a problem reading the file - */ - public ConformanceCredential(final Path certificatePath) throws IOException { - super(certificatePath); - } - -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/PortalInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/PortalInfo.java deleted file mode 100644 index 039e0302a..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/PortalInfo.java +++ /dev/null @@ -1,102 +0,0 @@ -package hirs.attestationca.persist.entity.userdefined.info; - -import hirs.utils.enums.PortalScheme; -import jakarta.persistence.Access; -import jakarta.persistence.AccessType; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * Store information about the Portal into the database. - */ -@NoArgsConstructor -@Getter -@Entity -@Table(name = "PortalInfo") -@Access(AccessType.FIELD) -public class PortalInfo { - - @Id - @Column - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - @Column(unique = true, nullable = false) - private String name; - @Column - private InetAddress ipAddress; - @Column - private int port = 0; - @Column - private String context; - - /** - * Sets the scheme name of the portal. - * - * @param scheme Name of the portal. - */ - public void setSchemeName(final PortalScheme scheme) { - if (scheme == null) { - throw new NullPointerException("Scheme cannot be null"); - } - this.name = scheme.name(); - } - - /** - * Stores the address of the portal. - * - * @param inetAddress address used by the portal. - */ - public void setIpAddress(final InetAddress inetAddress) { - if (inetAddress == null) { - throw new IllegalArgumentException("setIpAddress input was null."); - } - - this.ipAddress = inetAddress; - } - - /** - * Resolves, then stores the address of the portal. - * - * @param host host name or address of the portal - * @throws UnknownHostException For problems resolving or storing the host. - */ - public void setIpAddress(final String host) throws UnknownHostException { - this.ipAddress = InetAddress.getByName(host); - } - - /** - * Store the port of the portal. - * - * @param port port of the portal - */ - public void setPort(final int port) { - final int upperBound = 65535; - if (port > 0 && port <= upperBound) { - this.port = port; - } else { - throw new IllegalArgumentException("Failed to store portal port. Provided number was" - + " outside of valid range (1 - " + upperBound + ")"); - } - } - - /** - * Sets the context name of the portal. - * - * @param context Context name of portal. - */ - public void setContextName(final String context) { - if (context == null) { - throw new NullPointerException("Context cannot be null"); - } - this.context = context; - } -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/RIMInfo.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/RIMInfo.java deleted file mode 100644 index 48c301cdd..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/info/RIMInfo.java +++ /dev/null @@ -1,66 +0,0 @@ -package hirs.attestationca.persist.entity.userdefined.info; - -import hirs.utils.StringValidator; -import hirs.utils.enums.DeviceInfoEnums; -import jakarta.persistence.Column; -import jakarta.persistence.Embeddable; -import jakarta.xml.bind.annotation.XmlElement; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.ToString; - -import java.io.Serializable; - -/** - * Store information about the RIM into the database. - */ -@Getter -@EqualsAndHashCode -@ToString -@Embeddable -public class RIMInfo implements Serializable { - - @XmlElement - @Column(length = DeviceInfoEnums.MED_STRING_LENGTH, nullable = false) - private final String rimManufacturer; - - @XmlElement - @Column(length = DeviceInfoEnums.MED_STRING_LENGTH, nullable = false) - private final String model; - - @XmlElement - @Column(length = DeviceInfoEnums.MED_STRING_LENGTH, nullable = false) - private final String fileHash; - - @XmlElement - @Column(length = DeviceInfoEnums.MED_STRING_LENGTH, nullable = false) - private final String pcrHash; - - /** - * Constructor for the initial values of the class. - * - * @param rimManufacturer string of the rimManufacturer - * @param model string of the model - * @param fileHash string of the file hash - * @param pcrHash string of the pcr hash - */ - public RIMInfo(final String rimManufacturer, final String model, - final String fileHash, final String pcrHash) { - this.rimManufacturer = StringValidator.check(rimManufacturer, "rimManufacturer") - .notBlank().maxLength(DeviceInfoEnums.MED_STRING_LENGTH).getValue(); - this.model = StringValidator.check(model, "model") - .notBlank().maxLength(DeviceInfoEnums.MED_STRING_LENGTH).getValue(); - this.fileHash = StringValidator.check(fileHash, "fileHash") - .notBlank().maxLength(DeviceInfoEnums.MED_STRING_LENGTH).getValue(); - this.pcrHash = StringValidator.check(pcrHash, "pcrHash") - .notBlank().maxLength(DeviceInfoEnums.MED_STRING_LENGTH).getValue(); - } - - /** - * Default no parameter constructor. - */ - public RIMInfo() { - this(DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED, - DeviceInfoEnums.NOT_SPECIFIED, DeviceInfoEnums.NOT_SPECIFIED); - } -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/result/CertificateValidationResult.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/result/CertificateValidationResult.java deleted file mode 100644 index a48573f30..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/result/CertificateValidationResult.java +++ /dev/null @@ -1,50 +0,0 @@ -package hirs.attestationca.persist.entity.userdefined.result; - -import lombok.Getter; -import lombok.Setter; - -/** - * An CertificateValidationResult represents the result of a certificate validation - * operation. - */ -@Getter -@Setter -public class CertificateValidationResult { - private CertificateValidationStatus validationStatus; - private String validationResultMessage; - - /** - * Sets the certificate validation status and result message. - * - * @param status enum representing the certificate validation status - * @param resultMessage String representing certificate validation message - */ - public final void setCertValidationStatusAndResultMessage( - final CertificateValidationStatus status, - final String resultMessage) { - this.validationStatus = status; - this.validationResultMessage = resultMessage; - } - - - /** - * Enum used to represent certificate validation status. - */ - public enum CertificateValidationStatus { - - /** - * Represents a passing validation. - */ - PASS, - - /** - * Represents a failed validation. - */ - FAIL, - - /** - * Represents a validation error. - */ - ERROR - } -} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/result/package-info.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/result/package-info.java deleted file mode 100644 index 3ad7260fe..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/result/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package hirs.attestationca.persist.entity.userdefined.result; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/util/CertificateType.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/CertificateType.java similarity index 97% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/util/CertificateType.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/CertificateType.java index ced9fa12e..721402a9b 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/util/CertificateType.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/CertificateType.java @@ -1,4 +1,4 @@ -package hirs.attestationca.persist.service.util; +package hirs.attestationca.persist.enums; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/HealthStatus.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/HealthStatus.java index 4ff0c4571..66c9554d8 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/HealthStatus.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/enums/HealthStatus.java @@ -4,9 +4,6 @@ import lombok.Getter; import lombok.ToString; -import java.util.Arrays; -import java.util.stream.Collectors; - /** * HealthStatus is used to represent the health of a device. */ @@ -30,17 +27,4 @@ public enum HealthStatus { UNKNOWN("unknown"); private final String healthStatus; - - /** - * Determines if the provided health status is a valid health status. - * - * @param healthStatus string representation of the healh status - * @return true if the health status is valid, otherwise false - */ - public static boolean isValidStatus(final String healthStatus) { - return Arrays.stream(HealthStatus.values()) - .map(HealthStatus::name) - .collect(Collectors.toSet()) - .contains(healthStatus); - } } 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..7d150f5ca 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,7 @@ package hirs.attestationca.persist.exceptions; /** - * Generic exception thrown while a {@link hirs.attestationca.persist.AttestationCertificateAuthority} + * Generic exception thrown when 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/DBManagerException.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/DBManagerException.java similarity index 95% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/DBManagerException.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/DBManagerException.java index aec4ddc93..fb9ace264 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/DBManagerException.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/DBManagerException.java @@ -1,4 +1,4 @@ -package hirs.attestationca.persist; +package hirs.attestationca.persist.exceptions; /** * This class represents an Exception generated by a diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/DBServiceException.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/DBServiceException.java similarity index 95% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/DBServiceException.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/DBServiceException.java index 35bddbbbd..bac65cb30 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/DBServiceException.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/DBServiceException.java @@ -1,4 +1,4 @@ -package hirs.attestationca.persist; +package hirs.attestationca.persist.exceptions; /** * This class represents an Exception generated by a 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..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,7 +1,7 @@ package hirs.attestationca.persist.exceptions; /** - * Generic exception thrown while a {@link hirs.attestationca.persist.AttestationCertificateAuthority} + * 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/validation/SupplyChainValidatorException.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/SupplyChainValidatorException.java similarity index 96% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainValidatorException.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/SupplyChainValidatorException.java index 456eb0439..6609d42a1 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainValidatorException.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/exceptions/SupplyChainValidatorException.java @@ -1,4 +1,4 @@ -package hirs.attestationca.persist.validation; +package hirs.attestationca.persist.exceptions; /** * This class represents exceptions thrown by the SupplyChainValidator class. 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..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,7 +1,7 @@ package hirs.attestationca.persist.exceptions; /** - * Generic exception thrown when a {@link hirs.attestationca.persist.AttestationCertificateAuthority} + * 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/AbstractProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/AbstractProcessor.java deleted file mode 100644 index 7d981da83..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 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.get(0).getEndValidity().after(currentDate)) { - // so the issued AC is not expired - // however are we within the threshold - days = ProvisionUtils.daysBetween(currentDate, issuedAc.get(0).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/provision/IdentityClaimProcessor.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java deleted file mode 100644 index 4866ff654..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/IdentityClaimProcessor.java +++ /dev/null @@ -1,883 +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.exceptions.IdentityProcessingException; -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 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.security.interfaces.RSAPublicKey; -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; - -@Log4j2 -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 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 TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository; - - /** - * 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 - */ - public IdentityClaimProcessor( - 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; - setPolicyRepository(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)) { - log.error("Identity claim empty throwing exception."); - throw new IllegalArgumentException("The IdentityClaim sent by the client" - + " cannot be null or empty."); - } - - final PolicyRepository policyRepository = this.getPolicyRepository(); - 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 - RSAPublicKey ekPub = ProvisionUtils.parsePublicKey(claim.getEkPublicArea().toByteArray()); - AppraisalStatus.Status validationResult = AppraisalStatus.Status.FAIL; - - try { - validationResult = doSupplyChainValidation(claim, ekPub); - } catch (Exception ex) { - log.error(ex.getMessage()); - } - - ByteString blobStr = ByteString.copyFrom(new byte[]{}); - - if (validationResult == AppraisalStatus.Status.PASS) { - RSAPublicKey akPub = ProvisionUtils.parsePublicKey(claim.getAkPublicArea().toByteArray()); - byte[] nonce = ProvisionUtils.generateRandomBytes(NONCE_LENGTH); - blobStr = ProvisionUtils.tpm20MakeCredential(ekPub, 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 = - parseEcFromIdentityClaim(claim, ekPub, certificateRepository); - - // attempt to find platform credentials to validate - List platformCredentials = 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/controllers/AttestationCertificateAuthorityRestController.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/controllers/AttestationCertificateAuthorityRestController.java new file mode 100644 index 000000000..760c0e551 --- /dev/null +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/controllers/AttestationCertificateAuthorityRestController.java @@ -0,0 +1,71 @@ +package hirs.attestationca.persist.provision.controllers; + +import hirs.attestationca.persist.provision.service.AttestationCertificateAuthorityService; +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; + +/** + * REST Controller for the ACA, responsible for communicating with the Provisioner during the provisioning process. + */ +@RestController +@RequestMapping("/HIRS_AttestationCA") +@Log4j2 +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 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) { + return attestationCertificateAuthorityService.processCertificateRequest(certificateRequest); + } + + /** + * Processes a GET request to retrieve the byte array representation of the leaf ACA certificate's public key. + * + * @return byte array representation of the leaf ACA certificate's public key + */ + @ResponseBody + @GetMapping("/public-key") + public byte[] 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..01fe465f2 --- /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; 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 deleted file mode 100644 index 86a8ea5f2..000000000 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelper.java +++ /dev/null @@ -1,165 +0,0 @@ -package hirs.attestationca.persist.provision.helper; - -import hirs.attestationca.persist.DBManagerException; -import hirs.attestationca.persist.entity.manager.CertificateRepository; -import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; -import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; -import lombok.extern.log4j.Log4j2; - -import java.util.List; - - -/** - * Utility class which includes credential management functions used by the ACA. - */ -@Log4j2 -public final class CredentialManagementHelper { - - private CredentialManagementHelper() { - } - - /** - * 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 - * @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"); - } - - if (endorsementBytes == null) { - throw new IllegalArgumentException("null endorsement credential bytes"); - } - - if (endorsementBytes.length <= 1) { - throw new IllegalArgumentException( - String.format("%d-length byte array given for endorsement credential", - endorsementBytes.length) - ); - } - - log.info("Parsing Endorsement Credential of length {}", endorsementBytes.length); - - EndorsementCredential endorsementCredential; - try { - endorsementCredential = EndorsementCredential - .parseWithPossibleHeader(endorsementBytes); - } catch (IllegalArgumentException iae) { - log.error(iae.getMessage()); - throw iae; - } - - int certificateHash = endorsementCredential.getCertificateHash(); - EndorsementCredential existingCredential = (EndorsementCredential) certificateRepository - .findByCertificateHash(certificateHash); - - if (existingCredential == null) { - log.info("No Endorsement Credential found with hash: {}", certificateHash); - endorsementCredential.setDeviceName(deviceName); - return certificateRepository.save(endorsementCredential); - } else if (existingCredential.isArchived()) { - // if the EK is stored in the DB and it's archived, un-archive it. - log.info("Un-archiving endorsement credential"); - existingCredential.restore(); - existingCredential.resetCreateTime(); - certificateRepository.save(existingCredential); - } - return existingCredential; - } - - /** - * 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 - * @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"); - } - - if (platformBytes == null) { - log.error("The provided platform credential byte array is null."); - throw new IllegalArgumentException("null platform credential bytes"); - } - - 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" - ); - } - - log.info("Parsing Platform Credential of length {}", platformBytes.length); - - try { - PlatformCredential platformCredential = - PlatformCredential.parseWithPossibleHeader(platformBytes); - - if (platformCredential == null) { - log.error("The platform credential that was parsed with the provided" - + "byte array was null"); - return null; - } - - PlatformCredential existingCredential = (PlatformCredential) certificateRepository - .findByCertificateHash(platformCredential.getCertificateHash()); - - if (existingCredential == null) { - if (platformCredential.getPlatformSerial() != null) { - List certificates = certificateRepository - .byBoardSerialNumber(platformCredential.getPlatformSerial()); - if (!certificates.isEmpty()) { - // found associated certificates - for (PlatformCredential pc : certificates) { - if (pc.isPlatformBase() && platformCredential.isPlatformBase()) { - // found a base in the database associated with - // parsed certificate - log.error("Base certificate stored" - + " in database with same platform" - + "serial number. ({})", - platformCredential.getPlatformSerial()); - return null; - } - } - } - } - platformCredential.setDeviceName(deviceName); - return certificateRepository.save(platformCredential); - } else if (existingCredential.isArchived()) { - // if the PC is stored in the DB and it's archived, un-archive it. - log.info("Un-archiving platform credential"); - existingCredential.restore(); - certificateRepository.save(existingCredential); - return existingCredential; - } - - return existingCredential; - } catch (DBManagerException dbEx) { - log.error("Error retrieving or saving platform credential to the database", dbEx); - } catch (Exception e) { - log.error("Error parsing platform credential", e); - } - - 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/RestfulInterface.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityService.java similarity index 60% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulInterface.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityService.java index a4bb8a00a..89b6c4721 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/RestfulInterface.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityService.java @@ -1,9 +1,9 @@ -package hirs.attestationca.persist; +package hirs.attestationca.persist.provision.service; /** - * Defines the responsibilities of the Attestation Certificate Authority. + * Interface that defines the responsibilities of the Attestation Certificate Authority service. */ -public interface RestfulInterface { +public interface AttestationCertificateAuthorityService { /** * Processes the provided identity claim. @@ -21,4 +21,10 @@ public interface RestfulInterface { */ byte[] processCertificateRequest(byte[] certificateRequest); + /** + * 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/provision/service/AttestationCertificateAuthorityServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java new file mode 100644 index 000000000..64e9b9456 --- /dev/null +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceImpl.java @@ -0,0 +1,58 @@ +package hirs.attestationca.persist.provision.service; + +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * Service class responsible for handling both certificate and identity claim requests made by the provisioner. + */ +@Service +@Log4j2 +public class AttestationCertificateAuthorityServiceImpl implements AttestationCertificateAuthorityService { + private final CertificateRequestProcessorService certificateRequestProcessorService; + private final IdentityClaimProcessorService identityClaimProcessorService; + + /** + * Constructor. + * + * @param certificateRequestProcessorService certificate request processor service + * @param identityClaimProcessorService identity claim processor service + */ + @Autowired + public AttestationCertificateAuthorityServiceImpl( + final CertificateRequestProcessorService certificateRequestProcessorService, + final IdentityClaimProcessorService identityClaimProcessorService) { + this.certificateRequestProcessorService = certificateRequestProcessorService; + this.identityClaimProcessorService = identityClaimProcessorService; + } + + /** + * 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 identityClaimProcessorService.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) { + return certificateRequestProcessorService.processCertificateRequest(certificateRequest); + } + + /** + * Retrieves the encoded public key of the leaf certificate. + * + * @return encoded public key of the leaf certificate + */ + public byte[] getLeafACACertPublicKey() { + return certificateRequestProcessorService.getLeafACACertificatePublicKey(); + } +} 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/CertificateRequestProcessorService.java similarity index 50% 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/CertificateRequestProcessorService.java index cc9e0b197..4f3a7ab38 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/CertificateRequestProcessor.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CertificateRequestProcessorService.java @@ -1,12 +1,10 @@ -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; import hirs.attestationca.persist.entity.tpm.TPM2ProvisionerState; import hirs.attestationca.persist.entity.userdefined.Device; import hirs.attestationca.persist.entity.userdefined.PolicySettings; @@ -17,158 +15,174 @@ import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport; import hirs.attestationca.persist.enums.AppraisalStatus; import hirs.attestationca.persist.exceptions.CertificateProcessingException; +import hirs.attestationca.persist.provision.helper.IssuedCertificateAttributeHelper; import hirs.attestationca.persist.provision.helper.ProvisionUtils; -import hirs.attestationca.persist.service.SupplyChainValidationService; +import hirs.attestationca.persist.validation.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.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.security.interfaces.RSAPublicKey; +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 CertificateRequestProcessor extends AbstractProcessor { - +public class CertificateRequestProcessorService { private final SupplyChainValidationService supplyChainValidationService; - private final CertificateRepository certificateRepository; + private final CredentialManagementService credentialManagementService; + private final Tpm2ProvisionerStateService tpm2ProvisionerStateService; private final DeviceRepository deviceRepository; + private final PolicyRepository policyRepository; private final X509Certificate acaCertificate; - private final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository; + private final int certificateValidityInDays; + private final PrivateKey privateKey; /** * Constructor. * - * @param supplyChainValidationService object that is used to run provisioning - * @param certificateRepository db connector for all certificates. - * @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 tpm2ProvisionerStateRepository db connector for provisioner state. - * @param policyRepository db connector for policies. + * @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. */ - public CertificateRequestProcessor(final SupplyChainValidationService supplyChainValidationService, - final CertificateRepository certificateRepository, - final DeviceRepository deviceRepository, - final PrivateKey privateKey, - final X509Certificate acaCertificate, - final int validDays, - final TPM2ProvisionerStateRepository tpm2ProvisionerStateRepository, - final PolicyRepository policyRepository) { - super(privateKey, validDays); + @Autowired + public CertificateRequestProcessorService(final SupplyChainValidationService supplyChainValidationService, + final CredentialManagementService credentialManagementService, + final Tpm2ProvisionerStateService tpm2ProvisionerStateService, + final DeviceRepository deviceRepository, + 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.certificateRepository = certificateRepository; this.deviceRepository = deviceRepository; this.acaCertificate = acaCertificate; - this.tpm2ProvisionerStateRepository = tpm2ProvisionerStateRepository; - setPolicyRepository(policyRepository); + this.policyRepository = policyRepository; + this.privateKey = privateKey; + } + + /** + * 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, - * 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)) { - throw new IllegalArgumentException("The CertificateRequest sent by the client" - + " cannot be null or empty."); + 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); } - final PolicyRepository policyRepository = this.getPolicyRepository(); 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) { - 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); + certificateRequestJsonString = JsonFormat.printer().print(certificateRequest); } 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 - 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 - RSAPublicKey ekPub = ProvisionUtils.parsePublicKey(claim.getEkPublicArea().toByteArray()); + RSAPublicKey ekPublicKey = ProvisionUtils.parsePublicKey(identityClaim.getEkPublicArea().toByteArray()); // Get attestation public key - RSAPublicKey akPub = ProvisionUtils.parsePublicKey(claim.getAkPublicArea().toByteArray()); + RSAPublicKey akPublicKey = ProvisionUtils.parsePublicKey(identityClaim.getAkPublicArea().toByteArray()); + + // Get LDevID public key if it exists + RSAPublicKey ldevidPublicKey = null; + if (identityClaim.hasLdevidPublicArea()) { + ldevidPublicKey = ProvisionUtils.parsePublicKey(identityClaim.getLdevidPublicArea().toByteArray()); + } // Get Endorsement Credential if it exists or was uploaded - EndorsementCredential endorsementCredential = parseEcFromIdentityClaim(claim, - ekPub, certificateRepository); + EndorsementCredential endorsementCredential = + credentialManagementService.parseEcFromIdentityClaim(identityClaim, ekPublicKey); // Get Platform Credentials if they exist or were uploaded - List platformCredentials = parsePcsFromIdentityClaim(claim, - endorsementCredential, certificateRepository); + List platformCredentials = + credentialManagementService.parsePcsFromIdentityClaim(identityClaim, + endorsementCredential); - // Get LDevID public key if it exists - RSAPublicKey ldevidPub = null; - if (claim.hasLdevidPublicArea()) { - ldevidPub = ProvisionUtils.parsePublicKey(claim.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() != null && !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 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(akPub, - endorsementCredential, platformCredentials, deviceName, acaCertificate); - if (ldevidPub != null) { + X509Certificate attestationCertificate = generateCredential(akPublicKey, + endorsementCredential, platformCredentials, device.getName(), acaCertificate); + + if (ldevidPublicKey != null) { // Create signed LDevID certificate - X509Certificate ldevidCertificate = generateCredential(ldevidPub, - endorsementCredential, platformCredentials, deviceName, acaCertificate); + X509Certificate ldevidCertificate = generateCredential(ldevidPublicKey, + endorsementCredential, platformCredentials, device.getName(), acaCertificate); byte[] derEncodedAttestationCertificate = ProvisionUtils.getDerEncodedCertificate( attestationCertificate); byte[] derEncodedLdevidCertificate = ProvisionUtils.getDerEncodedCertificate( @@ -179,35 +193,38 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) { ldevidCertificate); // 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); + tpm2ProvisionerStateService.deleteTPM2ProvisionerState(tpm2ProvisionerState); + + 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); + 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 { - 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() @@ -219,7 +236,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 " @@ -239,15 +256,16 @@ public byte[] processCertificateRequest(final byte[] certificateRequest) { 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. newBuilder().setStatus(ProvisionerTpm2.ResponseStatus.PASS); - boolean generateAtt = saveAttestationCertificate(certificateRepository, + boolean generateAtt = credentialManagementService.saveAttestationCertificate( derEncodedAttestationCertificate, endorsementCredential, platformCredentials, device, false); + if (generateAtt) { certificateResponseBuilder = certificateResponseBuilder.setCertificate(pemEncodedAttestationCertificate); @@ -257,11 +275,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() @@ -274,7 +292,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 " @@ -299,10 +317,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() @@ -312,9 +330,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); @@ -331,9 +348,8 @@ 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: {}", - certificateRequestJsonString.isEmpty() ? request : certificateRequestJsonString); + log.error("Could not process credential request. Invalid nonce provided: {}", + certificateRequestJsonString.isEmpty() ? certificateRequest : certificateRequestJsonString); log.info("------------- End Of Protobuf Log Of Certificate Request After Failed " + "Validation (Invalid Nonce) -------------"); @@ -342,19 +358,60 @@ 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. * - * @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; } @@ -369,8 +426,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 @@ -387,4 +443,73 @@ private AppraisalStatus.Status doQuoteValidation(final Device device) { return validationResult; } + + /** + * Generates a credential using the specified public key. + * + * @param publicKey non-null public key + * @param endorsementCredential the endorsement credential + * @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 + */ + 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 x509v3CertificateBuilder = new X509v3CertificateBuilder(issuer, serialNumber, + notBefore, notAfter, null /* subjectName */, subjectPublicKeyInfo); + + Extension subjectAlternativeName = IssuedCertificateAttributeHelper.buildSubjectAlternativeNameFromCerts( + endorsementCredential, platformCredentials, deviceName); + + Extension authKeyIdentifier = IssuedCertificateAttributeHelper.buildAuthorityKeyIdentifier(acaCertificate); + + x509v3CertificateBuilder.addExtension(subjectAlternativeName); + + if (authKeyIdentifier != null) { + x509v3CertificateBuilder.addExtension(authKeyIdentifier); + } + + // identify cert as an AIK with this extension + if (IssuedCertificateAttributeHelper.EXTENDED_KEY_USAGE_EXTENSION != null) { + x509v3CertificateBuilder.addExtension(IssuedCertificateAttributeHelper.EXTENDED_KEY_USAGE_EXTENSION); + } else { + log.warn("Failed to build extended key usage extension and add to AIK"); + throw new IllegalArgumentException( + "Extended Key Usage attribute unavailable. Unable to issue certificates"); + } + + // Add signing extension + x509v3CertificateBuilder.addExtension(Extension.keyUsage, true, + new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment)); + + // Basic constraints + x509v3CertificateBuilder.addExtension(Extension.basicConstraints, true, new BasicConstraints(false)); + + ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA").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); + } + } } 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 new file mode 100644 index 000000000..d2ac42d51 --- /dev/null +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/CredentialManagementService.java @@ -0,0 +1,462 @@ +package hirs.attestationca.persist.provision.service; + +import com.google.protobuf.ByteString; +import hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2; +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.exceptions.DBManagerException; +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; + +/** + * 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 CredentialManagementService { + private final PolicyRepository policyRepository; + private final CertificateRepository certificateRepository; + private final ComponentResultRepository componentResultRepository; + + /** + * Constructor. + * + * @param policyRepository policy repository + * @param certificateRepository certificate repository + * @param componentResultRepository component result repository + */ + @Autowired + public CredentialManagementService(final PolicyRepository policyRepository, + final CertificateRepository certificateRepository, + final ComponentResultRepository componentResultRepository) { + this.policyRepository = policyRepository; + this.certificateRepository = certificateRepository; + this.componentResultRepository = componentResultRepository; + } + + /** + * 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 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 EndorsementCredential storeEndorsementCredential(final byte[] endorsementBytes, final String deviceName) + throws IllegalArgumentException { + + if (endorsementBytes == null) { + throw new IllegalArgumentException("null endorsement credential bytes"); + } + + if (endorsementBytes.length <= 1) { + throw new IllegalArgumentException(String.format("%d-length byte array given for endorsement credential", + endorsementBytes.length) + ); + } + + log.info("Parsing Endorsement Credential of length {}", endorsementBytes.length); + + EndorsementCredential endorsementCredential; + try { + endorsementCredential = EndorsementCredential.parseWithPossibleHeader(endorsementBytes); + } catch (IllegalArgumentException iae) { + log.error(iae.getMessage()); + throw iae; + } + + int certificateHash = endorsementCredential.getCertificateHash(); + EndorsementCredential existingCredential = (EndorsementCredential) certificateRepository + .findByCertificateHash(certificateHash); + + if (existingCredential == null) { + log.info("No Endorsement Credential found with hash: {}", certificateHash); + endorsementCredential.setDeviceName(deviceName); + return certificateRepository.save(endorsementCredential); + } else if (existingCredential.isArchived()) { + // if the EK is stored in the DB and it's archived, un-archive it. + log.info("Un-archiving endorsement credential"); + existingCredential.restore(); + existingCredential.resetCreateTime(); + certificateRepository.save(existingCredential); + } + return existingCredential; + } + + /** + * Parses and stores the PC in the cert manager. If the cert is already present and archived, + * it is unarchived. + * + * @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 PlatformCredential storePlatformCredential(final byte[] platformBytes, final String deviceName) { + + if (platformBytes == null) { + log.error("The provided platform credential byte array is null."); + throw new IllegalArgumentException("null platform credential bytes"); + } + + 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"); + } + + log.info("Parsing Platform Credential of length {}", platformBytes.length); + + try { + PlatformCredential platformCredential = + PlatformCredential.parseWithPossibleHeader(platformBytes); + + if (platformCredential == null) { + log.error("The platform credential that was parsed with the provided byte array was null"); + return null; + } + + PlatformCredential existingCredential = (PlatformCredential) certificateRepository + .findByCertificateHash(platformCredential.getCertificateHash()); + + if (existingCredential == null) { + if (platformCredential.getPlatformSerial() != null) { + List certificates = certificateRepository + .byBoardSerialNumber(platformCredential.getPlatformSerial()); + if (!certificates.isEmpty()) { + // found associated certificates + for (PlatformCredential pc : certificates) { + if (pc.isPlatformBase() && platformCredential.isPlatformBase()) { + // found a base in the database associated with + // parsed certificate + log.error("Base certificate stored" + + " in database with same platform" + + "serial number. ({})", + platformCredential.getPlatformSerial()); + return null; + } + } + } + } + platformCredential.setDeviceName(deviceName); + return certificateRepository.save(platformCredential); + } else if (existingCredential.isArchived()) { + // if the PC is stored in the DB and it's archived, un-archive it. + log.info("Un-archiving platform credential"); + existingCredential.restore(); + certificateRepository.save(existingCredential); + return existingCredential; + } + + return existingCredential; + } catch (DBManagerException dbEx) { + log.error("Error retrieving or saving platform credential to the database", dbEx); + } catch (Exception e) { + log.error("Error parsing platform credential", e); + } + + 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; + } + + /** + * 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(final 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. + * + * @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 byte[] derEncodedAttestationCertificate, + final EndorsementCredential endorsementCredential, + final List platformCredentials, + final Device device, + final boolean ldevID) { + List issuedAc; + boolean generateCertificate; + 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; + } + + /** + * Gets the Endorsement Credential from the DB given the EK public key. + * + * @param ekPublicKey the EK public key + * @return the Endorsement credential, if found, otherwise null + */ + private EndorsementCredential getEndorsementCredential(final PublicKey ekPublicKey) { + 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 ec endorsement credential + * @return list of platform credentials + */ + private List getPlatformCredentials(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; + } + + /** + * 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(final 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/DeviceInfoProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java new file mode 100644 index 000000000..bf508274f --- /dev/null +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/DeviceInfoProcessorService.java @@ -0,0 +1,709 @@ +package hirs.attestationca.persist.provision.service; + + +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; +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.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; +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.regex.Pattern; + +/** + * 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 +public class DeviceInfoProcessorService { + private static final int MAC_BYTES = 6; + + 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 ComponentInfoRepository componentInfoRepository) + throws NoSuchAlgorithmException { + this.deviceRepository = deviceRepository; + this.referenceManifestRepository = referenceManifestRepository; + this.referenceDigestValueRepository = referenceDigestValueRepository; + this.componentInfoRepository = componentInfoRepository; + this.messageDigest = MessageDigest.getInstance("SHA-256"); + } + + /** + * Creates and updates a {@link Device} object after parsing the identity claim's Device Info. + * + * @param identityClaim Identity Claim + * @return the {@link Device} object representing the device + */ + public Device processDeviceInfo(final ProvisionerTpm2.IdentityClaim identityClaim) { + + log.info("Parsing Device Info from the Identity Claim"); + + final DeviceInfoReport deviceInfoReport = parseDeviceInfo(identityClaim); + + log.info("Processing Device Info Report"); + + // store device and device info report. + Device device = null; + + if (deviceInfoReport.getNetworkInfo() != null + && !StringUtils.isBlank(deviceInfoReport.getNetworkInfo().getHostname())) { + device = deviceRepository.findByName(deviceInfoReport.getNetworkInfo().getHostname()); + } + + if (device == null) { + device = new Device(deviceInfoReport); + } + device.setDeviceInfo(deviceInfoReport); + + 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)); + + 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 {@link DeviceInfoReport} object using the provided Identity Claim's Device Info. + * + * @param identityClaim the protobuf serialized Identity Claim containing the device info + * @return the {@link DeviceInfoReport} object representing the Device Info Report + */ + private DeviceInfoReport parseDeviceInfo(final ProvisionerTpm2.IdentityClaim identityClaim) { + ProvisionerTpm2.DeviceInfo provisionedDeviceInfo = identityClaim.getDv(); + + // Get Hardware info + HardwareInfo hardwareInfo = getHardwareInfo(provisionedDeviceInfo.getHw()); + + // Get TPM info (todo Currently unimplemented) + TPMInfo tpmInfo = getTPMInfo(provisionedDeviceInfo); + + // Get Network info + NetworkInfo networkInfo = getNetworkInfo(provisionedDeviceInfo.getNw()); + + // Get Firmware info + FirmwareInfo firmwareInfo = getFirmwareInfo(provisionedDeviceInfo.getFw()); + + // Get OS info + OSInfo osInfo = getOSInfo(provisionedDeviceInfo.getOs()); + + getAndUpdateRIMSUsingProvisionedDeviceInfo(provisionedDeviceInfo); + + // Create final device info report + DeviceInfoReport dvReport = new DeviceInfoReport(networkInfo, osInfo, firmwareInfo, hardwareInfo, tpmInfo, + identityClaim.getClientVersion()); + dvReport.setPaccorOutputString(identityClaim.getPaccorOutput()); + + return dvReport; + } + + /** + * Helper method that creates a {@link TPMInfo} object using the provided provisioned Device Info. + * (todo Currently unimplemented) + * + * @param provisionedDeviceInfo provisioned Device Info + * @return the {@link TPMInfo} object representing the Device's TPM Info + */ + private TPMInfo getTPMInfo(final ProvisionerTpm2.DeviceInfo provisionedDeviceInfo) { + String pcrValues = ""; + + if (provisionedDeviceInfo.hasPcrslist()) { + pcrValues = provisionedDeviceInfo.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} object using the provided provisioned Device Info's + * Hardware Info. + * + * @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 provisionedHardwareInfo) { + + // Make sure chassis info has at least one chassis + String firstChassisSerialNumber = DeviceInfoEnums.NOT_SPECIFIED; + if (provisionedHardwareInfo.getChassisInfoCount() > 0) { + firstChassisSerialNumber = provisionedHardwareInfo.getChassisInfo(0).getSerialNumber(); + } + + // Make sure baseboard info has at least one baseboard + String firstBaseboardSerialNumber = DeviceInfoEnums.NOT_SPECIFIED; + if (provisionedHardwareInfo.getBaseboardInfoCount() > 0) { + firstBaseboardSerialNumber = provisionedHardwareInfo.getBaseboardInfo(0).getSerialNumber(); + } + + return new HardwareInfo(provisionedHardwareInfo.getManufacturer(), provisionedHardwareInfo.getProductName(), + provisionedHardwareInfo.getProductVersion(), provisionedHardwareInfo.getSystemSerialNumber(), + firstChassisSerialNumber, firstBaseboardSerialNumber); + } + + /** + * Helper method that creates a {@link NetworkInfo} object using the provided provisioned Device Info's Network + * Info. + * + * @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 provisionedNetworkInfo) { + InetAddress ip = null; + try { + ip = InetAddress.getByName(provisionedNetworkInfo.getIpAddress()); + } catch (UnknownHostException uhEx) { + log.error("Unable to parse IP address from the provisioned Device Info: ", uhEx); + } + String[] macAddressParts = provisionedNetworkInfo.getMacAddress().split(":"); + + // convert mac hex string to byte values + byte[] macAddressBytes = new byte[MAC_BYTES]; + + if (macAddressParts.length == MAC_BYTES) { + for (int i = 0; i < MAC_BYTES; i++) { + Integer hex = HexUtils.hexToInt(macAddressParts[i]); + macAddressBytes[i] = hex.byteValue(); + } + } + + return new NetworkInfo(provisionedNetworkInfo.getHostname(), ip, macAddressBytes); + } + + /** + * Helper method that creates an {@link OSInfo} using the provided provisioned Device Info's OS info. + * + * @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 provisionedOsInfo) { + return new OSInfo(provisionedOsInfo.getOsName(), provisionedOsInfo.getOsVersion(), + provisionedOsInfo.getOsArch(), + provisionedOsInfo.getDistribution(), provisionedOsInfo.getDistributionRelease()); + } + + /** + * Helper method that creates a {@link FirmwareInfo} using the provided provisioned Device Info's Firmware Info. + * + * @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 provisionedFirmwareInfo) { + return new FirmwareInfo(provisionedFirmwareInfo.getBiosVendor(), provisionedFirmwareInfo.getBiosVersion(), + provisionedFirmwareInfo.getBiosReleaseDate()); + } + + /** + * Helper method that updates all Reference Integrity Manifests (RIMs) using the provided provisioned Device Info. + * + * @param provisionedDeviceInfo provisioned Device Info + */ + 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", provisionedDeviceInfo.getHw().getManufacturer(), + provisionedDeviceInfo.getHw().getProductName()); + + final String deviceInfoHostName = provisionedDeviceInfo.getNw().getHostname(); + + // update base RIMs using the identity claim's device information + 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 (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 + updateBaseSupportRIMSUsingDeviceInfo(provisionedDeviceInfo); + + generateDigestRecords(provisionedDeviceInfo.getHw().getManufacturer(), + provisionedDeviceInfo.getHw().getProductName()); + + // update event log information + 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 provisioned + * Device Info. + * + * @param defaultClientName default client name + * @param provisionedDeviceInfo provisioned Device Info + */ + private void updateBaseRIMSUsingDeviceInfo(final String defaultClientName, + final ProvisionerTpm2.DeviceInfo provisionedDeviceInfo) { + final List baseRims = referenceManifestRepository.findAllBaseRims(); + final List unarchivedRims = referenceManifestRepository.findByArchiveFlag(false); + final String deviceHostName = provisionedDeviceInfo.getNw().getHostname(); + + log.info("Device {} sent SWID tag files", deviceHostName); + + 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, + 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()); + referenceManifestRepository.save(matchedReplacementBaseRIM); + continue; + } + + // otherwise save the replacement base RIM we created + 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. */ + // 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."); + } + + final BaseReferenceManifest matchedUnarchivedBaseRIM = matchedUnarchivedBaseRIMOptional.get(); + matchedUnarchivedBaseRIM.setDeviceName(deviceHostName); + referenceManifestRepository.save(matchedUnarchivedBaseRIM); + } else { + baseRim.setDeviceName(deviceHostName); + referenceManifestRepository.save(baseRim); + } + } catch (Exception exception) { + log.error("Failed to process Base RIM file for device {}: {}", deviceHostName, + exception.getMessage(), exception); + } + } + } + + /** + * 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 provisionedDeviceInfo provisioned Device Info + */ + private void updateSupportRIMSUsingDeviceInfo(final String defaultClientName, + final ProvisionerTpm2.DeviceInfo provisionedDeviceInfo) { + final String deviceHostName = provisionedDeviceInfo.getNw().getHostname(); + final int numOfVariables = 5; + + log.info("Device {} sent Support RIM files", deviceHostName); + + final List unarchivedRims = referenceManifestRepository.findByArchiveFlag(false); + final List logfileList = provisionedDeviceInfo.getLogfileList(); + + for (ByteString logFile : logfileList) { + 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(replacementSupportRIM.getRimBytes()); + + // no issues, continue + replacementSupportRIM.setPlatformManufacturer(provisionedDeviceInfo.getHw().getManufacturer()); + replacementSupportRIM.setPlatformModel(provisionedDeviceInfo.getHw().getProductName()); + replacementSupportRIM.setFileName(String.format("%s_[%s].rimel", defaultClientName, + replacementSupportRIM.getHexDecHash().substring( + replacementSupportRIM.getHexDecHash().length() - numOfVariables))); + replacementSupportRIM.setDeviceName(deviceHostName); + 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())) + .map(rim -> (SupportReferenceManifest) rim) + .findFirst(); + + if (matchedUnarchivedSupportRIMOptional.isEmpty()) { + throw new Exception("Unable to locate an unarchived support RIM."); + } + + final SupportReferenceManifest matchedUnarchivedSupportRIM = + matchedUnarchivedSupportRIMOptional.get(); + matchedUnarchivedSupportRIM.setDeviceName(deviceHostName); + referenceManifestRepository.save(matchedUnarchivedSupportRIM); + } else { + supportRim.setDeviceName(deviceHostName); + referenceManifestRepository.save(supportRim); + } + } catch (Exception exception) { + log.error("Failed to process Support RIM file for device {}: {}", deviceHostName, + exception.getMessage(), exception); + + } + } + } + + /** + * Helper method that updates both base and support RIMs after modifying each type of RIM, ensuring that the + * updates are consistent and aligned. + * + * @param provisionedDeviceInfo provisioned Device Info + */ + 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 : swidfileList) { + final String swidFileHash = + Base64.getEncoder().encodeToString(messageDigest.digest(swidFile.toByteArray())); + + final BaseReferenceManifest baseRim = + (BaseReferenceManifest) referenceManifestRepository.findByBase64Hash(swidFileHash); + + if (baseRim != null) { + 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); + baseRim.setFileName(String.format("%s.swidtag", fileName)); + } + + // now update support rim + 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; + } + + 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()); + referenceManifestRepository.save(dbSupportRIM); + } + + referenceManifestRepository.save(baseRim); + } + } + } + + /** + * 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 = 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); + } + } + } + + /** + * Helper method that updates the event log information using the provisioned Device Info. + * + * @param provisionedDeviceInfo provisioned Device Info + */ + 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 provisioned device info + EventLogMeasurements provisionedEventLog = new EventLogMeasurements(fileName, + provisionedDeviceInfo.getLivelog().toByteArray()); + + // find the previous event log that's stored in the database. + EventLogMeasurements integrityMeasurements = + referenceManifestRepository.byMeasurementDeviceNameUnarchived(deviceHostName); + + // if the event log does exist in the database + if (integrityMeasurements != null) { + // archive it and update the entity in the database + integrityMeasurements.archive(); + referenceManifestRepository.save(integrityMeasurements); + } + + List baseRims = referenceManifestRepository.getBaseByManufacturerModel( + provisionedDeviceInfo.getHw().getManufacturer(), + provisionedDeviceInfo.getHw().getProductName()); + + provisionedEventLog.setDeviceName(deviceHostName); + provisionedEventLog.setPlatformManufacturer(provisionedDeviceInfo.getHw().getManufacturer()); + provisionedEventLog.setPlatformModel(provisionedDeviceInfo.getHw().getProductName()); + referenceManifestRepository.save(provisionedEventLog); + + 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(provisionedEventLog.getHexDecHash()); + sBaseRim.setEventLogHash(provisionedEventLog.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/IdentityClaimProcessorService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java new file mode 100644 index 000000000..a9908c56d --- /dev/null +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/IdentityClaimProcessorService.java @@ -0,0 +1,253 @@ +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.PolicyRepository; +import hirs.attestationca.persist.entity.tpm.TPM2ProvisionerState; +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.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.attestationca.persist.validation.SupplyChainValidationService; +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.security.interfaces.RSAPublicKey; +import java.util.List; +import java.util.Objects; + +/** + * Service class responsible for processing the Provisioner's Identity Claim. + */ +@Service +@Log4j2 +public class IdentityClaimProcessorService { + /** + * 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 DeviceInfoProcessorService deviceInfoProcessorService; + private final Tpm2ProvisionerStateService tpm2ProvisionerStateService; + private final PolicyRepository policyRepository; + + /** + * Constructor. + * + * @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 Tpm2ProvisionerStateService tpm2ProvisionerStateService, + final PolicyRepository policyRepository) { + this.supplyChainValidationService = supplyChainValidationService; + this.credentialManagementService = credentialManagementService; + this.deviceInfoProcessorService = deviceInfoProcessorService; + this.tpm2ProvisionerStateService = tpm2ProvisionerStateService; + this.policyRepository = policyRepository; + } + + /** + * 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 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[] identityClaimByteArray) { + log.info("Identity Claim has been received and is ready to be processed"); + + 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); + } + + final PolicySettings policySettings = policyRepository.findByName("Default"); + + // attempt to deserialize Protobuf Identity Claim + ProvisionerTpm2.IdentityClaim identityClaim = ProvisionUtils.parseIdentityClaim(identityClaimByteArray); + + String identityClaimJsonString = ""; + try { + 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 + RSAPublicKey endorsementCredentialPublicKey = + ProvisionUtils.parsePublicKey(identityClaim.getEkPublicArea().toByteArray()); + + AppraisalStatus.Status validationResult = AppraisalStatus.Status.FAIL; + + try { + validationResult = doSupplyChainValidation(identityClaim, endorsementCredentialPublicKey); + } catch (Exception ex) { + log.error(ex.getMessage()); + } + + ByteString blobStr = ByteString.copyFrom(new byte[]{}); + + if (validationResult == AppraisalStatus.Status.PASS) { + RSAPublicKey akPub = + ProvisionUtils.parsePublicKey(identityClaim.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: {}", identityClaimByteArray.length); + + tpm2ProvisionerStateService.saveTPM2ProvisionerState( + new TPM2ProvisionerState(nonce, identityClaimByteArray)); + + 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() + ? identityClaim : 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() + ? identityClaim : 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 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 identityClaim, + final PublicKey ekPublicKey) throws IOException { + + // Find an endorsement credential to validate + EndorsementCredential endorsementCredential = + credentialManagementService.parseEcFromIdentityClaim(identityClaim, ekPublicKey); + + // Find platform credentials to validate + List platformCredentials = + credentialManagementService.parsePcsFromIdentityClaim(identityClaim, endorsementCredential); + + // 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(), + identityClaim.getPaccorOutput()); + + // Store the platform certificates' components + credentialManagementService.saveOrUpdatePlatformCertificateComponents(platformCredentials); + + // Perform supply chain validation + SupplyChainValidationSummary summary = supplyChainValidationService.validateSupplyChain( + endorsementCredential, platformCredentials, device, componentInfoList); + device.setSummaryId(summary.getId().toString()); + + // Update the validation result in the device and update the updated device in the database + AppraisalStatus.Status validationResult = summary.getOverallValidationResult(); + device.setSupplyChainValidationStatus(validationResult); + deviceInfoProcessorService.saveOrUpdateDevice(device); + + return validationResult; + } +} 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..ba38c64e7 --- /dev/null +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/Tpm2ProvisionerStateService.java @@ -0,0 +1,72 @@ +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.beans.factory.annotation.Autowired; +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 + */ + @Autowired + 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/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..2f7a6b6d1 --- /dev/null +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/provision/service/package-info.java @@ -0,0 +1,4 @@ +/** + * Contains all the service classes used in the provisioning process. + */ +package hirs.attestationca.persist.provision.service; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/CertificatePageService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/CertificatePageService.java index 4840d5627..613d12632 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/CertificatePageService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/CertificatePageService.java @@ -3,17 +3,17 @@ import hirs.attestationca.persist.entity.manager.CertificateRepository; import hirs.attestationca.persist.entity.manager.ComponentResultRepository; import hirs.attestationca.persist.entity.userdefined.Certificate; +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; +import hirs.attestationca.persist.entity.userdefined.DownloadFile; import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential; import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult; 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.service.util.CertificateType; -import hirs.attestationca.persist.service.util.DataTablesColumn; +import hirs.attestationca.persist.enums.CertificateType; import hirs.attestationca.persist.service.util.PageServiceUtils; import hirs.attestationca.persist.service.util.PredicateFactory; import hirs.attestationca.persist.util.CredentialHelper; -import hirs.attestationca.persist.util.DownloadFile; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityNotFoundException; import jakarta.persistence.TypedQuery; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/DevicePageService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/DevicePageService.java index 959454da9..36c50249e 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/DevicePageService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/DevicePageService.java @@ -1,15 +1,15 @@ package hirs.attestationca.persist.service; -import hirs.attestationca.persist.FilteredRecordsList; import hirs.attestationca.persist.entity.manager.DeviceRepository; -import hirs.attestationca.persist.entity.manager.EndorsementCredentialRepository; +import hirs.attestationca.persist.entity.manager.EndorsementCertificateRepository; import hirs.attestationca.persist.entity.manager.IssuedCertificateRepository; import hirs.attestationca.persist.entity.manager.PlatformCertificateRepository; +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; import hirs.attestationca.persist.entity.userdefined.Device; +import hirs.attestationca.persist.entity.userdefined.FilteredRecordsList; 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.service.util.DataTablesColumn; import hirs.attestationca.persist.service.util.PredicateFactory; import jakarta.persistence.EntityManager; import jakarta.persistence.TypedQuery; @@ -42,28 +42,28 @@ public class DevicePageService { private final DeviceRepository deviceRepository; private final PlatformCertificateRepository platformCertificateRepository; - private final EndorsementCredentialRepository endorsementCredentialRepository; + private final EndorsementCertificateRepository endorsementCertificateRepository; private final IssuedCertificateRepository issuedCertificateRepository; private final EntityManager entityManager; /** * Constructor for Device Page Service. * - * @param deviceRepository device repository - * @param platformCertificateRepository platform certificate repository - * @param endorsementCredentialRepository endorsement credential repository - * @param issuedCertificateRepository issued certificate repository - * @param entityManager entity manager + * @param deviceRepository device repository + * @param platformCertificateRepository platform certificate repository + * @param endorsementCertificateRepository endorsement certificate repository + * @param issuedCertificateRepository issued certificate repository + * @param entityManager entity manager */ @Autowired public DevicePageService(final DeviceRepository deviceRepository, final PlatformCertificateRepository platformCertificateRepository, - final EndorsementCredentialRepository endorsementCredentialRepository, + final EndorsementCertificateRepository endorsementCertificateRepository, final IssuedCertificateRepository issuedCertificateRepository, final EntityManager entityManager) { this.deviceRepository = deviceRepository; this.platformCertificateRepository = platformCertificateRepository; - this.endorsementCredentialRepository = endorsementCredentialRepository; + this.endorsementCertificateRepository = endorsementCertificateRepository; this.issuedCertificateRepository = issuedCertificateRepository; this.entityManager = entityManager; } @@ -244,10 +244,10 @@ public FilteredRecordsList> retrieveDevicesAndAssociated deviceCertMap.put("device", device); // create a new entry for platform certificates associated with the current device in the map - addPlatformCredentialEntryToDeviceMap(device, certificatePropertyMap); + addPlatformCertificateEntryToDeviceMap(device, certificatePropertyMap); // create a new entry for the endorsement certificate associated with the current device in the map - addEndorsementCredentialEntryToDeviceMap(device, certificatePropertyMap); + addEndorsementCertificateEntryToDeviceMap(device, certificatePropertyMap); // create a new entry for issued certificates associated with the current device in the map addIssuedCertificateEntryToDeviceMap(device, certificatePropertyMap); @@ -271,19 +271,19 @@ public FilteredRecordsList> retrieveDevicesAndAssociated * @param device device * @param certificatePropertyMap hash map of the certificate type and list of associated certificate ids */ - private void addPlatformCredentialEntryToDeviceMap(final Device device, - final HashMap> certificatePropertyMap) { + private void addPlatformCertificateEntryToDeviceMap(final Device device, + final HashMap> certificatePropertyMap) { // find all platform certificates associated with this device id - final List platformCredentialList = + final List platformCertificateList = platformCertificateRepository.findByDeviceId(device.getId()); - final String platformCredentialIdsKey = PlatformCredential.class.getSimpleName() + "Ids"; + final String platformCertificateIdsKey = PlatformCredential.class.getSimpleName() + "Ids"; - for (PlatformCredential pc : platformCredentialList) { + for (PlatformCredential pc : platformCertificateList) { // verify that the platform certificate is associated with this device if (device.getName().equals(pc.getDeviceName())) { - // if there is not a platform credential entry already in the map, create a new set - certificatePropertyMap.computeIfAbsent(platformCredentialIdsKey, _ -> new HashSet<>()) + // if there is not a platform certificate entry already in the map, create a new set + certificatePropertyMap.computeIfAbsent(platformCertificateIdsKey, _ -> new HashSet<>()) .add(pc.getId()); // Add the new ID to the set } } @@ -296,19 +296,19 @@ private void addPlatformCredentialEntryToDeviceMap(final Device device, * @param device device * @param certificatePropertyMap hash map of the certificate type and list of associated certificate ids */ - private void addEndorsementCredentialEntryToDeviceMap(final Device device, - final HashMap> certificatePropertyMap) { + private void addEndorsementCertificateEntryToDeviceMap(final Device device, + final HashMap> certificatePropertyMap) { // find all endorsement certificates associated with this device id - final List endorsementCredentialList = - endorsementCredentialRepository.findByDeviceId(device.getId()); + final List endorsementCertificateList = + endorsementCertificateRepository.findByDeviceId(device.getId()); - final String endorsementCredentialIdsKey = EndorsementCredential.class.getSimpleName() + "Ids"; + final String endorsementCertificateIdsKey = EndorsementCredential.class.getSimpleName() + "Ids"; - for (EndorsementCredential ec : endorsementCredentialList) { + for (EndorsementCredential ec : endorsementCertificateList) { // verify that the endorsement certificate is associated with this device if (device.getName().equals(ec.getDeviceName())) { // if there is not an endorsement certificate entry already in the map, create a new set - certificatePropertyMap.computeIfAbsent(endorsementCredentialIdsKey, _ -> new HashSet<>()) + certificatePropertyMap.computeIfAbsent(endorsementCertificateIdsKey, _ -> new HashSet<>()) .add(ec.getId()); // Add the new ID to the set } } @@ -330,9 +330,9 @@ private void addIssuedCertificateEntryToDeviceMap(final Device device, final String issuedCertificatesIdsKey = IssuedAttestationCertificate.class.getSimpleName() + "Ids"; for (IssuedAttestationCertificate ic : issuedCertificateList) { - // verify that the issued attestation certificate is associated with this device + // verify that the issued certificate is associated with this device if (device.getName().equals(ic.getDeviceName())) { - // if there is not an issued attestation certificate entry already in the map, create a new set + // if there is not an issued certificate entry already in the map, create a new set certificatePropertyMap.computeIfAbsent(issuedCertificatesIdsKey, _ -> new HashSet<>()) .add(ic.getId()); // Add the new ID to the set } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/EndorsementCredentialPageService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/EndorsementCertificatePageService.java similarity index 57% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/EndorsementCredentialPageService.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/EndorsementCertificatePageService.java index 5c7eb4d1b..b89e37562 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/EndorsementCredentialPageService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/EndorsementCertificatePageService.java @@ -1,6 +1,6 @@ package hirs.attestationca.persist.service; -import hirs.attestationca.persist.entity.manager.EndorsementCredentialRepository; +import hirs.attestationca.persist.entity.manager.EndorsementCertificateRepository; import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; import lombok.extern.log4j.Log4j2; import org.bouncycastle.util.encoders.DecoderException; @@ -14,90 +14,88 @@ import java.util.List; /** - * Service class responsible for encapsulating all business logic related to the Endorsement Credentials Page. + * Service class responsible for encapsulating all business logic related to the Endorsement Certificates Page. */ @Service @Log4j2 -public class EndorsementCredentialPageService { - private final EndorsementCredentialRepository endorsementCredentialRepository; +public class EndorsementCertificatePageService { + private final EndorsementCertificateRepository endorsementCertificateRepository; /** - * Constructor for the Endorsement Credential Page Service. + * Constructor for the Endorsement Certificate Page Service. * - * @param endorsementCredentialRepository endorsement credential repository + * @param endorsementCertificateRepository endorsement certificate repository */ @Autowired - public EndorsementCredentialPageService(final EndorsementCredentialRepository endorsementCredentialRepository) { - this.endorsementCredentialRepository = endorsementCredentialRepository; + public EndorsementCertificatePageService(final EndorsementCertificateRepository endorsementCertificateRepository) { + this.endorsementCertificateRepository = endorsementCertificateRepository; } /** - * Retrieves a page of endorsement credentials using the provided archive flag and pageable value. + * Retrieves a page of {@link EndorsementCredential} objects using the provided archive flag and pageable value. * * @param archiveFlag archive flag * @param pageable pageable - * @return page of endorsement credentials + * @return page of {@link EndorsementCredential} objects */ - public Page findEndorsementCredentialsByArchiveFlag(final boolean archiveFlag, - final Pageable pageable) { - return endorsementCredentialRepository.findByArchiveFlag(archiveFlag, pageable); + public Page findEndorsementCertificatesByArchiveFlag(final boolean archiveFlag, + final Pageable pageable) { + return endorsementCertificateRepository.findByArchiveFlag(archiveFlag, pageable); } /** - * Retrieves the total number of records in the endorsement credential repository. + * Retrieves the total number of records stored in the {@link EndorsementCertificateRepository}. * - * @return total number of records in the endorsement credential repository. + * @return total number of records stored in the {@link EndorsementCertificateRepository}. */ - public long findEndorsementCredentialRepositoryCount() { - return endorsementCredentialRepository.countByArchiveFlag(false); + public long findEndorsementCertificateRepositoryCount() { + return endorsementCertificateRepository.countByArchiveFlag(false); } /** - * Attempts to parse the provided file in order to create an Endorsement Credential. + * Attempts to parse the provided file in order to create an {@link EndorsementCredential} object. * * @param file file * @param errorMessages contains any error messages that will be displayed on the page - * @return endorsement credential + * @return an {@link EndorsementCredential} object */ - public EndorsementCredential parseEndorsementCredential(final MultipartFile file, - final List errorMessages) { - log.info("Received endorsement credential file of size: {}", file.getSize()); + public EndorsementCredential parseEndorsementCertificate(final MultipartFile file, + final List errorMessages) { + log.info("Received endorsement certificate file of size: {}", file.getSize()); byte[] fileBytes; final String fileName = file.getOriginalFilename(); - try { fileBytes = file.getBytes(); } catch (IOException ioEx) { final String failMessage = - String.format("Failed to read uploaded endorsement credential file (%s): ", fileName); + String.format("Failed to read uploaded endorsement certificate file (%s): ", fileName); log.error(failMessage, ioEx); errorMessages.add(failMessage + ioEx.getMessage()); return null; } - try { return new EndorsementCredential(fileBytes); } catch (IOException ioEx) { final String failMessage = - String.format("Failed to parse uploaded endorsement credential file (%s): ", fileName); + String.format("Failed to parse uploaded endorsement certificate file (%s): ", fileName); log.error(failMessage, ioEx); errorMessages.add(failMessage + ioEx.getMessage()); return null; } catch (DecoderException dEx) { final String failMessage = - String.format("Failed to parse uploaded endorsement credential pem file (%s): ", fileName); + String.format("Failed to parse uploaded endorsement certificate PEM file (%s): ", fileName); log.error(failMessage, dEx); errorMessages.add(failMessage + dEx.getMessage()); return null; } catch (IllegalArgumentException iaEx) { - final String failMessage = String.format("Endorsement credential format not recognized(%s): ", fileName); + final String failMessage = String.format("Endorsement certificate format not recognized(%s): ", fileName); log.error(failMessage, iaEx); errorMessages.add(failMessage + iaEx.getMessage()); return null; } catch (IllegalStateException isEx) { final String failMessage = - String.format("Unexpected object while parsing endorsement credential %s ", fileName); + String.format("Unexpected object while parsing endorsement certificate %s ", fileName); log.error(failMessage, isEx); errorMessages.add(failMessage + isEx.getMessage()); return null; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/IssuedAttestationCertificatePageService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/IssuedCertificatePageService.java similarity index 71% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/IssuedAttestationCertificatePageService.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/IssuedCertificatePageService.java index abfec91bc..ded427f77 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/IssuedAttestationCertificatePageService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/IssuedCertificatePageService.java @@ -9,12 +9,11 @@ import org.springframework.stereotype.Service; /** - * Service class responsible for encapsulating all business logic related to the Issued Attestation - * Certificate Page. + * Service class responsible for encapsulating all business logic related to the Issued Certificates Page. */ @Service @Log4j2 -public class IssuedAttestationCertificatePageService { +public class IssuedCertificatePageService { private final IssuedCertificateRepository issuedCertificateRepository; /** @@ -23,16 +22,17 @@ public class IssuedAttestationCertificatePageService { * @param issuedCertificateRepository issued certificate repository */ @Autowired - public IssuedAttestationCertificatePageService(final IssuedCertificateRepository issuedCertificateRepository) { + public IssuedCertificatePageService(final IssuedCertificateRepository issuedCertificateRepository) { this.issuedCertificateRepository = issuedCertificateRepository; } /** - * Retrieves a page of issued attestation certificates using the provided archive flag and pageable value. + * Retrieves a page of {@link IssuedAttestationCertificate} objects using the provided archive flag and pageable + * value. * * @param archiveFlag archive flag * @param pageable pageable - * @return page of issued attestation certificates + * @return page of {@link IssuedAttestationCertificate} objects */ public Page findIssuedCertificatesByArchiveFlag(final boolean archiveFlag, final Pageable pageable) { @@ -40,9 +40,9 @@ public Page findIssuedCertificatesByArchiveFlag(fi } /** - * Retrieves the total number of records in the issued certificate repository. + * Retrieves the total number of records stored in the {@link IssuedCertificateRepository}. * - * @return total number of records in the issued certificate repository. + * @return total number of records stored in the {@link IssuedCertificateRepository}. */ public long findIssuedCertificateRepoCount() { return issuedCertificateRepository.countByArchiveFlag(false); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/PlatformCredentialPageService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/PlatformCertificatePageService.java similarity index 59% rename from HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/PlatformCredentialPageService.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/PlatformCertificatePageService.java index 1174ab67f..273575f7f 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/PlatformCredentialPageService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/PlatformCertificatePageService.java @@ -1,6 +1,6 @@ package hirs.attestationca.persist.service; -import hirs.attestationca.persist.entity.manager.EndorsementCredentialRepository; +import hirs.attestationca.persist.entity.manager.EndorsementCertificateRepository; import hirs.attestationca.persist.entity.manager.PlatformCertificateRepository; import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; @@ -17,104 +17,102 @@ import java.util.List; /** - * Service class responsible for encapsulating all business logic related to the Platform Credential + * Service class responsible for encapsulating all business logic related to the Platform Certificate * Page. */ @Service @Log4j2 -public class PlatformCredentialPageService { +public class PlatformCertificatePageService { private final PlatformCertificateRepository platformCertificateRepository; - private final EndorsementCredentialRepository endorsementCredentialRepository; + private final EndorsementCertificateRepository endorsementCertificateRepository; /** - * Constructor for the Platform Credential Page service. + * Constructor for the Platform Certificate Page service. * - * @param platformCertificateRepository platform certificate repository - * @param endorsementCredentialRepository endorsement credential repository + * @param platformCertificateRepository platform certificate repository + * @param endorsementCertificateRepository endorsement certificate repository */ @Autowired - public PlatformCredentialPageService(final PlatformCertificateRepository platformCertificateRepository, - final EndorsementCredentialRepository endorsementCredentialRepository) { + public PlatformCertificatePageService(final PlatformCertificateRepository platformCertificateRepository, + final EndorsementCertificateRepository endorsementCertificateRepository) { this.platformCertificateRepository = platformCertificateRepository; - this.endorsementCredentialRepository = endorsementCredentialRepository; + this.endorsementCertificateRepository = endorsementCertificateRepository; } /** - * Retrieves a page of platform credentials using the provided archive flag and pageable value. + * Retrieves a page of {@link PlatformCredential} objects using the provided archive flag and pageable value. * * @param archiveFlag archive flag * @param pageable pageable - * @return page of platform credentials + * @return a page of {@link PlatformCredential} objects */ - public Page findPlatformCredentialsByArchiveFlag(final boolean archiveFlag, - final Pageable pageable) { + public Page findPlatformCertificatesByArchiveFlag(final boolean archiveFlag, + final Pageable pageable) { return platformCertificateRepository.findByArchiveFlag(archiveFlag, pageable); } /** - * Retrieves an endorsement credential using the provided holder serial number. + * Retrieves an {@link EndorsementCredential} object using the provided holder serial number. * * @param holderSerialNumber big integer representation of the holder serial number - * @return endorsement credential + * @return an {@link EndorsementCredential} object */ - public EndorsementCredential findECBySerialNumber(final BigInteger holderSerialNumber) { - return endorsementCredentialRepository.findBySerialNumber(holderSerialNumber); + public EndorsementCredential findEndorsementCertificateBySerialNumber(final BigInteger holderSerialNumber) { + return endorsementCertificateRepository.findBySerialNumber(holderSerialNumber); } /** - * Retrieves the total number of records in the platform credential repository. + * Retrieves the total number of records stored in the {@link PlatformCertificateRepository}. * - * @return total number of records in the platform credential repository. + * @return total number of records stored in the {@link PlatformCertificateRepository}. */ - public long findPlatformCredentialRepositoryCount() { + public long findPlatformCertificateRepositoryCount() { return platformCertificateRepository.countByArchiveFlag(false); } /** - * Attempts to parse the provided file in order to create a Platform Credential. + * Attempts to parse the provided file in order to create a {@link PlatformCredential} object. * * @param file file * @param errorMessages contains any error messages that will be displayed on the page - * @return platform credential + * @return a {@link PlatformCredential} object */ - public PlatformCredential parsePlatformCredential(final MultipartFile file, final List errorMessages) { - log.info("Received platform credential file of size: {}", file.getSize()); + public PlatformCredential parsePlatformCertificate(final MultipartFile file, final List errorMessages) { + log.info("Received platform certificate file of size: {}", file.getSize()); byte[] fileBytes; final String fileName = file.getOriginalFilename(); - try { fileBytes = file.getBytes(); } catch (IOException ioEx) { final String failMessage = - String.format("Failed to read uploaded platform credential file (%s): ", fileName); + String.format("Failed to read uploaded platform certificate file (%s): ", fileName); log.error(failMessage, ioEx); errorMessages.add(failMessage + ioEx.getMessage()); return null; } - try { return new PlatformCredential(fileBytes); } catch (IOException ioEx) { final String failMessage = - String.format("Failed to parse uploaded platform credential file (%s): ", fileName); + String.format("Failed to parse uploaded platform certificate file (%s): ", fileName); log.error(failMessage, ioEx); errorMessages.add(failMessage + ioEx.getMessage()); return null; } catch (DecoderException dEx) { final String failMessage = - String.format("Failed to parse uploaded platform credential pem file (%s): ", fileName); + String.format("Failed to parse uploaded platform certificate PEM file (%s): ", fileName); log.error(failMessage, dEx); errorMessages.add(failMessage + dEx.getMessage()); return null; } catch (IllegalArgumentException iaEx) { - final String failMessage = String.format("Platform credential format not recognized(%s): ", fileName); + final String failMessage = String.format("Platform certificate format not recognized(%s): ", fileName); log.error(failMessage, iaEx); errorMessages.add(failMessage + iaEx.getMessage()); return null; } catch (IllegalStateException isEx) { final String failMessage = - String.format("Unexpected object while parsing platform credential %s ", fileName); + String.format("Unexpected object while parsing platform certificate %s ", fileName); log.error(failMessage, isEx); errorMessages.add(failMessage + isEx.getMessage()); return null; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ReferenceDigestValuePageService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ReferenceDigestValuePageService.java index 447295941..954f312f4 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ReferenceDigestValuePageService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ReferenceDigestValuePageService.java @@ -2,9 +2,9 @@ import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository; import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository; +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; import hirs.attestationca.persist.entity.userdefined.ReferenceManifest; import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue; -import hirs.attestationca.persist.service.util.DataTablesColumn; import hirs.attestationca.persist.service.util.PageServiceUtils; import hirs.attestationca.persist.service.util.PredicateFactory; import jakarta.persistence.EntityManager; 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..f34a386f0 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 @@ -1,6 +1,5 @@ package hirs.attestationca.persist.service; -import hirs.attestationca.persist.DBServiceException; import hirs.attestationca.persist.entity.manager.CACredentialRepository; import hirs.attestationca.persist.entity.manager.CertificateRepository; import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository; @@ -12,8 +11,10 @@ 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.DBServiceException; +import hirs.attestationca.persist.exceptions.SupplyChainValidatorException; 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/service/ReferenceManifestPageService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ReferenceManifestPageService.java index a4b21d7ac..d5ae038bd 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ReferenceManifestPageService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ReferenceManifestPageService.java @@ -2,13 +2,13 @@ import hirs.attestationca.persist.entity.manager.ReferenceDigestValueRepository; import hirs.attestationca.persist.entity.manager.ReferenceManifestRepository; +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; +import hirs.attestationca.persist.entity.userdefined.DownloadFile; import hirs.attestationca.persist.entity.userdefined.ReferenceManifest; import hirs.attestationca.persist.entity.userdefined.rim.BaseReferenceManifest; import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue; import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest; -import hirs.attestationca.persist.service.util.DataTablesColumn; import hirs.attestationca.persist.service.util.PredicateFactory; -import hirs.attestationca.persist.util.DownloadFile; import hirs.utils.tpm.eventlog.TCGEventLog; import hirs.utils.tpm.eventlog.TpmPcrEvent; import jakarta.persistence.EntityManager; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationSummaryPageService.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationSummaryPageService.java index 2b42aadbe..3a5dcc2c6 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationSummaryPageService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/ValidationSummaryPageService.java @@ -5,12 +5,12 @@ import hirs.attestationca.persist.entity.manager.DeviceRepository; import hirs.attestationca.persist.entity.manager.PlatformCertificateRepository; import hirs.attestationca.persist.entity.manager.SupplyChainValidationSummaryRepository; +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; import hirs.attestationca.persist.entity.userdefined.Device; import hirs.attestationca.persist.entity.userdefined.SupplyChainValidationSummary; 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.service.util.DataTablesColumn; import hirs.attestationca.persist.service.util.PageServiceUtils; import hirs.attestationca.persist.service.util.PredicateFactory; import jakarta.persistence.EntityManager; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java index 7909ee683..bb2029acd 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/CredentialValidator.java @@ -9,6 +9,7 @@ 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.exceptions.SupplyChainValidatorException; import lombok.extern.log4j.Log4j2; import org.bouncycastle.cert.X509AttributeCertificateHolder; 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..8024fa568 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,7 @@ 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.attestationca.persist.exceptions.SupplyChainValidatorException; 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/validation/SupplyChainCredentialValidator.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java index 55328796c..f33112a31 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidator.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import hirs.attestationca.persist.entity.userdefined.info.ComponentInfo; +import hirs.attestationca.persist.exceptions.SupplyChainValidatorException; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.StringUtils; import org.bouncycastle.asn1.x500.X500Name; diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/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/service/SupplyChainValidationService.java rename to HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainValidationService.java index c6ef4c6d6..d1bc22c0d 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/service/SupplyChainValidationService.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/validation/SupplyChainValidationService.java @@ -1,6 +1,5 @@ -package hirs.attestationca.persist.service; +package hirs.attestationca.persist.validation; -import hirs.attestationca.persist.DBManagerException; import hirs.attestationca.persist.entity.ArchivableEntity; import hirs.attestationca.persist.entity.manager.CACredentialRepository; import hirs.attestationca.persist.entity.manager.CertificateRepository; @@ -25,8 +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.validation.PcrValidator; -import hirs.attestationca.persist.validation.SupplyChainCredentialValidator; +import hirs.attestationca.persist.exceptions.DBManagerException; import lombok.extern.log4j.Log4j2; import org.apache.logging.log4j.Level; import org.springframework.beans.factory.annotation.Autowired; @@ -56,7 +54,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; @@ -90,7 +87,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/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; 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 06b242325..000000000 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/AttestationCertificateAuthorityTest.java +++ /dev/null @@ -1,327 +0,0 @@ -package hirs.attestationca.persist; - -import com.google.protobuf.ByteString; -import hirs.attestationca.persist.provision.AbstractProcessor; -import hirs.attestationca.persist.provision.helper.ProvisionUtils; -import hirs.utils.HexUtils; -import org.apache.commons.codec.binary.Hex; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -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 java.io.IOException; -import java.math.BigInteger; -import java.net.URISyntaxException; -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.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.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.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 AttestationCertificateAuthority}. - */ -@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"; - - // object in test - private AttestationCertificateAuthority aca; - // test key pair - private KeyPair keyPair; - - /** - * 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 AttestationCertificateAuthority(null, keyPair.getPrivate(), - null, null, null, null, null, null, 1, - null, null, null, null) { - }; - - Security.addProvider(new BouncyCastleProvider()); - } - - /** - * Tests {@link AttestationCertificateAuthority#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 AttestationCertificateAuthority#getPublicKey()}. - */ - @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.getPublicKey()); - - // verify mock interactions - verify(acaCertificate).getPublicKey(); - verify(publicKey).getEncoded(); - - // verify no other interactions with mocks - verifyNoMoreInteractions(acaCertificate, publicKey); - } - - /** - * Tests {@link ProvisionUtils#assemblePublicKey(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.assemblePublicKey(modulusString); - - // 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(getClass().getResource( - EK_PUBLIC_PATH).toURI()); - - byte[] ekFile = Files.readAllBytes(ekPath); - - RSAPublicKey ek = ProvisionUtils.parsePublicKey(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(getClass().getResource( - AK_PUBLIC_PATH).toURI()); - - byte[] akFile = Files.readAllBytes(akPath); - - RSAPublicKey ak = ProvisionUtils.parsePublicKey(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 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.parsePublicKey(ekPubFile); - RSAPublicKey akPub = ProvisionUtils.parsePublicKey(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); - } - - /** - * 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); - } - } -} diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/AbstractUserdefinedEntityTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/AbstractUserdefinedEntityTest.java index bd4786fc5..240b7fbf8 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/AbstractUserdefinedEntityTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/AbstractUserdefinedEntityTest.java @@ -2,7 +2,6 @@ import hirs.attestationca.persist.entity.ArchivableEntity; import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential; -import hirs.attestationca.persist.entity.userdefined.certificate.ConformanceCredential; import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate; import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; @@ -12,10 +11,8 @@ 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.report.DeviceInfoReportTest; import hirs.attestationca.persist.enums.AppraisalStatus; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import lombok.extern.log4j.Log4j2; import java.io.FileNotFoundException; import java.io.IOException; @@ -34,6 +31,7 @@ /** * Class with definitions and functions common to multiple Userdefined Entity object tests. */ +@Log4j2 public class AbstractUserdefinedEntityTest { /** @@ -92,7 +90,6 @@ public class AbstractUserdefinedEntityTest { * Location of a test identity certificate. */ private static final String TEST_IDENTITY_CERT = "/tpm/sample_identity_cert.cer"; - private static final Logger LOGGER = LogManager.getLogger(DeviceInfoReportTest.class); /** * This protected constructor was created to silence one of checkstyle errors. @@ -137,15 +134,12 @@ public static Certificate getTestCertificate( try { certPath = Paths.get(Objects.requireNonNull( AbstractUserdefinedEntityTest.class.getResource(filename)).toURI()); -// certPath = Paths.get(Objects.requireNonNull( -// CertificateTest.class.getResource(filename)).toURI()); } catch (URISyntaxException e) { throw new IOException("Could not resolve path URI", e); } return switch (certificateClass.getSimpleName()) { case "CertificateAuthorityCredential" -> new CertificateAuthorityCredential(certPath); - case "ConformanceCredential" -> new ConformanceCredential(certPath); case "EndorsementCredential" -> new EndorsementCredential(certPath); case "PlatformCredential" -> new PlatformCredential(certPath); case "IssuedAttestationCertificate" -> new IssuedAttestationCertificate(certPath, @@ -190,14 +184,14 @@ public static DeviceInfoReport getTestDeviceInfoReport() { public static NetworkInfo createTestNetworkInfo() { try { final String hostname = "test.hostname"; - final byte[] byteAddress = new byte[] {127, 0, 0, 1}; + final byte[] byteAddress = new byte[]{127, 0, 0, 1}; final InetAddress ipAddress = InetAddress.getByAddress(byteAddress); - final byte[] macAddress = new byte[] {11, 22, 33, 44, 55, 66}; + final byte[] macAddress = new byte[]{11, 22, 33, 44, 55, 66}; return new NetworkInfo(hostname, ipAddress, macAddress); } catch (UnknownHostException e) { - LOGGER.error("error occurred while creating InetAddress"); + log.error("error occurred while creating InetAddress"); return null; } } @@ -238,7 +232,7 @@ public static HardwareInfo createTestHardwareInfo() { * * @return TPM information for a fake device */ - public static final TPMInfo createTPMInfo() { + public static TPMInfo createTPMInfo() { final short num1 = 1; final short num2 = 2; final short num3 = 3; @@ -273,7 +267,7 @@ public static X509Certificate getTestIdentityCertificate() { try { istream.close(); } catch (IOException e) { - LOGGER.error("test certificate file could not be closed"); + log.error("test certificate file could not be closed"); } } } diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/CertificateTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/CertificateTest.java index 12a83d92c..d416e2b56 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/CertificateTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/CertificateTest.java @@ -1,7 +1,6 @@ package hirs.attestationca.persist.entity.userdefined; import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential; -import hirs.attestationca.persist.entity.userdefined.certificate.ConformanceCredential; import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; import org.bouncycastle.cert.X509AttributeCertificateHolder; @@ -164,7 +163,7 @@ public void testConstructCertFromNullByteArray() public void testConstructCertFromEmptyByteArray() throws IllegalArgumentException { assertThrows(IllegalArgumentException.class, () -> - new CertificateAuthorityCredential(new byte[] {})); + new CertificateAuthorityCredential(new byte[]{})); } /** @@ -459,11 +458,6 @@ public void testEquals() throws IOException, URISyntaxException { getTestCertificate(CertificateAuthorityCredential.class, FAKE_INTEL_INT_CA_FILE) ); - assertNotEquals( - getTestCertificate(CertificateAuthorityCredential.class, FAKE_ROOT_CA_FILE), - getTestCertificate(ConformanceCredential.class, FAKE_ROOT_CA_FILE) - ); - assertNotEquals( null, getTestCertificate(CertificateAuthorityCredential.class, FAKE_ROOT_CA_FILE) diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/info/PortalInfoTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/info/PortalInfoTest.java deleted file mode 100644 index ba3fa97a2..000000000 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/entity/userdefined/info/PortalInfoTest.java +++ /dev/null @@ -1,130 +0,0 @@ -package hirs.attestationca.persist.entity.userdefined.info; - -import hirs.utils.enums.PortalScheme; -import org.junit.jupiter.api.Test; - -import java.net.InetAddress; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.fail; - -/** - * Provides tests for PortalInfo. - */ -public class PortalInfoTest { - - /** - * Test the default state of the object, once constructed. - */ - @Test - public void testPortalInfoDefaults() { - PortalInfo info = new PortalInfo(); - assertNull(info.getName()); - assertNull(info.getIpAddress()); - assertEquals(info.getPort(), 0); - } - - /** - * Test that the scheme can be set and retrieved. - */ - @Test - public void testScheme() { - final PortalScheme scheme = PortalScheme.HTTPS; - - PortalInfo info = new PortalInfo(); - info.setSchemeName(scheme); - - assertEquals(info.getName(), scheme.name()); - } - - /** - * Test that setSchemeName does not accept a null input. - */ - @Test - public void testSchemeNull() { - final PortalScheme scheme = null; - - PortalInfo info = new PortalInfo(); - - try { - info.setSchemeName(scheme); - fail("The null scheme should have caused an error."); - } catch (Exception e) { - assertNull(info.getName()); - } - } - - /** - * Test that the ip address can be set and retrieved via an InetAddress. - * - * @throws Exception If there is a problem with InetAddress. - */ - @Test - public void testIpAddressInetAddress() throws Exception { - final InetAddress address = InetAddress.getLocalHost(); - - PortalInfo info = new PortalInfo(); - info.setIpAddress(address); - - assertEquals(info.getIpAddress(), address); - } - - /** - * Test that the ip address can be set and retrieved via a String. - * - * @throws Exception If there is a problem with InetAddress. - */ - @Test - public void testIpAddressString() throws Exception { - final String address = "localhost"; - - PortalInfo info = new PortalInfo(); - info.setIpAddress(address); - - assertEquals(info.getIpAddress().getHostName(), address); - } - - /** - * Test that the scheme can be set and retrieved. - */ - @Test - public void testPort() { - final int port = 127; - - PortalInfo info = new PortalInfo(); - info.setPort(port); - - assertEquals(info.getPort(), port); - } - - /** - * Test that the context name can be set and retrieved. - */ - @Test - public void testContext() { - final String context = "Portal"; - - PortalInfo info = new PortalInfo(); - info.setContextName(context); - - assertEquals(info.getContext(), context); - } - - /** - * Test that setContextName does not accept a null input. - */ - @Test - public void testContextNull() { - final String context = null; - - PortalInfo info = new PortalInfo(); - - try { - info.setContextName(context); - fail("The null context should have caused an error."); - } catch (Exception e) { - assertNull(info.getContext()); - } - } -} diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceTest.java new file mode 100644 index 000000000..ddbbe4f90 --- /dev/null +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/service/AttestationCertificateAuthorityServiceTest.java @@ -0,0 +1,349 @@ +package hirs.attestationca.persist.provision.service; + +import hirs.attestationca.persist.exceptions.CertificateProcessingException; +import hirs.attestationca.persist.provision.helper.ProvisionUtils; +import hirs.utils.HexUtils; +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.IOException; +import java.math.BigInteger; +import java.net.URISyntaxException; +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.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPublicKey; +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.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Tests the {@link AttestationCertificateAuthorityServiceImpl} service class. + */ +public class AttestationCertificateAuthorityServiceTest { + private static final String EK_PUBLIC_KEY_PATH = "/tpm2/ek.pub"; + + private static final String AK_PUBLIC_KEY_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; + + @Mock + private CertificateRequestProcessorService certificateRequestProcessorService; + + @Mock + private IdentityClaimProcessorService identityClaimProcessorService; + + /** + * 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 + mocks = MockitoAnnotations.openMocks(this); + + final int keySize = 2048; + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(keySize); + 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) { + mocks.close(); + } + } + + /** + * Tests {@link AttestationCertificateAuthorityServiceImpl#processIdentityClaimTpm2(byte[])} + * where the byte array is null or empty. Expects an {@link IllegalArgumentException} to be thrown. + */ + @Test + public void testProcessIdentityClaimTpm2NullOrEmptyRequest() { + final String expectedExceptionMsg = "The IdentityClaim sent by the client cannot be null or empty."; + + // test 1: test null identity claim + when(identityClaimProcessorService.processIdentityClaimTpm2(null)).thenThrow( + new IllegalArgumentException(expectedExceptionMsg)); + + // Act & Assert: Verify that the exception is thrown + String actualExceptionMsg = assertThrows(IllegalArgumentException.class, + () -> attestationCertificateAuthorityService.processIdentityClaimTpm2(null)).getMessage(); + + assertEquals(expectedExceptionMsg, actualExceptionMsg); + + // test 2: test empty identity claim + + // initialize an empty byte array + final byte[] emptyArr = {}; + + when(identityClaimProcessorService.processIdentityClaimTpm2(emptyArr)).thenThrow( + new IllegalArgumentException(expectedExceptionMsg)); + + // Act & Assert: Verify that the exception is thrown + actualExceptionMsg = assertThrows(IllegalArgumentException.class, + () -> attestationCertificateAuthorityService.processIdentityClaimTpm2(emptyArr)).getMessage(); + + assertEquals(expectedExceptionMsg, actualExceptionMsg); + } + + /** + * Tests {@link AttestationCertificateAuthorityServiceImpl#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(identityClaimProcessorService.processIdentityClaimTpm2(identityClaim)).thenReturn( + expectedIdentityClaimResponse); + + final byte[] actualCertificateResponse = + identityClaimProcessorService.processIdentityClaimTpm2(identityClaim); + + // Assert that the byte arrays match + assertArrayEquals(expectedIdentityClaimResponse, actualCertificateResponse); + } + + /** + * Tests {@link AttestationCertificateAuthorityServiceImpl#processCertificateRequest(byte[])} + * where the byte array is null or empty. Expects an {@link IllegalArgumentException} to be thrown. + */ + @Test + public void testProcessCertificateRequestNullOrEmptyRequest() { + final String expectedExceptionMsg = "The CertificateRequest sent by the client cannot be null or empty."; + + // test 1: test null certificate request + when(certificateRequestProcessorService.processCertificateRequest(null)).thenThrow( + new IllegalArgumentException(expectedExceptionMsg)); + + // Act & Assert: Verify that the exception is thrown + String actualExceptionMsg = assertThrows(IllegalArgumentException.class, + () -> attestationCertificateAuthorityService.processCertificateRequest(null)).getMessage(); + + assertEquals(expectedExceptionMsg, actualExceptionMsg); + + // test 2: test empty certificate request + + // initialize an empty byte array + final byte[] emptyArr = {}; + + when(certificateRequestProcessorService.processCertificateRequest(emptyArr)).thenThrow( + new IllegalArgumentException(expectedExceptionMsg)); + + // Act & Assert: Verify that the exception is thrown + actualExceptionMsg = assertThrows(IllegalArgumentException.class, + () -> attestationCertificateAuthorityService.processCertificateRequest(emptyArr)).getMessage(); + + assertEquals(expectedExceptionMsg, actualExceptionMsg); + } + + /** + * Tests {@link AttestationCertificateAuthorityServiceImpl#processCertificateRequest(byte[])} + * where the byte array is invalid. Expects a {@link CertificateProcessingException} to be thrown. + */ + @Test + public void testProcessCertificateRequestProcessorDeserializationError() { + final String expectedExceptionMsg = "Could not deserialize Protobuf Certificate Request object"; + + final byte[] badCertificateRequest = {0, 0, 0, 0, 0, 1, 0, 0}; + + when(certificateRequestProcessorService.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 AttestationCertificateAuthorityServiceImpl#processCertificateRequest(byte[])}. + */ + @Test + public void testProcessCertificateRequest() { + final byte[] certificateRequest = {0, 1, 0, 1}; + + final byte[] expectedCertificateResponse = {1, 1, 1, 1}; + + when(certificateRequestProcessorService.processCertificateRequest(certificateRequest)).thenReturn( + expectedCertificateResponse); + + final byte[] actualCertificateResponse = + attestationCertificateAuthorityService.processCertificateRequest(certificateRequest); + + // Assert that the byte arrays match + assertArrayEquals(expectedCertificateResponse, actualCertificateResponse); + } + + /** + * Tests {@link AttestationCertificateAuthorityServiceImpl#getLeafACACertPublicKey()}. + */ + @Test + public void testGetPublicKey() { + // encoded byte array to be returned by public key + final byte[] expectedByteArray = 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(expectedByteArray); + + // grab the public key encoding + byte[] mockedByteArrayResult = mockPublicKey.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 mocked and actual byte arrays match + assertArrayEquals(expectedByteArray, actualByteArray); + } + + /** + * Tests {@link ProvisionUtils#assemblePublicKey(byte[])} (byte[])}. + */ + @Test + public void testAssembleRSAPublicKeyUsingByteArray() { + // obtain the expected modulus from the existing public key + final BigInteger modulus = ((RSAPublicKey) keyPair.getPublic()).getModulus(); + + // perform test + RSAPublicKey publicKey = (RSAPublicKey) ProvisionUtils.assemblePublicKey(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_KEY_PATH)).toURI()); + + byte[] ekFile = Files.readAllBytes(ekPath); + + RSAPublicKey ek = ProvisionUtils.parsePublicKey(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_KEY_PATH)).toURI()); + + byte[] akFile = Files.readAllBytes(akPath); + + RSAPublicKey ak = ProvisionUtils.parsePublicKey(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); + } +} 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/service/CredentialManagementServiceTest.java similarity index 56% 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/service/CredentialManagementServiceTest.java index dfed13110..f837d57c3 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelperTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/service/CredentialManagementServiceTest.java @@ -1,4 +1,4 @@ -package hirs.attestationca.persist.provision.helper; +package hirs.attestationca.persist.provision.service; import hirs.attestationca.persist.entity.manager.CertificateRepository; import hirs.attestationca.persist.entity.userdefined.Certificate; @@ -6,26 +6,29 @@ 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 {@link 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 +43,6 @@ public class CredentialManagementHelperTest { */ @BeforeEach public void setUp() { - //certificateRepository = mock(CertificateRepository.class); mocks = MockitoAnnotations.openMocks(this); } @@ -56,27 +58,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")); } @@ -85,9 +73,8 @@ public void processNullEndorsementCredential() { */ @Test public void processEmptyEndorsementCredential() { - assertThrows(IllegalArgumentException.class, () -> - CredentialManagementHelper.storeEndorsementCredential( - certificateRepository, new byte[0], "testName")); + assertThrows(IllegalArgumentException.class, () -> credentialManagementService.storeEndorsementCredential( + new byte[0], "testName")); } /** @@ -95,10 +82,9 @@ public void processEmptyEndorsementCredential() { */ @Test public void processInvalidEndorsementCredentialCase1() { - byte[] ekBytes = new byte[] {1}; - assertThrows(IllegalArgumentException.class, () -> - CredentialManagementHelper.storeEndorsementCredential( - certificateRepository, ekBytes, "testName")); + byte[] ekBytes = new byte[]{1}; + assertThrows(IllegalArgumentException.class, () -> credentialManagementService.storeEndorsementCredential( + ekBytes, "testName")); } /** @@ -106,9 +92,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 +105,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 +119,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_AttestationCA/src/test/java/hirs/attestationca/persist/provision/service/package-info.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/service/package-info.java new file mode 100644 index 000000000..98904bcb1 --- /dev/null +++ b/HIRS_AttestationCA/src/test/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/validation/SupplyChainCredentialValidatorTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java index a8d946990..86317b280 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/validation/SupplyChainCredentialValidatorTest.java @@ -22,6 +22,7 @@ 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.exceptions.SupplyChainValidatorException; import hirs.utils.enums.DeviceInfoEnums; import lombok.NonNull; import org.apache.commons.io.IOUtils; @@ -2159,10 +2160,10 @@ private KeyPair createKeyPair() { private DeviceInfoReport setupDeviceInfoReport() throws UnknownHostException { // setup network info - final byte[] byteAddress = new byte[] {127, 0, 0, 1}; + final byte[] byteAddress = new byte[]{127, 0, 0, 1}; InetAddress inetAddress = InetAddress.getByAddress(byteAddress); NetworkInfo networkInfo = - new NetworkInfo("the-device", inetAddress, new byte[] {1, 0, 1, 0, 1, 0}); + new NetworkInfo("the-device", inetAddress, new byte[]{1, 0, 1, 0, 1, 0}); // setup os info OSInfo osInfo = new OSInfo("Windows", "11.0", "Not Specified", @@ -2280,7 +2281,7 @@ private List retrieveListOfComponentInfos() { */ private InetAddress getTestIpAddress() { try { - final byte[] byteAddress = new byte[] {127, 0, 0, 1}; + final byte[] byteAddress = new byte[]{127, 0, 0, 1}; return InetAddress.getByAddress(byteAddress); } catch (UnknownHostException e) { return null; @@ -2493,7 +2494,7 @@ private ComponentResultRepository setupMockComponentResultRepositoryWithPlatform */ private DeviceInfoReport buildDeviceInfoReportUsingHardwareInfo(final HardwareInfo givenHardwareInfo) { final InetAddress ipAddress = getTestIpAddress(); - final byte[] macAddress = new byte[] {11, 22, 33, 44, 55, 66}; + final byte[] macAddress = new byte[]{11, 22, 33, 44, 55, 66}; OSInfo osInfo = new OSInfo(); NetworkInfo networkInfo = new NetworkInfo("test", ipAddress, macAddress); diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/PersistenceJPAConfig.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/configuration/PersistenceJPAConfig.java similarity index 93% rename from HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/PersistenceJPAConfig.java rename to HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/configuration/PersistenceJPAConfig.java index dacadd720..d06468120 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/PersistenceJPAConfig.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/configuration/PersistenceJPAConfig.java @@ -1,4 +1,4 @@ -package hirs.attestationca.portal; +package hirs.attestationca.portal.configuration; import jakarta.annotation.PostConstruct; import lombok.extern.log4j.Log4j2; @@ -13,7 +13,6 @@ import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySources; import org.springframework.core.env.Environment; -import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.jpa.JpaTransactionManager; @@ -22,7 +21,6 @@ import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; -import org.springframework.web.multipart.support.StandardServletMultipartResolver; import javax.sql.DataSource; import java.nio.file.Files; @@ -210,7 +208,7 @@ public X509Certificate[] acaTrustChainCertificates() { // intermediate certificate has been signed by the root certificate validateCertificateChain(leafThreeACACert, intermediateACACert, rootACACert); - X509Certificate[] certsChainArray = new X509Certificate[] {leafThreeACACert, + X509Certificate[] certsChainArray = new X509Certificate[]{leafThreeACACert, intermediateACACert, rootACACert}; log.info("The ACA certificate chain is valid and trusted"); @@ -268,16 +266,6 @@ public PlatformTransactionManager transactionManager() { return transactionManager; } - /** - * Persistence Exception Translation Post Processor bean. - * - * @return persistence exception translation post processor bean - */ - @Bean - public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { - return new PersistenceExceptionTranslationPostProcessor(); - } - /** * Helper method that validates the provided leaf certificate against the * established intermediate and root certificates. @@ -316,7 +304,7 @@ private void validateCertificateChain(final X509Certificate leafCert, certPathValidator.validate(certPath, pkixParams); } - final Properties additionalProperties() { + private Properties additionalProperties() { final Properties hibernateProperties = new Properties(); hibernateProperties.setProperty("hibernate.hbm2ddl.auto", environment.getProperty("hibernate.hbm2ddl.auto")); @@ -327,15 +315,4 @@ final Properties additionalProperties() { return hibernateProperties; } - - /** - * Creates a Spring Resolver for Multi-part form uploads. This is required - * for spring controllers to be able to process Spring MultiPartFiles - * - * @return bean to handle multipart form requests - */ - @Bean(name = "multipartResolver") - public StandardServletMultipartResolver multipartResolver() { - return new StandardServletMultipartResolver(); - } } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/configuration/package-info.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/configuration/package-info.java new file mode 100644 index 000000000..8505ad6d4 --- /dev/null +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/configuration/package-info.java @@ -0,0 +1,4 @@ +/** + * Contains all the configuration files needed to support the HIRS Attestation CA Portal functionality. + */ +package hirs.attestationca.portal.configuration; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/datatables/DataTableResponse.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/datatables/DataTableResponse.java index 4d2c906ed..d6ebcaa12 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/datatables/DataTableResponse.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/datatables/DataTableResponse.java @@ -1,6 +1,6 @@ package hirs.attestationca.portal.datatables; -import hirs.attestationca.persist.FilteredRecordsList; +import hirs.attestationca.persist.entity.userdefined.FilteredRecordsList; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/datatables/DataTableView.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/datatables/DataTableView.java deleted file mode 100644 index d21b52310..000000000 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/datatables/DataTableView.java +++ /dev/null @@ -1,46 +0,0 @@ -package hirs.attestationca.portal.datatables; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import jakarta.servlet.ServletOutputStream; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.springframework.http.MediaType; -import org.springframework.web.servlet.view.AbstractUrlBasedView; - -import java.util.Map; - -/** - * Serializes the DataTableResponse from the view as JSON and writes it to the HTTP response. - */ -public class DataTableView extends AbstractUrlBasedView { - - private static final Gson GSON = new GsonBuilder().create(); - private static final String MODEL_FIELD; - - static { - final String name = DataTableResponse.class.getSimpleName(); - MODEL_FIELD = name.substring(0, 1).toLowerCase() + name.substring(1); - } - - /** - * Serializes the DataTableResponse from the view as JSON and writes it to the HTTP response. - * - * @param model combined output Map (never {@code null}), with dynamic values taking precedence - * over static attributes - * @param request current HTTP request - * @param response current HTTP response - * @throws Exception if rendering failed - */ - @Override - protected void renderMergedOutputModel( - final Map model, - final HttpServletRequest request, - final HttpServletResponse response) throws Exception { - response.setContentType(MediaType.APPLICATION_JSON_VALUE); - DataTableResponse dataTable = (DataTableResponse) model.get(MODEL_FIELD); - ServletOutputStream out = response.getOutputStream(); - String json = GSON.toJson(dataTable); - out.print(json); - } -} diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/listener/AnnotationDrivenEndpointsListener.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/listener/AnnotationDrivenEndpointsListener.java deleted file mode 100644 index 57abcc06e..000000000 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/listener/AnnotationDrivenEndpointsListener.java +++ /dev/null @@ -1,31 +0,0 @@ -package hirs.attestationca.portal.listener; - -import lombok.extern.log4j.Log4j2; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.context.event.EventListener; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.mvc.method.RequestMappingInfo; -import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; - -import java.util.Map; - -@Log4j2 -@Configuration -public class AnnotationDrivenEndpointsListener { - - /** - * Annotation Driven Endpoints event listener. - * - * @param event context refreshed event. - */ - @EventListener - public void handleContextRefresh(final ContextRefreshedEvent event) { - ApplicationContext applicationContext = event.getApplicationContext(); - RequestMappingHandlerMapping requestMappingHandlerMapping = applicationContext - .getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class); - Map map = requestMappingHandlerMapping.getHandlerMethods(); - map.forEach((key, value) -> log.debug("{} {}", key, value)); - } -} diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/listener/package-info.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/listener/package-info.java deleted file mode 100644 index 9f6fb6a59..000000000 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/listener/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package hirs.attestationca.portal.listener; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificateDetailsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificateDetailsPageController.java index dba2eb952..eb6ebb202 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificateDetailsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/CertificateDetailsPageController.java @@ -4,7 +4,6 @@ import hirs.attestationca.persist.entity.manager.CertificateRepository; import hirs.attestationca.persist.entity.manager.ComponentResultRepository; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageMessages; import hirs.attestationca.portal.page.params.CertificateDetailsPageParams; import hirs.attestationca.portal.page.utils.CertificateStringMapBuilder; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java index 87f28b03a..01c99a5cb 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/DevicePageController.java @@ -1,14 +1,13 @@ package hirs.attestationca.portal.page.controllers; -import hirs.attestationca.persist.FilteredRecordsList; +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; import hirs.attestationca.persist.entity.userdefined.Device; +import hirs.attestationca.persist.entity.userdefined.FilteredRecordsList; import hirs.attestationca.persist.service.DevicePageService; -import hirs.attestationca.persist.service.util.DataTablesColumn; import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableResponse; import hirs.attestationca.portal.datatables.Order; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.params.NoPageParams; import hirs.attestationca.portal.page.utils.ControllerPagesUtils; import lombok.extern.log4j.Log4j2; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/EndorsementCredentialPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/EndorsementCertificatePageController.java similarity index 71% rename from HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/EndorsementCredentialPageController.java rename to HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/EndorsementCertificatePageController.java index 6b8cdcbb7..43b823a94 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/EndorsementCredentialPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/EndorsementCertificatePageController.java @@ -1,17 +1,17 @@ package hirs.attestationca.portal.page.controllers; -import hirs.attestationca.persist.FilteredRecordsList; + +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; +import hirs.attestationca.persist.entity.userdefined.DownloadFile; +import hirs.attestationca.persist.entity.userdefined.FilteredRecordsList; import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; +import hirs.attestationca.persist.enums.CertificateType; import hirs.attestationca.persist.service.CertificatePageService; -import hirs.attestationca.persist.service.EndorsementCredentialPageService; -import hirs.attestationca.persist.service.util.CertificateType; -import hirs.attestationca.persist.service.util.DataTablesColumn; -import hirs.attestationca.persist.util.DownloadFile; +import hirs.attestationca.persist.service.EndorsementCertificatePageService; import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableResponse; import hirs.attestationca.portal.datatables.Order; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageMessages; import hirs.attestationca.portal.page.params.NoPageParams; import hirs.attestationca.portal.page.utils.ControllerPagesUtils; @@ -45,37 +45,36 @@ import java.util.zip.ZipOutputStream; /** - * Controller for the Endorsement Key Credentials page. + * Controller for the Endorsement Key Certificates page. */ @Controller @RequestMapping("/HIRS_AttestationCAPortal/portal/certificate-request/endorsement-key-credentials") @Log4j2 -public class EndorsementCredentialPageController extends PageController { - private final EndorsementCredentialPageService endorsementCredentialPageService; +public class EndorsementCertificatePageController extends PageController { + private final EndorsementCertificatePageService endorsementCertificatePageService; private final CertificatePageService certificatePageService; /** - * Constructor for the Endorsement Credential Page Controller. + * Constructor for the Endorsement Certificate Page Controller. * - * @param endorsementCredentialPageService endorsement credential page service - * @param certificatePageService certificate page service + * @param endorsementCertificatePageService endorsement certificate page service + * @param certificatePageService certificate page service */ @Autowired - public EndorsementCredentialPageController( - final EndorsementCredentialPageService endorsementCredentialPageService, + public EndorsementCertificatePageController( + final EndorsementCertificatePageService endorsementCertificatePageService, final CertificatePageService certificatePageService) { super(Page.ENDORSEMENT_KEY_CREDENTIALS); - this.endorsementCredentialPageService = endorsementCredentialPageService; + this.endorsementCertificatePageService = endorsementCertificatePageService; this.certificatePageService = certificatePageService; } /** - * Returns the path for the view and the data model for the Endorsement Key Credentials page. + * Returns the path for the view and the data model for the Endorsement Key Certificates page. * * @param params The object to map url parameters into. - * @param model The data model for the request. Can contain data from - * redirect. - * @return the path for the view and data model for the Endorsement Key Credentials page. + * @param model The data model for the request. Can contain data from redirect. + * @return the path for the view and data model for the Endorsement Key Certificates page. */ @RequestMapping public ModelAndView initPage(final NoPageParams params, final Model model) { @@ -83,19 +82,19 @@ public ModelAndView initPage(final NoPageParams params, final Model model) { } /** - * Processes the request to retrieve a list of endorsement credentials for display on the endorsement credential's - * page. + * Processes the request to retrieve a list of {@link EndorsementCredential} objects for display on the + * Endorsement Certificates page. * * @param dataTableInput data table input received from the front-end - * @return data table of endorsement credentials + * @return data table of {@link EndorsementCredential} objects */ @ResponseBody @GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE) - public DataTableResponse getEndorsementCredentialsTableData( + public DataTableResponse getEndorsementCertificatesTableData( final DataTableInput dataTableInput) { - log.info("Received request to display list of endorsement credentials"); + log.info("Received request to display list of endorsement certificates"); log.debug("Request received a datatable input object for the endorsement " - + "credentials page: {}", dataTableInput); + + "certificates page: {}", dataTableInput); // grab the column to which ordering has been applied final Order orderColumn = dataTableInput.getOrderColumn(); @@ -119,30 +118,28 @@ public DataTableResponse getEndorsementCredentialsTableDa orderColumn); FilteredRecordsList ekFilteredRecordsList = - getFilteredEndorsementCredentialList( + getFilteredEndorsementCertificateList( globalSearchTerm, columnsWithSearchCriteria, searchableColumnNames, pageable); - log.info("Returning the size of the filtered list of endorsement credentials: {}", + log.info("Returning the size of the filtered list of endorsement certificates: {}", ekFilteredRecordsList.getRecordsFiltered()); return new DataTableResponse<>(ekFilteredRecordsList, dataTableInput); } /** - * Processes the request to download the specified endorsement credential. + * Processes the request to download the specified {@link EndorsementCredential} object. * - * @param id the UUID of the endorsement credential to download - * @param response the response object (needed to update the header with the - * file name) + * @param id the UUID of the specified {@link EndorsementCredential} object to download + * @param response the response object (needed to update the header with the file name) * @throws IOException when writing to response output stream */ @GetMapping("/download") - public void downloadEndorsementCredential(@RequestParam final String id, - final HttpServletResponse response) + public void downloadEndorsementCertificate(@RequestParam final String id, final HttpServletResponse response) throws IOException { - log.info("Received request to download endorsement credential id {}", id); + log.info("Received request to download endorsement certificate id {}", id); try { final DownloadFile downloadFile = certificatePageService.downloadCertificate(EndorsementCredential.class, @@ -152,21 +149,20 @@ public void downloadEndorsementCredential(@RequestParam final String id, response.getOutputStream().write(downloadFile.getFileBytes()); } catch (Exception exception) { log.error("An exception was thrown while attempting to download the" - + " specified endorsement credential", exception); + + " specified endorsement certificate", exception); response.sendError(HttpServletResponse.SC_NOT_FOUND); } } /** - * Processes the request to bulk download all the endorsement credentials. + * Processes the request to bulk download all the {@link EndorsementCredential} objects. * - * @param response the response object (needed to update the header with the - * file name) + * @param response the response object (needed to update the header with the file name) * @throws IOException when writing to response output stream */ @GetMapping("/bulk-download") - public void bulkDownloadEndorsementCredentials(final HttpServletResponse response) throws IOException { - log.info("Received request to download all endorsement credentials"); + public void bulkDownloadEndorsementCertificates(final HttpServletResponse response) throws IOException { + log.info("Received request to download all endorsement certificates"); final String zipFileName = "endorsement_certificates.zip"; final String singleFileName = "Endorsement_Certificates"; @@ -179,24 +175,24 @@ public void bulkDownloadEndorsementCredentials(final HttpServletResponse respons singleFileName); } catch (Exception exception) { log.error("An exception was thrown while attempting to bulk download all the " - + "endorsement credentials", exception); + + "endorsement certificates", exception); response.sendError(HttpServletResponse.SC_NOT_FOUND); } } /** - * Processes the request to upload one or more endorsement credentials to the ACA. + * Processes the request to upload one or more {@link EndorsementCredential} objects to the ACA. * * @param files the files to process * @param redirectAttributes RedirectAttributes used to forward data back to the original page. - * @return the redirection view + * @return redirect to the Endorsement Credentials page * @throws URISyntaxException if malformed URI */ @PostMapping("/upload") - protected RedirectView uploadEndorsementCredential(@RequestParam("file") final MultipartFile[] files, - final RedirectAttributes redirectAttributes) + protected RedirectView uploadEndorsementCertificate(@RequestParam("file") final MultipartFile[] files, + final RedirectAttributes redirectAttributes) throws URISyntaxException { - log.info("Received request to upload one or more endorsement credentials"); + log.info("Received request to upload one or more endorsement certificates"); Map model = new HashMap<>(); PageMessages messages = new PageMessages(); @@ -205,13 +201,13 @@ protected RedirectView uploadEndorsementCredential(@RequestParam("file") final M List errorMessages = new ArrayList<>(); List successMessages = new ArrayList<>(); - EndorsementCredential parsedEndorsementCredential = - endorsementCredentialPageService.parseEndorsementCredential(file, errorMessages); + EndorsementCredential parsedEndorsementCertificate = + endorsementCertificatePageService.parseEndorsementCertificate(file, errorMessages); - if (parsedEndorsementCredential != null) { + if (parsedEndorsementCertificate != null) { certificatePageService.storeCertificate(CertificateType.ENDORSEMENT_CREDENTIALS, file.getOriginalFilename(), - successMessages, errorMessages, parsedEndorsementCredential); + successMessages, errorMessages, parsedEndorsementCertificate); } messages.addSuccessMessages(successMessages); @@ -223,19 +219,18 @@ protected RedirectView uploadEndorsementCredential(@RequestParam("file") final M } /** - * Processes the request to archive/soft delete the specified endorsement credential. + * Processes the request to archive/soft delete the specified {@link EndorsementCredential} object. * - * @param id the UUID of the endorsement certificate to delete - * @param redirectAttributes RedirectAttributes used to forward data back to the original - * page. - * @return redirect to this page + * @param id the UUID of the specified {@link EndorsementCredential} object to delete + * @param redirectAttributes RedirectAttributes used to forward data back to the original page. + * @return redirect to the Endorsement Credentials page * @throws URISyntaxException if malformed URI */ @PostMapping("/delete") - public RedirectView deleteEndorsementCredential(@RequestParam final String id, - final RedirectAttributes redirectAttributes) + public RedirectView deleteEndorsementCertificate(@RequestParam final String id, + final RedirectAttributes redirectAttributes) throws URISyntaxException { - log.info("Received request to delete endorsement credential id {}", id); + log.info("Received request to delete endorsement certificate id {}", id); Map model = new HashMap<>(); PageMessages messages = new PageMessages(); @@ -249,8 +244,8 @@ public RedirectView deleteEndorsementCredential(@RequestParam final String id, messages.addSuccessMessages(successMessages); messages.addErrorMessages(errorMessages); } catch (Exception exception) { - final String errorMessage = "An exception was thrown while attempting to delete" - + " endorsement credential"; + final String errorMessage = "An exception was thrown while attempting to delete the specified" + + " endorsement certificate"; messages.addErrorMessage(errorMessage); log.error(errorMessage, exception); } @@ -260,18 +255,18 @@ public RedirectView deleteEndorsementCredential(@RequestParam final String id, } /** - * Processes the request to delete multiple endorsement credentials. + * Processes the request to delete multiple {@link EndorsementCredential} objects. * - * @param ids the list of UUIDs of the endorsement credentials to be deleted + * @param ids the list of UUIDs of the {@link EndorsementCredential} objects to be deleted * @param redirectAttributes used to pass data back to the original page after the operation - * @return a redirect to the endorsement credential page + * @return a redirect to the Endorsement Certificates page * @throws URISyntaxException if the URI is malformed */ @PostMapping("/bulk-delete") - public RedirectView bulkDeleteEndorsementCredentials(@RequestParam final List ids, - final RedirectAttributes redirectAttributes) + public RedirectView bulkDeleteEndorsementCertificates(@RequestParam final List ids, + final RedirectAttributes redirectAttributes) throws URISyntaxException { - log.info("Received request to delete multiple endorsement credentials"); + log.info("Received request to delete multiple endorsement certificates"); Map model = new HashMap<>(); PageMessages messages = new PageMessages(); @@ -280,13 +275,12 @@ public RedirectView bulkDeleteEndorsementCredentials(@RequestParam final List errorMessages = new ArrayList<>(); try { - certificatePageService.bulkDeleteCertificates(ids, successMessages, - errorMessages); + certificatePageService.bulkDeleteCertificates(ids, successMessages, errorMessages); messages.addSuccessMessages(successMessages); messages.addErrorMessages(errorMessages); } catch (Exception exception) { final String errorMessage = "An exception was thrown while attempting to delete" - + " multiple endorsement credentials"; + + " multiple endorsement certificates"; messages.addErrorMessage(errorMessage); log.error(errorMessage, exception); } @@ -296,34 +290,35 @@ public RedirectView bulkDeleteEndorsementCredentials(@RequestParam final List * The method allows filtering based on a global search term and column-specific search criteria, * and returns the result in a paginated format. - * *

* The method handles four cases: *

    *
  1. If no global search term and no column-specific search criteria are provided, - * all endorsement credentials are returned.
  2. + * all {@link EndorsementCredential} objects are returned. *
  3. If both a global search term and column-specific search criteria are provided, - * it performs filtering on both.
  4. - *
  5. If only column-specific search criteria are provided, it filters based on the column-specific - * criteria.
  6. - *
  7. If only a global search term is provided, it filters based on the global search term.
  8. + * {@link EndorsementCredential} objects are filtered based on both criteria. + *
  9. If only column-specific search criteria are provided, {@link EndorsementCredential} objects + * are filtered according to the column-specific criteria.
  10. + *
  11. If only a global search term is provided, {@link EndorsementCredential} objects + * are filtered according to the global search term.
  12. *
*

* - * @param globalSearchTerm A global search term that will be used to filter the endorsement - * credentials by the searchable fields. + * @param globalSearchTerm A global search term that will be used to filter the + * {@link EndorsementCredential} objects by the searchable fields. * @param columnsWithSearchCriteria A set of columns with specific search criteria entered by the user. * @param searchableColumnNames A set of searchable column names that are for the global search term. * @param pageable pageable * @return A {@link FilteredRecordsList} containing the filtered and paginated list of - * endorsement credentials, along with the total number of records and the number of records matching the - * filter criteria. + * {@link EndorsementCredential} objects, along with the total number of records and the number of records + * matching the filter criteria. */ - private FilteredRecordsList getFilteredEndorsementCredentialList( + private FilteredRecordsList getFilteredEndorsementCertificateList( final String globalSearchTerm, final Set columnsWithSearchCriteria, final Set searchableColumnNames, @@ -333,7 +328,7 @@ private FilteredRecordsList getFilteredEndorsementCredent // if no value has been entered in the global search textbox and in the column search dropdown if (StringUtils.isBlank(globalSearchTerm) && columnsWithSearchCriteria.isEmpty()) { pagedResult = - endorsementCredentialPageService.findEndorsementCredentialsByArchiveFlag(false, pageable); + endorsementCertificatePageService.findEndorsementCertificatesByArchiveFlag(false, pageable); } else if (!StringUtils.isBlank(globalSearchTerm) && !columnsWithSearchCriteria.isEmpty()) { // if a value has been entered in both the global search textbox and in the column search dropdown pagedResult = certificatePageService.findCertificatesByGlobalAndColumnSpecificSearchTerm( @@ -367,7 +362,7 @@ private FilteredRecordsList getFilteredEndorsementCredent ekFilteredRecordsList.setRecordsFiltered(pagedResult.getTotalElements()); ekFilteredRecordsList.setRecordsTotal( - endorsementCredentialPageService.findEndorsementCredentialRepositoryCount()); + endorsementCertificatePageService.findEndorsementCertificateRepositoryCount()); return ekFilteredRecordsList; } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/HelpPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/HelpPageController.java index e29e1b34d..d42eae63f 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/HelpPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/HelpPageController.java @@ -1,12 +1,11 @@ package hirs.attestationca.portal.page.controllers; -import hirs.attestationca.persist.FilteredRecordsList; +import hirs.attestationca.persist.entity.userdefined.FilteredRecordsList; import hirs.attestationca.persist.entity.userdefined.HIRSLogger; import hirs.attestationca.persist.service.HelpPageService; import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableResponse; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageMessages; import hirs.attestationca.portal.page.params.NoPageParams; import jakarta.servlet.http.HttpServletResponse; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IDevIdCertificatePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IDevIdCertificatePageController.java index 0c8e5f945..4f76718c3 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IDevIdCertificatePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IDevIdCertificatePageController.java @@ -1,17 +1,16 @@ package hirs.attestationca.portal.page.controllers; -import hirs.attestationca.persist.FilteredRecordsList; +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; +import hirs.attestationca.persist.entity.userdefined.DownloadFile; +import hirs.attestationca.persist.entity.userdefined.FilteredRecordsList; import hirs.attestationca.persist.entity.userdefined.certificate.IDevIDCertificate; +import hirs.attestationca.persist.enums.CertificateType; import hirs.attestationca.persist.service.CertificatePageService; import hirs.attestationca.persist.service.IDevIdCertificatePageService; -import hirs.attestationca.persist.service.util.CertificateType; -import hirs.attestationca.persist.service.util.DataTablesColumn; -import hirs.attestationca.persist.util.DownloadFile; import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableResponse; import hirs.attestationca.portal.datatables.Order; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageMessages; import hirs.attestationca.portal.page.params.NoPageParams; import hirs.attestationca.portal.page.utils.ControllerPagesUtils; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IndexPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IndexPageController.java index 1e1d2d531..5972ed3bb 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IndexPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IndexPageController.java @@ -1,7 +1,6 @@ package hirs.attestationca.portal.page.controllers; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.params.NoPageParams; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Controller; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IssuedCertificatePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IssuedCertificatePageController.java index 75c6ef54d..17d3c7132 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IssuedCertificatePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/IssuedCertificatePageController.java @@ -1,17 +1,16 @@ package hirs.attestationca.portal.page.controllers; -import hirs.attestationca.persist.FilteredRecordsList; +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; +import hirs.attestationca.persist.entity.userdefined.DownloadFile; +import hirs.attestationca.persist.entity.userdefined.FilteredRecordsList; import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate; +import hirs.attestationca.persist.enums.CertificateType; import hirs.attestationca.persist.service.CertificatePageService; -import hirs.attestationca.persist.service.IssuedAttestationCertificatePageService; -import hirs.attestationca.persist.service.util.CertificateType; -import hirs.attestationca.persist.service.util.DataTablesColumn; -import hirs.attestationca.persist.util.DownloadFile; +import hirs.attestationca.persist.service.IssuedCertificatePageService; import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableResponse; import hirs.attestationca.portal.datatables.Order; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageMessages; import hirs.attestationca.portal.page.params.NoPageParams; import hirs.attestationca.portal.page.utils.ControllerPagesUtils; @@ -50,21 +49,21 @@ @RequestMapping("/HIRS_AttestationCAPortal/portal/certificate-request/issued-certificates") @Log4j2 public class IssuedCertificatePageController extends PageController { - private final IssuedAttestationCertificatePageService issuedAttestationCertificateService; + private final IssuedCertificatePageService issuedAttestationCertificateService; private final CertificatePageService certificatePageService; /** * Constructor for the Issued Attestation Certificate page. * - * @param issuedAttestationCertificatePageService issued certificate page service - * @param certificatePageService certificate page service + * @param issuedCertificatePageService issued certificate page service + * @param certificatePageService certificate page service */ @Autowired public IssuedCertificatePageController( - final IssuedAttestationCertificatePageService issuedAttestationCertificatePageService, + final IssuedCertificatePageService issuedCertificatePageService, final CertificatePageService certificatePageService) { super(Page.ISSUED_CERTIFICATES); - this.issuedAttestationCertificateService = issuedAttestationCertificatePageService; + this.issuedAttestationCertificateService = issuedCertificatePageService; this.certificatePageService = certificatePageService; } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/PageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/PageController.java similarity index 81% rename from HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/PageController.java rename to HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/PageController.java index 317c966b3..93a64d7ed 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/PageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/PageController.java @@ -1,5 +1,7 @@ -package hirs.attestationca.portal.page; +package hirs.attestationca.portal.page.controllers; +import hirs.attestationca.portal.page.Page; +import hirs.attestationca.portal.page.params.PageParams; import lombok.AllArgsConstructor; import lombok.extern.log4j.Log4j2; import org.apache.http.client.utils.URIBuilder; @@ -14,7 +16,6 @@ import java.net.URISyntaxException; import java.util.Map; -import java.util.Optional; /** * Abstract class to provide common functionality for page Controllers. @@ -110,10 +111,10 @@ protected final RedirectView redirectToSelf( /** * Redirects controller's page with the specified data. * - * @param newPage new page to get the model and view - * @param params The url parameters to pass to the page. - * @param model The model data to pass to the page. - * @param attr The request's RedirectAttributes to hold the model data. + * @param newPage new page to get the model and view + * @param params The url parameters to pass to the page. + * @param model The model data to pass to the page. + * @param redirectAttributes The request's RedirectAttributes to hold the model data. * @return RedirectView back to the page with the specified parameters. * @throws URISyntaxException if malformed URI */ @@ -121,33 +122,34 @@ protected final RedirectView redirectTo( final Page newPage, final P params, final Map model, - final RedirectAttributes attr) throws URISyntaxException { + final RedirectAttributes redirectAttributes) throws URISyntaxException { + + final String defaultUri = "../" + newPage.getViewName(); - String defaultUri = "../" + newPage.getViewName(); - // create uri with specified parameters - URIBuilder uri = new URIBuilder("../" + newPage.getViewName()); + // create uri with default uri + URIBuilder uri = new URIBuilder(defaultUri); log.debug("Redirection URI = {}", uri.toString()); if (params != null) { for (Map.Entry e : params.asMap().entrySet()) { - Object v = Optional.ofNullable(e.getValue()).orElse(null); + Object v = e.getValue(); uri.addParameter(e.getKey(), v.toString()); } } - // create view - RedirectView redirect = new RedirectView(defaultUri); + // create redirect view + RedirectView redirectView = new RedirectView(uri.toString()); // do not put model attributes in the url - redirect.setExposeModelAttributes(false); + redirectView.setExposeModelAttributes(false); // add model data to forward to redirected page if (model != null) { for (Map.Entry e : model.entrySet()) { - attr.addFlashAttribute(e.getKey(), e.getValue()); + redirectAttributes.addFlashAttribute(e.getKey(), e.getValue()); } } - return redirect; + return redirectView; } } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/PlatformCredentialPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/PlatformCertificatePageController.java similarity index 71% rename from HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/PlatformCredentialPageController.java rename to HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/PlatformCertificatePageController.java index 92373441c..5304d2ff0 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/PlatformCredentialPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/PlatformCertificatePageController.java @@ -1,18 +1,18 @@ package hirs.attestationca.portal.page.controllers; -import hirs.attestationca.persist.FilteredRecordsList; + +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; +import hirs.attestationca.persist.entity.userdefined.DownloadFile; +import hirs.attestationca.persist.entity.userdefined.FilteredRecordsList; import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; +import hirs.attestationca.persist.enums.CertificateType; import hirs.attestationca.persist.service.CertificatePageService; -import hirs.attestationca.persist.service.PlatformCredentialPageService; -import hirs.attestationca.persist.service.util.CertificateType; -import hirs.attestationca.persist.service.util.DataTablesColumn; -import hirs.attestationca.persist.util.DownloadFile; +import hirs.attestationca.persist.service.PlatformCertificatePageService; import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableResponse; import hirs.attestationca.portal.datatables.Order; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageMessages; import hirs.attestationca.portal.page.params.NoPageParams; import hirs.attestationca.portal.page.utils.ControllerPagesUtils; @@ -46,36 +46,35 @@ import java.util.zip.ZipOutputStream; /** - * Controller for the Platform Credentials page. + * Controller for the Platform Certificates page. */ @Controller @RequestMapping("/HIRS_AttestationCAPortal/portal/certificate-request/platform-credentials") @Log4j2 -public class PlatformCredentialPageController extends PageController { +public class PlatformCertificatePageController extends PageController { private final CertificatePageService certificatePageService; - private final PlatformCredentialPageService platformCredentialService; + private final PlatformCertificatePageService platformCertificatePageService; /** - * Constructor for the Platform Credential Page Controller. + * Constructor for the Platform Certificate Page Controller. * - * @param certificatePageService certificate page service - * @param platformCredentialService platform credential service + * @param certificatePageService certificate page service + * @param platformCertificatePageService platform certificate page service */ @Autowired - public PlatformCredentialPageController(final CertificatePageService certificatePageService, - final PlatformCredentialPageService platformCredentialService) { + public PlatformCertificatePageController(final CertificatePageService certificatePageService, + final PlatformCertificatePageService platformCertificatePageService) { super(Page.PLATFORM_CREDENTIALS); this.certificatePageService = certificatePageService; - this.platformCredentialService = platformCredentialService; + this.platformCertificatePageService = platformCertificatePageService; } /** - * Returns the path for the view and the data model for the platform credential page. + * Returns the path for the view and the data model for the Platform Certificate page. * * @param params The object to map url parameters into. - * @param model The data model for the request. Can contain data from - * redirect. - * @return the path for the view and data model for the platform credential page. + * @param model The data model for the request. Can contain data from redirect. + * @return the path for the view and data model for the Platform Certificate page. */ @RequestMapping public ModelAndView initPage(final NoPageParams params, final Model model) { @@ -83,17 +82,17 @@ public ModelAndView initPage(final NoPageParams params, final Model model) { } /** - * Processes the request to retrieve a list of platform credentials for display on the platform credentials page. + * Processes the request to retrieve a {@link PlatformCredential} objects for display on the Platform Certificate + * page. * * @param dataTableInput data table input received from the front-end - * @return data table of platform credentials + * @return data table of {@link PlatformCredential} objects */ @ResponseBody @GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE) - public DataTableResponse getPlatformCredentialsTableData( - final DataTableInput dataTableInput) { - log.info("Received request to display list of platform credentials"); - log.debug("Request received a datatable input object for the platform credentials page: {}", + public DataTableResponse getPlatformCertificatesTableData(final DataTableInput dataTableInput) { + log.info("Received request to display list of platform certificates"); + log.debug("Request received a datatable input object for the platform certificates page: {}", dataTableInput); // grab the column to which ordering has been applied @@ -118,68 +117,65 @@ public DataTableResponse getPlatformCredentialsTableData( orderColumn); FilteredRecordsList pcFilteredRecordsList = - getFilteredPlatformCredentialList( + getFilteredPlatformCertificateList( globalSearchTerm, columnsWithSearchCriteria, searchableColumnNames, pageable); - // loop all the platform credentials + // loop all the platform certificates for (PlatformCredential pc : pcFilteredRecordsList) { // find the EC using the PC's "holder serial number" - EndorsementCredential associatedEC = platformCredentialService - .findECBySerialNumber(pc.getHolderSerialNumber()); + EndorsementCredential associatedEC = platformCertificatePageService + .findEndorsementCertificateBySerialNumber(pc.getHolderSerialNumber()); if (associatedEC != null) { - log.debug("EC ID for holder s/n {} = {}", pc - .getHolderSerialNumber(), associatedEC.getId()); + log.debug("EC ID for holder s/n {} = {}", pc.getHolderSerialNumber(), associatedEC.getId()); } pc.setEndorsementCredential(associatedEC); } - log.info("Returning the size of the filtered list of platform credentials: {}", + log.info("Returning the size of the filtered list of platform certificates: {}", pcFilteredRecordsList.getRecordsFiltered()); return new DataTableResponse<>(pcFilteredRecordsList, dataTableInput); } /** - * Processes the request to download the selected platform credential. + * Processes the request to download the selected {@link PlatformCredential} object. * - * @param id the UUID of the platform credential to download - * @param response the response object (needed to update the header with the - * file name) + * @param id the UUID of the {@link PlatformCredential} object to download + * @param response the response object (needed to update the header with the file name) * @throws IOException when writing to response output stream */ @GetMapping("/download") - public void downloadPlatformCredential(@RequestParam final String id, final HttpServletResponse response) + public void downloadPlatformCertificate(@RequestParam final String id, final HttpServletResponse response) throws IOException { - log.info("Received request to download platform credential id {}", id); + log.info("Received request to download platform certificate with id {}", id); try { final DownloadFile downloadFile = - certificatePageService.downloadCertificate(PlatformCredential.class, - UUID.fromString(id)); + certificatePageService.downloadCertificate(PlatformCredential.class, UUID.fromString(id)); response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;" + downloadFile.getFileName()); response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); response.getOutputStream().write(downloadFile.getFileBytes()); } catch (Exception exception) { log.error("An exception was thrown while attempting to download the" - + " specified platform credential", exception); + + " specified platform certificate", exception); response.sendError(HttpServletResponse.SC_NOT_FOUND); } } /** - * Processes the request to bulk download all the platform credentials. + * Processes the request to bulk download all the {@link PlatformCredential} objects. * * @param response the response object (needed to update the header with the * file name) * @throws IOException when writing to response output stream */ @GetMapping("/bulk-download") - public void bulkDownloadPlatformCredentials(final HttpServletResponse response) throws IOException { - log.info("Received request to download all platform credentials"); + public void bulkDownloadPlatformCertificates(final HttpServletResponse response) throws IOException { + log.info("Received request to download all platform certificates"); final String zipFileName = "platform_certificates.zip"; final String singleFileName = "Platform_Certificate"; @@ -192,24 +188,24 @@ public void bulkDownloadPlatformCredentials(final HttpServletResponse response) singleFileName); } catch (Exception exception) { log.error("An exception was thrown while attempting to bulk download all the" - + "platform credentials", exception); + + "platform certificates", exception); response.sendError(HttpServletResponse.SC_NOT_FOUND); } } /** - * Processes the request to upload one or more platform credentials to the ACA. + * Processes the request to upload one or more {@link PlatformCredential} objects to the ACA. * * @param files the files to process * @param redirectAttributes RedirectAttributes used to forward data back to the original page. - * @return the redirection view + * @return a redirect to the Platform Certificates page * @throws URISyntaxException if malformed URI */ @PostMapping("/upload") - protected RedirectView uploadPlatformCredentials( - @RequestParam("file") final MultipartFile[] files, - final RedirectAttributes redirectAttributes) throws URISyntaxException { - log.info("Received request to upload one or more platform credentials"); + protected RedirectView uploadPlatformCertificates(@RequestParam("file") final MultipartFile[] files, + final RedirectAttributes redirectAttributes) + throws URISyntaxException { + log.info("Received request to upload one or more platform certificates"); Map model = new HashMap<>(); PageMessages messages = new PageMessages(); @@ -218,15 +214,14 @@ protected RedirectView uploadPlatformCredentials( List errorMessages = new ArrayList<>(); List successMessages = new ArrayList<>(); - PlatformCredential parsedPlatformCredential = - platformCredentialService.parsePlatformCredential(file, - errorMessages); + PlatformCredential parsedPlatformCertificate = + platformCertificatePageService.parsePlatformCertificate(file, errorMessages); - if (parsedPlatformCredential != null) { + if (parsedPlatformCertificate != null) { certificatePageService.storeCertificate( CertificateType.PLATFORM_CREDENTIALS, file.getOriginalFilename(), - successMessages, errorMessages, parsedPlatformCredential); + successMessages, errorMessages, parsedPlatformCertificate); } messages.addSuccessMessages(successMessages); @@ -238,19 +233,19 @@ protected RedirectView uploadPlatformCredentials( } /** - * Processes the request to archive/soft delete the provided platform credential. + * Processes the request to archive/soft delete the specified {@link PlatformCredential} object. * - * @param id the UUID of the platform credential to delete + * @param id the UUID of the specified {@link PlatformCredential} object to delete * @param redirectAttributes RedirectAttributes used to forward data back to the original * page. - * @return a redirect to the platform certificate page + * @return a redirect to the Platform Certificates page * @throws URISyntaxException if the URI is malformed */ @PostMapping("/delete") - public RedirectView deletePlatformCredential(@RequestParam final String id, - final RedirectAttributes redirectAttributes) + public RedirectView deletePlatformCertificate(@RequestParam final String id, + final RedirectAttributes redirectAttributes) throws URISyntaxException { - log.info("Received request to delete platform credential id {}", id); + log.info("Received request to delete platform certificate with id {}", id); Map model = new HashMap<>(); PageMessages messages = new PageMessages(); @@ -259,14 +254,12 @@ public RedirectView deletePlatformCredential(@RequestParam final String id, List errorMessages = new ArrayList<>(); try { - certificatePageService.deleteCertificate(UUID.fromString(id), - successMessages, errorMessages); - + certificatePageService.deleteCertificate(UUID.fromString(id), successMessages, errorMessages); messages.addSuccessMessages(successMessages); messages.addErrorMessages(errorMessages); } catch (Exception exception) { final String errorMessage = "An exception was thrown while attempting to delete" - + " the specified platform credential"; + + " the specified platform certificate"; messages.addErrorMessage(errorMessage); log.error(errorMessage, exception); } @@ -276,11 +269,11 @@ public RedirectView deletePlatformCredential(@RequestParam final String id, } /** - * Processes the request to delete multiple platform certificates. + * Processes the request to delete multiple {@link PlatformCredential} objects. * - * @param ids the list of UUIDs of the platform certificates to be deleted + * @param ids the list of UUIDs of the {@link PlatformCredential} objects to be deleted * @param redirectAttributes used to pass data back to the original page after the operation - * @return a redirect to the platform certificate page + * @return a redirect to the Platform Certificates page * @throws URISyntaxException if the URI is malformed */ @PostMapping("/bulk-delete") @@ -296,8 +289,7 @@ public RedirectView bulkDeletePlatformCertificates(@RequestParam final List errorMessages = new ArrayList<>(); try { - certificatePageService.bulkDeleteCertificates(ids, successMessages, - errorMessages); + certificatePageService.bulkDeleteCertificates(ids, successMessages, errorMessages); messages.addSuccessMessages(successMessages); messages.addErrorMessages(errorMessages); } catch (Exception exception) { @@ -312,34 +304,35 @@ public RedirectView bulkDeletePlatformCertificates(@RequestParam final List * The method allows filtering based on a global search term and column-specific search criteria, * and returns the result in a paginated format. - * *

* The method handles four cases: *

    *
  1. If no global search term and no column-specific search criteria are provided, - * all platform credentials are returned.
  2. + * all {@link PlatformCredential} objects are returned. *
  3. If both a global search term and column-specific search criteria are provided, - * it performs filtering on both.
  4. - *
  5. If only column-specific search criteria are provided, it filters based on the column-specific - * criteria.
  6. - *
  7. If only a global search term is provided, it filters based on the global search term.
  8. + * {@link PlatformCredential} objects are filtered based on both criteria. + *
  9. If only column-specific search criteria are provided, {@link PlatformCredential} objects + * are filtered according to the column-specific criteria.
  10. + *
  11. If only a global search term is provided, {@link PlatformCredential} objects + * are filtered according to the global search term.
  12. *
*

* - * @param globalSearchTerm A global search term that will be used to filter the platform - * credentials by the searchable fields. + * @param globalSearchTerm A global search term that will be used to filter {@link PlatformCredential} + * objects by the searchable fields. * @param columnsWithSearchCriteria A set of columns with specific search criteria entered by the user. - * @param searchableColumnNames A set of searchable column names that are for the global search term. + * @param searchableColumnNames A set of searchable column names that are for the global search term. * @param pageable pageable * @return A {@link FilteredRecordsList} containing the filtered and paginated list of - * platform credentials, along with the total number of records and the number of records matching the + * {@link PlatformCredential} objects, along with the total number of records and the number of records matching the * filter criteria. */ - private FilteredRecordsList getFilteredPlatformCredentialList( + private FilteredRecordsList getFilteredPlatformCertificateList( final String globalSearchTerm, final Set columnsWithSearchCriteria, final Set searchableColumnNames, @@ -348,7 +341,7 @@ private FilteredRecordsList getFilteredPlatformCredentialLis // if no value has been entered in the global search textbox and in the column search dropdown if (StringUtils.isBlank(globalSearchTerm) && columnsWithSearchCriteria.isEmpty()) { - pagedResult = platformCredentialService.findPlatformCredentialsByArchiveFlag(false, pageable); + pagedResult = platformCertificatePageService.findPlatformCertificatesByArchiveFlag(false, pageable); } else if (!StringUtils.isBlank(globalSearchTerm) && !columnsWithSearchCriteria.isEmpty()) { // if a value has been entered in both the global search textbox and in the column search dropdown pagedResult = certificatePageService.findCertificatesByGlobalAndColumnSpecificSearchTerm( @@ -381,8 +374,7 @@ private FilteredRecordsList getFilteredPlatformCredentialLis } pcFilteredRecordsList.setRecordsFiltered(pagedResult.getTotalElements()); - pcFilteredRecordsList.setRecordsTotal(platformCredentialService.findPlatformCredentialRepositoryCount()); - + pcFilteredRecordsList.setRecordsTotal(platformCertificatePageService.findPlatformCertificateRepositoryCount()); return pcFilteredRecordsList; } diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/PolicyPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/PolicyPageController.java index afeed1758..3478647ce 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/PolicyPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/PolicyPageController.java @@ -3,7 +3,6 @@ import hirs.attestationca.persist.entity.userdefined.PolicySettings; import hirs.attestationca.persist.service.PolicyPageService; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageMessages; import hirs.attestationca.portal.page.PolicyPageModel; import hirs.attestationca.portal.page.params.NoPageParams; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java index 337f3735c..69b091dbf 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java @@ -2,7 +2,6 @@ import hirs.attestationca.persist.service.ReferenceManifestDetailsPageService; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageMessages; import hirs.attestationca.portal.page.params.ReferenceManifestDetailsPageParams; import lombok.extern.log4j.Log4j2; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java index 0276ed760..e9d6b60cd 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestPageController.java @@ -1,17 +1,16 @@ package hirs.attestationca.portal.page.controllers; -import hirs.attestationca.persist.FilteredRecordsList; +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; +import hirs.attestationca.persist.entity.userdefined.DownloadFile; +import hirs.attestationca.persist.entity.userdefined.FilteredRecordsList; import hirs.attestationca.persist.entity.userdefined.ReferenceManifest; import hirs.attestationca.persist.entity.userdefined.rim.BaseReferenceManifest; import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest; import hirs.attestationca.persist.service.ReferenceManifestPageService; -import hirs.attestationca.persist.service.util.DataTablesColumn; -import hirs.attestationca.persist.util.DownloadFile; import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableResponse; import hirs.attestationca.portal.datatables.Order; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageMessages; import hirs.attestationca.portal.page.params.NoPageParams; import hirs.attestationca.portal.page.utils.ControllerPagesUtils; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java index a318e0ba6..eba1dcaf7 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/RimDatabasePageController.java @@ -1,16 +1,15 @@ package hirs.attestationca.portal.page.controllers; -import hirs.attestationca.persist.DBManagerException; -import hirs.attestationca.persist.FilteredRecordsList; +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; +import hirs.attestationca.persist.entity.userdefined.FilteredRecordsList; import hirs.attestationca.persist.entity.userdefined.rim.ReferenceDigestValue; import hirs.attestationca.persist.entity.userdefined.rim.SupportReferenceManifest; +import hirs.attestationca.persist.exceptions.DBManagerException; import hirs.attestationca.persist.service.ReferenceDigestValuePageService; -import hirs.attestationca.persist.service.util.DataTablesColumn; import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableResponse; import hirs.attestationca.portal.datatables.Order; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.params.NoPageParams; import hirs.attestationca.portal.page.utils.ControllerPagesUtils; import jakarta.validation.Valid; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/TrustChainCertificatePageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/TrustChainCertificatePageController.java index 638b86597..5de121bc5 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/TrustChainCertificatePageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/TrustChainCertificatePageController.java @@ -1,19 +1,18 @@ package hirs.attestationca.portal.page.controllers; -import hirs.attestationca.persist.FilteredRecordsList; import hirs.attestationca.persist.entity.manager.CACredentialRepository; import hirs.attestationca.persist.entity.manager.CertificateRepository; +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; +import hirs.attestationca.persist.entity.userdefined.DownloadFile; +import hirs.attestationca.persist.entity.userdefined.FilteredRecordsList; import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential; +import hirs.attestationca.persist.enums.CertificateType; import hirs.attestationca.persist.service.CertificatePageService; import hirs.attestationca.persist.service.TrustChainCertificatePageService; -import hirs.attestationca.persist.service.util.CertificateType; -import hirs.attestationca.persist.service.util.DataTablesColumn; -import hirs.attestationca.persist.util.DownloadFile; import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableResponse; import hirs.attestationca.portal.datatables.Order; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageMessages; import hirs.attestationca.portal.page.params.NoPageParams; import hirs.attestationca.portal.page.utils.CertificateStringMapBuilder; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java index dbe7e48d6..538f3c8c8 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java @@ -1,14 +1,13 @@ package hirs.attestationca.portal.page.controllers; -import hirs.attestationca.persist.FilteredRecordsList; +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; +import hirs.attestationca.persist.entity.userdefined.FilteredRecordsList; import hirs.attestationca.persist.entity.userdefined.SupplyChainValidationSummary; import hirs.attestationca.persist.service.ValidationSummaryPageService; -import hirs.attestationca.persist.service.util.DataTablesColumn; import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableResponse; import hirs.attestationca.portal.datatables.Order; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.params.NoPageParams; import hirs.attestationca.portal.page.utils.ControllerPagesUtils; import jakarta.servlet.http.HttpServletRequest; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/CertificateDetailsPageParams.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/CertificateDetailsPageParams.java index 7f5a94ccd..60f1b52bb 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/CertificateDetailsPageParams.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/CertificateDetailsPageParams.java @@ -1,6 +1,5 @@ package hirs.attestationca.portal.page.params; -import hirs.attestationca.portal.page.PageParams; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; @@ -16,26 +15,9 @@ @AllArgsConstructor @ToString public class CertificateDetailsPageParams implements PageParams { - private String id; - private String type; - /** - * Constructor to set ID Certificate Details URL parameters. - * - * @param id the String parameter to set - */ - public CertificateDetailsPageParams(final String id) { - this.id = id; - } - - /** - * Default constructor for Spring. - */ - public CertificateDetailsPageParams() { - id = null; - type = null; - } + private String type; /** * Allows PageController to iterate over the url parameters. diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/NoPageParams.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/NoPageParams.java index a270d0afc..d9def2e01 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/NoPageParams.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/NoPageParams.java @@ -1,7 +1,5 @@ package hirs.attestationca.portal.page.params; -import hirs.attestationca.portal.page.PageParams; - import java.util.LinkedHashMap; /** diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/PageParams.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/PageParams.java similarity index 86% rename from HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/PageParams.java rename to HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/PageParams.java index 0771facdd..08f2ad091 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/PageParams.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/PageParams.java @@ -1,4 +1,4 @@ -package hirs.attestationca.portal.page; +package hirs.attestationca.portal.page.params; import java.util.LinkedHashMap; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/ReferenceManifestDetailsPageParams.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/ReferenceManifestDetailsPageParams.java index 0acb4eb6a..b7a22f449 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/ReferenceManifestDetailsPageParams.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/ReferenceManifestDetailsPageParams.java @@ -1,6 +1,5 @@ package hirs.attestationca.portal.page.params; -import hirs.attestationca.portal.page.PageParams; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/ReferenceManifestPageParams.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/ReferenceManifestPageParams.java deleted file mode 100644 index bd166cc57..000000000 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/params/ReferenceManifestPageParams.java +++ /dev/null @@ -1,44 +0,0 @@ -package hirs.attestationca.portal.page.params; - -import hirs.attestationca.portal.page.PageParams; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.util.LinkedHashMap; - -/** - * URL parameters object for the ReferenceManifest page and controller. - */ -@Getter -@Setter -@NoArgsConstructor -@AllArgsConstructor -public class ReferenceManifestPageParams implements PageParams { - - private String id; - private String type; - - /** - * Constructor to set all Reference Integrity Manifest URL parameters. - * - * @param id the String parameter to set - */ - public ReferenceManifestPageParams(final String id) { - this.id = id; - } - - /** - * Allows PageController to iterate over the url parameters. - * - * @return map containing the object's URL parameters. - */ - @Override - public LinkedHashMap asMap() { - LinkedHashMap map = new LinkedHashMap<>(); - map.put("id", id); - map.put("type", type); - return map; - } -} diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/ControllerPagesUtils.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/ControllerPagesUtils.java index bfde10df2..4f23f4a6e 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/ControllerPagesUtils.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/utils/ControllerPagesUtils.java @@ -1,8 +1,8 @@ package hirs.attestationca.portal.page.utils; import hirs.attestationca.persist.entity.userdefined.Certificate; +import hirs.attestationca.persist.entity.userdefined.DataTablesColumn; import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; -import hirs.attestationca.persist.service.util.DataTablesColumn; import hirs.attestationca.portal.datatables.Column; import hirs.attestationca.portal.datatables.Order; import io.micrometer.common.util.StringUtils; diff --git a/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/PageControllerTest.java b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/PageControllerTest.java index 839b0a2cc..0da0857b0 100644 --- a/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/PageControllerTest.java +++ b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/PageControllerTest.java @@ -6,6 +6,7 @@ import hirs.attestationca.persist.entity.userdefined.certificate.IDevIDCertificate; import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate; import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; +import hirs.attestationca.portal.page.controllers.PageController; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; diff --git a/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/CertificateDetailsPageControllerTest.java b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/CertificateDetailsPageControllerTest.java index 09cbbbe30..d1d0f69e2 100644 --- a/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/CertificateDetailsPageControllerTest.java +++ b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/CertificateDetailsPageControllerTest.java @@ -10,7 +10,6 @@ import hirs.attestationca.persist.enums.AppraisalStatus; import hirs.attestationca.persist.enums.HealthStatus; import hirs.attestationca.portal.page.Page; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageControllerTest; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.jupiter.api.BeforeAll; diff --git a/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/EndorsementKeyCredentialsPageControllerTest.java b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/EndorsementKeyCredentialsPageControllerTest.java index e71b0202b..7dbbcb7ff 100644 --- a/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/EndorsementKeyCredentialsPageControllerTest.java +++ b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/EndorsementKeyCredentialsPageControllerTest.java @@ -1,6 +1,6 @@ package hirs.attestationca.portal.page.controllers; -import hirs.attestationca.persist.entity.manager.EndorsementCredentialRepository; +import hirs.attestationca.persist.entity.manager.EndorsementCertificateRepository; import hirs.attestationca.persist.entity.userdefined.Certificate; import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; import hirs.attestationca.portal.page.PageControllerTest; @@ -44,7 +44,7 @@ public class EndorsementKeyCredentialsPageControllerTest extends PageControllerT // Repository manager to handle data access between endorsement certificate entity and data storage in db @Autowired - private EndorsementCredentialRepository endorsementCredentialRepository; + private EndorsementCertificateRepository endorsementCertificateRepository; // A file that contains a cert that is not an EK Cert. Should be parsable as a general cert, // but should (eventually) not be stored as an EK because it isn't one. @@ -84,7 +84,7 @@ public void prepareTests() throws IOException { */ @AfterEach public void afterEachTest() { - this.endorsementCredentialRepository.deleteAll(); + this.endorsementCertificateRepository.deleteAll(); } /** @@ -116,7 +116,7 @@ public void uploadAndArchiveNonEndorsementCert() throws Exception { // verify the cert was actually stored List records = - endorsementCredentialRepository.findAll(); + endorsementCertificateRepository.findAll(); assertEquals(1, records.size()); // verify the cert is not yet archived @@ -129,7 +129,7 @@ public void uploadAndArchiveNonEndorsementCert() throws Exception { .param("id", cert.getId().toString())) .andExpect(status().is3xxRedirection()) .andReturn(); - records = endorsementCredentialRepository.findAll(); + records = endorsementCertificateRepository.findAll(); assertEquals(1, records.size()); // verify the cert is now archived @@ -164,7 +164,7 @@ public void testUploadBadEndorsementCert() throws Exception { // verify the cert was not actually stored List records = - endorsementCredentialRepository.findAll(); + endorsementCertificateRepository.findAll(); assertEquals(0, records.size()); } @@ -193,7 +193,7 @@ public void testDeleteEndorsementKeyCredential() throws Exception { assertEquals(0, pageMessages.getErrorMessages().size()); // Verify the EK cert has been stored - List records = endorsementCredentialRepository.findAll(); + List records = endorsementCertificateRepository.findAll(); assertEquals(1, records.size()); Certificate cert = records.iterator().next(); @@ -244,7 +244,7 @@ public void testDeleteMultipleEndorsementKeyCredentials() throws Exception { assertEquals(0, pageMessages.getErrorMessages().size()); // Verify one EK certificate has been stored - List records = endorsementCredentialRepository.findAll(); + List records = endorsementCertificateRepository.findAll(); assertEquals(1, records.size()); Certificate cert = records.iterator().next(); diff --git a/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/PolicyPageControllerTest.java b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/PolicyPageControllerTest.java index 45aec3237..2ad67b086 100644 --- a/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/PolicyPageControllerTest.java +++ b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/PolicyPageControllerTest.java @@ -2,7 +2,6 @@ import hirs.attestationca.persist.entity.manager.PolicyRepository; import hirs.attestationca.persist.entity.userdefined.PolicySettings; -import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.PageControllerTest; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; diff --git a/HIRS_Utils/src/main/java/hirs/utils/enums/ComponentType.java b/HIRS_Utils/src/main/java/hirs/utils/enums/ComponentType.java deleted file mode 100644 index d896b1268..000000000 --- a/HIRS_Utils/src/main/java/hirs/utils/enums/ComponentType.java +++ /dev/null @@ -1,85 +0,0 @@ -package hirs.utils.enums; - -public enum ComponentType { - - /** - * Baseboard. - */ - BASEBOARD(Values.BASEBOARD), - /** - * BIOS or UEFI. - */ - BIOS_UEFI(Values.BIOS_UEFI), - /** - * Chassis. - */ - CHASSIS(Values.CHASSIS), - /** - * Hard Drive. - */ - HARD_DRIVE(Values.HARD_DRIVE), - /** - * Memory. - */ - MEMORY(Values.MEMORY), - /** - * Network Interface Card. - */ - NIC(Values.NIC), - /** - * Processor. - */ - PROCESSOR(Values.PROCESSOR); - - /** - * Constructor. - * - * @param val string value - */ - ComponentType(final String val) { - if (!this.name().equals(val)) { - throw new IllegalArgumentException("Incorrect use of ComponentType"); - } - } - - /** - * String values for use in {@link ComponentType}. - */ - public static class Values { - - /** - * Baseboard. - */ - public static final String BASEBOARD = "BASEBOARD"; - - /** - * BIOS or UEFI. - */ - public static final String BIOS_UEFI = "BIOS_UEFI"; - - /** - * Chassis. - */ - public static final String CHASSIS = "CHASSIS"; - - /** - * Hard Drive. - */ - public static final String HARD_DRIVE = "HARD_DRIVE"; - - /** - * Memory. - */ - public static final String MEMORY = "MEMORY"; - - /** - * Network Interface Card. - */ - public static final String NIC = "NIC"; - - /** - * Processor. - */ - public static final String PROCESSOR = "PROCESSOR"; - } -} diff --git a/HIRS_Utils/src/main/java/hirs/utils/enums/PortalScheme.java b/HIRS_Utils/src/main/java/hirs/utils/enums/PortalScheme.java deleted file mode 100644 index c42f358d7..000000000 --- a/HIRS_Utils/src/main/java/hirs/utils/enums/PortalScheme.java +++ /dev/null @@ -1,16 +0,0 @@ -package hirs.utils.enums; - -/** - * Schemes used by the HIRS Portal. - */ -public enum PortalScheme { - - /** - * HTTP. - */ - HTTP, - /** - * HTTPS. - */ - HTTPS; -} diff --git a/HIRS_Utils/src/main/java/hirs/utils/exception/PolicyManagerException.java b/HIRS_Utils/src/main/java/hirs/utils/exception/PolicyManagerException.java deleted file mode 100644 index ae7a234e9..000000000 --- a/HIRS_Utils/src/main/java/hirs/utils/exception/PolicyManagerException.java +++ /dev/null @@ -1,41 +0,0 @@ -package hirs.utils.exception; - -/** - * This class represents an Exception generated by a - * PolicyManager. - */ -public class PolicyManagerException extends RuntimeException { - - private static final long serialVersionUID = 3081536085161873284L; - - /** - * Creates a new PolicyManagerException that has the message - * msg. - * - * @param msg exception message - */ - public PolicyManagerException(final String msg) { - super(msg); - } - - /** - * Creates a new PolicyManagerException that wraps the given - * Throwable. - * - * @param t root cause - */ - public PolicyManagerException(final Throwable t) { - super(t); - } - - /** - * Creates a new PolicyManagerException that has the message - * msg and wraps the root cause. - * - * @param msg exception message - * @param t root cause - */ - public PolicyManagerException(final String msg, final Throwable t) { - super(msg, t); - } -} diff --git a/HIRS_Utils/src/main/java/hirs/utils/exception/package-info.java b/HIRS_Utils/src/main/java/hirs/utils/exception/package-info.java deleted file mode 100644 index 464dea8c2..000000000 --- a/HIRS_Utils/src/main/java/hirs/utils/exception/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package hirs.utils.exception; diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/TPMBaselineGeneratorException.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/TPMBaselineGeneratorException.java deleted file mode 100644 index 89485beaf..000000000 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/TPMBaselineGeneratorException.java +++ /dev/null @@ -1,42 +0,0 @@ -package hirs.utils.tpm; - -/** - * This class represents an Exception generated by - * CreateTPMBaseline. - */ -public class TPMBaselineGeneratorException extends Exception { - - private static final long serialVersionUID = 8850867303391694668L; - - /** - * Creates a new CreateTPMBaselineException that has the - * message msg. - * - * @param msg exception message - */ - TPMBaselineGeneratorException(final String msg) { - super(msg); - } - - /** - * Creates a new CreateTPMBaselineException that wraps the - * given Throwable. - * - * @param t root cause - */ - TPMBaselineGeneratorException(final Throwable t) { - super(t); - } - - /** - * Creates a new CreateTPMBaselineException that has the - * message msg and wraps the root cause. - * - * @param msg exception message - * @param t root cause - */ - TPMBaselineGeneratorException(final String msg, final Throwable t) { - super(msg, t); - } - -} diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/DigestTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/DigestTest.java index bc030f81a..b79371521 100644 --- a/HIRS_Utils/src/test/java/hirs/data/persist/DigestTest.java +++ b/HIRS_Utils/src/test/java/hirs/data/persist/DigestTest.java @@ -497,6 +497,6 @@ public final void testFromStringInvalid() { } private byte[] getEmptySHA1Digest() { - return DigestUtils.sha1(new byte[] {}); + return DigestUtils.sha1(new byte[]{}); } }