diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AttestationCertificateAuthorityConfiguration.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AttestationCertificateAuthorityConfiguration.java index 3c6207f0..ca17bec1 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AttestationCertificateAuthorityConfiguration.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AttestationCertificateAuthorityConfiguration.java @@ -6,11 +6,7 @@ import hirs.utils.LogConfigurationUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.hibernate.SessionFactory; -import org.hibernate.boot.Metadata; -import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -import org.hibernate.service.ServiceRegistry; +import org.hibernate.jpa.HibernatePersistenceProvider; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -22,7 +18,9 @@ import org.springframework.context.annotation.Scope; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.core.env.Environment; import org.springframework.jdbc.datasource.DriverManagerDataSource; -import org.springframework.orm.hibernate5.HibernateTransactionManager; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -75,13 +73,20 @@ public class AttestationCertificateAuthorityConfiguration implements WebMvcConfi } } - -// @Value("${persistence.db.url}") -// private String url; - @Autowired private Environment environment; + /** + * Creates a JPA transaction manager. + * @return instance of the manager + */ + @Bean + public JpaTransactionManager jpaTransactionManager() { + JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject()); + return transactionManager; + } + /** * @return bean to resolve injected annotation.Value property expressions * for beans. @@ -91,26 +96,64 @@ public class AttestationCertificateAuthorityConfiguration implements WebMvcConfi return new PropertySourcesPlaceholderConfigurer(); } + /** + * Initialization of the ACA. Detects environment and runs configuration + * methods as required. This method is intended to be invoked by the Spring + * application context. + */ + @PostConstruct + void initialize() { + + // ensure that Bouncy Castle is registered as a security provider + Security.addProvider(new BouncyCastleProvider()); + + // obtain path to ACA configuration + Path certificatesPath = Paths.get( + environment.getRequiredProperty("aca.directories.certificates")); + + // create base directories if they do not exist + try { + Files.createDirectories(certificatesPath); + } catch (IOException e) { + throw new BeanInitializationException( + "Encountered error while initializing ACA directories: " + e.getMessage(), e); + } + + // create the ACA key store if it doesn't exist + Path keyStorePath = Paths.get(environment.getRequiredProperty("aca.keyStore.location")); + if (!Files.exists(keyStorePath)) { + throw new IllegalStateException( + String.format("ACA Key Store not found at %s. Consult the HIRS User " + + "Guide for ACA installation instructions.", + environment.getRequiredProperty("aca.keyStore.location"))); + } + } + + private HibernateJpaVendorAdapter vendorAdaptor() { + HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + vendorAdapter.setShowSql(true); + return vendorAdapter; + } + /** * Configures a session factory bean that in turn configures the hibernate session factory. * Enables auto scanning of annotations such that entities do not need to be registered in a * hibernate configuration file. * - * @return session factory + * @return Entity Manager */ -// @Bean - public SessionFactory sessionFactory() { - ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() - .applySettings(getSettings()).build(); - MetadataSources metadataSources = new MetadataSources(serviceRegistry); - Metadata metadata = metadataSources.buildMetadata(); -// LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); - SessionFactory sessionFactory = metadata.getSessionFactoryBuilder().build(); -// sessionFactory.setDataSource(dataSource()); -// sessionFactory.setPackagesToScan("hirs"); -// sessionFactory.setHibernateProperties(hibernateProperties()); - return sessionFactory; - } + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() { + LocalContainerEntityManagerFactoryBean entityManagerFactoryBean + = new LocalContainerEntityManagerFactoryBean(); + entityManagerFactoryBean.setJpaVendorAdapter(vendorAdaptor()); + entityManagerFactoryBean.setDataSource(dataSource()); + entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class); + entityManagerFactoryBean.setPackagesToScan("hirs"); + entityManagerFactoryBean.setJpaProperties(hibernateProperties()); + + return entityManagerFactoryBean; + } private Map getSettings() { Map settings = new HashMap<>(); @@ -135,7 +178,7 @@ public class AttestationCertificateAuthorityConfiguration implements WebMvcConfi * * @return configured data source */ - @Bean + @Bean(destroyMethod = "close") public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setUrl( @@ -178,39 +221,6 @@ public class AttestationCertificateAuthorityConfiguration implements WebMvcConfi return properties; } - /** - * Initialization of the ACA. Detects environment and runs configuration - * methods as required. This method is intended to be invoked by the Spring - * application context. - */ - @PostConstruct - void initialize() { - - // ensure that Bouncy Castle is registered as a security provider - Security.addProvider(new BouncyCastleProvider()); - - // obtain path to ACA configuration - Path certificatesPath = Paths.get( - environment.getRequiredProperty("aca.directories.certificates")); - - // create base directories if they do not exist - try { - Files.createDirectories(certificatesPath); - } catch (IOException e) { - throw new BeanInitializationException( - "Encountered error while initializing ACA directories: " + e.getMessage(), e); - } - - // create the ACA key store if it doesn't exist - Path keyStorePath = Paths.get(environment.getRequiredProperty("aca.keyStore.location")); - if (!Files.exists(keyStorePath)) { - throw new IllegalStateException( - String.format("ACA Key Store not found at %s. Consult the HIRS User " - + "Guide for ACA installation instructions.", - environment.getRequiredProperty("aca.keyStore.location"))); - } - } - /** * @return the {@link PrivateKey} of the ACA */ @@ -239,15 +249,6 @@ public class AttestationCertificateAuthorityConfiguration implements WebMvcConfi + "from key store: " + e.getMessage(), e); } } - /** - * Configure a transaction manager for the hibernate session factory. - * - * @return transaction manager - */ - @Bean - public HibernateTransactionManager getTransactionManager() { - return new HibernateTransactionManager(sessionFactory()); - } /** * Bean holding the maximum retry attempts for a DB transaction. diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/InitializationListener.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/InitializationListener.java index fe290bd2..005f5baa 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/InitializationListener.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/InitializationListener.java @@ -24,12 +24,10 @@ public class InitializationListener implements ServletContextListener { context.refresh(); // obtain reference to hibernate session factory -// SessionFactory sessionFactory = context.getBean(LocalSessionFactoryBean.class) -// .getObject(); EntityManager entityManager = context.getBean(EntityManagerFactory.class) .createEntityManager(); AcaDbInit.insertDefaultEntries(new AppraiserServiceImpl(entityManager), - new PolicyServiceImpl(entityManager) + new PolicyServiceImpl() ); } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/SystemInit.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/SystemInit.java new file mode 100644 index 00000000..c240cb97 --- /dev/null +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/SystemInit.java @@ -0,0 +1,179 @@ +package hirs.attestationca; + +import hirs.appraiser.Appraiser; +import hirs.appraiser.AppraiserPlugin; +import hirs.appraiser.AppraiserPluginManager; +import hirs.appraiser.DeviceInfoAppraiser; +import hirs.appraiser.IMAAppraiser; +import hirs.appraiser.TPMAppraiser; +import hirs.attestationca.configuration.PersistenceConfiguration; +import hirs.attestationca.service.AppraiserServiceImpl; +import hirs.attestationca.service.PolicyServiceImpl; +import hirs.data.persist.policy.HIRSPolicy; +import hirs.data.persist.policy.Policy; +import hirs.data.persist.policy.TPMPolicy; +import hirs.utils.HIRSProfiles; +import hirs.utils.SpringContextProvider; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ClassPathBeanDefinitionScanner; +import org.springframework.core.type.filter.AssignableTypeFilter; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; + +import javax.persistence.EntityManagerFactory; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +/** + * This class initializes the system for appraisals. This stores the requisite items in the database + * to ensure that an appraisal can happen. For example, the system requires that a set of + * Appraisers be defined in the database. This class will initialize the set of + * Appraisers. + */ +public final class SystemInit { + + private static final Logger LOGGER = LogManager.getLogger(SystemInit.class); + private static final int ALL_MASK = 0xFFFFFF; + private static final int NONE_MASK = 0x000000; + + private static final String TPM_POLICY_NAME = "Test TPM Policy"; + + private SystemInit() { + /* do nothing */ + } + + /** + * Initializes the system by creating a new IMAAppraiser and storing it in the + * database. + *

+ * This method is currently available for command line use, but is not used within the project. + * + * @param args not used + */ + @SuppressWarnings("checkstyle:methodlength") + public static void main(final String[] args) { + LOGGER.info("Seeding database with initial entries..."); + // construct application context + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + context.getEnvironment().addActiveProfile(HIRSProfiles.SERVER); + + // create class path scanner for discovering appraiser plugins + ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context, false); + scanner.addIncludeFilter(new AssignableTypeFilter(AppraiserPlugin.class)); + scanner.addIncludeFilter(new AssignableTypeFilter(SpringContextProvider.class)); + scanner.addIncludeFilter(new AssignableTypeFilter(AppraiserPluginManager.class)); + + // scan for appraiser plugins + int registeredBeanCount = scanner.scan("hirs"); + System.out.println("Beans scanned " + registeredBeanCount); + LOGGER.info("Beans scanned: " + registeredBeanCount); + + // register the database configuration and refresh the context + context.register(PersistenceConfiguration.class); + context.refresh(); + + // obtain reference to hibernate Entity Manager + EntityManagerFactory entityManagerFactory + = context.getBean(LocalContainerEntityManagerFactoryBean.class).getObject(); + + // initialize the managers for this initialization process + AppraiserServiceImpl appraiserServiceImpl = new AppraiserServiceImpl( + entityManagerFactory.createEntityManager()); + PolicyServiceImpl policyServiceImpl = new PolicyServiceImpl(); + + + LOGGER.info("Checking for DeviceInfo appraiser..."); + DeviceInfoAppraiser deviceInfoAppraiser = (DeviceInfoAppraiser) + appraiserServiceImpl.getAppraiser(DeviceInfoAppraiser.NAME); + if (deviceInfoAppraiser == null) { + LOGGER.info("DeviceInfo appraiser not found; creating..."); + appraiserServiceImpl.saveAppraiser(new DeviceInfoAppraiser()); + } else { + LOGGER.info("DeviceInfo appraiser found."); + } + + LOGGER.info("Checking for TPM appraiser..."); + TPMAppraiser tpmApp = (TPMAppraiser) appraiserServiceImpl.getAppraiser(TPMAppraiser.NAME); + if (tpmApp == null) { + LOGGER.info("TPM appraiser not found; creating..."); + tpmApp = (TPMAppraiser) appraiserServiceImpl.saveAppraiser(new TPMAppraiser()); + } else { + LOGGER.info("TPM appraiser found."); + } + + // build up required appraisers set + Set> requiredAppraisers = new HashSet<>(); + requiredAppraisers.add(DeviceInfoAppraiser.class); + requiredAppraisers.add(TPMAppraiser.class); + requiredAppraisers.add(IMAAppraiser.class); + + // obtain plugins from the context + Collection appraiserPlugins = + context.getBeansOfType(AppraiserPlugin.class).values(); + + LOGGER.info("Total Appraiser Plugins: " + appraiserPlugins.size()); + System.out.println("Total Appraiser Plugins: " + appraiserPlugins.size()); + + // merge the appraiser plugins with the hirs policy appraisers + for (AppraiserPlugin appraiserPlugin : appraiserPlugins) { + // add in appraiser plugin to required appraisers list + requiredAppraisers.add(appraiserPlugin.getClass()); + + LOGGER.info("Checking for plugin appraiser {}...", appraiserPlugin); + Appraiser storedAppraiser = appraiserServiceImpl + .getAppraiser(appraiserPlugin.getName()); + if (storedAppraiser == null) { + LOGGER.info("Saving plugin appraiser {}...", appraiserPlugin); + storedAppraiser = appraiserServiceImpl.saveAppraiser(appraiserPlugin); + } else { + LOGGER.info("Found plugin appraiser {}.", appraiserPlugin); + } + + Policy policy = appraiserPlugin.getDefaultPolicy(); + if (policy != null) { + LOGGER.info("Saving plugin appraiser's default policy: {}", policy); + policy = policyServiceImpl.savePolicy(policy); + policyServiceImpl.setDefaultPolicy(storedAppraiser, policy); + } + } + + // create HIRS policy + LOGGER.info("Checking for HIRS policy..."); + HIRSPolicy hirsPolicy = (HIRSPolicy) policyServiceImpl.getPolicyByName( + HIRSPolicy.DEFAULT_HIRS_POLICY_NAME + ); + if (hirsPolicy == null) { + LOGGER.info( + "HIRS policy not found; saving with required appraisers: {}", + requiredAppraisers + ); + hirsPolicy = new HIRSPolicy(HIRSPolicy.DEFAULT_HIRS_POLICY_NAME); + hirsPolicy.setRequiredAppraisers(requiredAppraisers); + + // initialize the default policy + policyServiceImpl.savePolicy(hirsPolicy); + } else { + LOGGER.info("HIRS policy found."); + } + + // initiate the default tpm policy + LOGGER.info("Checking for TPM policy..."); + TPMPolicy tpmPolicy = (TPMPolicy) policyServiceImpl.getPolicyByName(TPM_POLICY_NAME); + if (tpmPolicy == null) { + LOGGER.info("TPM policy not found, creating..."); + tpmPolicy = new TPMPolicy(TPM_POLICY_NAME); + tpmPolicy.setAppraiseFullReport(true); + tpmPolicy.setAppraisePcrMask(NONE_MASK); + tpmPolicy.setDefaultPcrAppraisalValues(); + tpmPolicy.setReportPcrMask(ALL_MASK); + tpmPolicy = (TPMPolicy) policyServiceImpl.savePolicy(tpmPolicy); + policyServiceImpl.setDefaultPolicy(tpmApp, tpmPolicy); + } else { + LOGGER.info("TPM policy found."); + } + + LOGGER.info("Complete."); + } +} diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/configuration/PersistenceConfiguration.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/configuration/PersistenceConfiguration.java index d530a537..05534b01 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/configuration/PersistenceConfiguration.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/configuration/PersistenceConfiguration.java @@ -1,5 +1,6 @@ package hirs.attestationca.configuration; +import hirs.attestationca.AttestationCertificateAuthorityConfiguration; import hirs.attestationca.service.CertificateServiceImpl; import hirs.attestationca.service.DbServiceImpl; import hirs.attestationca.service.DeviceServiceImpl; @@ -13,7 +14,9 @@ import hirs.persist.service.ReferenceDigestValueService; import hirs.persist.service.ReferenceManifestService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import javax.persistence.EntityManager; @@ -29,6 +32,8 @@ import javax.persistence.PersistenceContext; */ @Configuration @EnableJpaRepositories("hirs.attestationca.service") +@ComponentScan(basePackages = "hirs.data.persist") +@Import({ AttestationCertificateAuthorityConfiguration.class }) public class PersistenceConfiguration { /** @@ -55,7 +60,7 @@ public class PersistenceConfiguration { */ @Bean public PolicyService policyService() { - PolicyServiceImpl serviceImpl = new PolicyServiceImpl(entityManager); + PolicyServiceImpl serviceImpl = new PolicyServiceImpl(); setDbServiceRetrySettings(serviceImpl); return serviceImpl; } @@ -67,7 +72,7 @@ public class PersistenceConfiguration { */ @Bean public DeviceService deviceService() { - DeviceServiceImpl serviceImpl = new DeviceServiceImpl(entityManager); + DeviceServiceImpl serviceImpl = new DeviceServiceImpl(); setDbServiceRetrySettings(serviceImpl); return serviceImpl; } @@ -79,7 +84,7 @@ public class PersistenceConfiguration { */ @Bean public CertificateService certificateService() { - CertificateServiceImpl serviceImpl = new CertificateServiceImpl(entityManager); + CertificateServiceImpl serviceImpl = new CertificateServiceImpl(); setDbServiceRetrySettings(serviceImpl); return serviceImpl; } @@ -92,7 +97,7 @@ public class PersistenceConfiguration { @Bean public ReferenceManifestService referenceManifestService() { ReferenceManifestServiceImpl serviceImpl - = new ReferenceManifestServiceImpl(entityManager); + = new ReferenceManifestServiceImpl(); setDbServiceRetrySettings(serviceImpl); return serviceImpl; } @@ -105,7 +110,7 @@ public class PersistenceConfiguration { @Bean public ReferenceDigestValueService referenceEventService() { ReferenceDigestValueServiceImpl serviceImpl - = new ReferenceDigestValueServiceImpl(entityManager); + = new ReferenceDigestValueServiceImpl(); setDbServiceRetrySettings(serviceImpl); return serviceImpl; } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/CertificateServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/CertificateServiceImpl.java index 436e1a0e..107b89e8 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/CertificateServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/CertificateServiceImpl.java @@ -43,14 +43,6 @@ public class CertificateServiceImpl extends DbServiceImpl @PersistenceContext private EntityManager entityManager; - /** - * Default constructor. - * @param entityManager entity manager for jpa hibernate events - */ - public CertificateServiceImpl(final EntityManager entityManager) { - this.entityManager = entityManager; - } - @Override public Certificate saveCertificate(final Certificate certificate) { LOGGER.debug("Saving certificate: {}", certificate); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/DeviceServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/DeviceServiceImpl.java index 7907314e..5a4ae96f 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/DeviceServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/DeviceServiceImpl.java @@ -36,14 +36,6 @@ public class DeviceServiceImpl extends DbServiceImpl @PersistenceContext private EntityManager entityManager; - /** - * Default constructor. - * @param entityManager entity manager for jpa hibernate events - */ - public DeviceServiceImpl(final EntityManager entityManager) { - this.entityManager = entityManager; - } - @Override public final Device getByName(final String name) { LOGGER.debug("Find device by name: {}", name); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/PolicyServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/PolicyServiceImpl.java index d96b1b99..157efeed 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/PolicyServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/PolicyServiceImpl.java @@ -45,15 +45,6 @@ public class PolicyServiceImpl extends DbServiceImpl @PersistenceContext private EntityManager entityManager; - /** - * Default Constructor. - * @param entityManager entity manager for jpa hibernate events - */ - public PolicyServiceImpl(final EntityManager entityManager) { - super(entityManager); - this.entityManager = entityManager; - } - @Override public List getList() { LOGGER.debug("Getting all policies..."); @@ -176,6 +167,17 @@ public class PolicyServiceImpl extends DbServiceImpl return ret; } + @Override + public Policy getPolicyByName(final String name) { + for (Policy policy : getList()) { + if (policy.getName().equals(name)) { + return policy; + } + } + + return null; + } + @Override public void setPolicy(final Appraiser appraiser, final Policy policy) { diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/ReferenceDigestValueServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/ReferenceDigestValueServiceImpl.java index 437f71e7..5240f60c 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/ReferenceDigestValueServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/ReferenceDigestValueServiceImpl.java @@ -38,14 +38,6 @@ public class ReferenceDigestValueServiceImpl extends DbServiceImpl getList() { LOGGER.debug("Getting all reference digest value..."); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/ReferenceManifestServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/ReferenceManifestServiceImpl.java index 9a2b9fa8..cd46c70f 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/ReferenceManifestServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/ReferenceManifestServiceImpl.java @@ -38,13 +38,6 @@ public class ReferenceManifestServiceImpl extends DbServiceImpl { */ Policy getDefaultPolicy(Appraiser appraiser); - + /** + * Retrieves the Policy from the database. This searches the + * database for an entry whose name matches name. It then + * reconstructs a Policy object from the database entry + * + * @param name name of the policy + * @return policy if found, otherwise null. + */ + Policy getPolicyByName(String name); /** * Sets the Policy for the Appraiser.