[#634] Updated Page Controller series integration tests and added new ones (#647)

* updated PageTestConfiguration

* updated PageControllerTest

* updated DevicePageControllerTest

* added 3 new tests

* added test resources
This commit is contained in:
D2B8CA1B27286366A8607B6858C0565962613D18D0546480078B520CD7AD705A 2023-12-05 20:04:06 +00:00 committed by GitHub
parent c2a150e6b9
commit b52eb770f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 1066 additions and 138 deletions

View File

@ -1,5 +1,15 @@
package hirs.attestationca.portal.page;
import hirs.attestationca.persist.entity.userdefined.Certificate;
import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential;
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 java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
@ -7,6 +17,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.Model;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
@ -26,30 +39,22 @@ import static org.hamcrest.Matchers.equalTo;
@TestInstance(TestInstance.Lifecycle.PER_CLASS) // needed to use non-static BeforeAll
public abstract class PageControllerTest {
/**
* Pre-prefix path for all the Controllers.
* There's an option in Page to add prefix path used for some Controllers.
*/
private String prePrefixPath = "HIRS_AttestationCAPortal/portal/";
/**
* Contains server-side support for testing Spring MVC applications
* via WebTestClient with MockMvc for server request handling.
*/
// Contains server-side support for testing Spring MVC applications
// via WebTestClient with MockMvc for server request handling.
@Autowired
private WebApplicationContext webApplicationContext;
/**
* Used to set up mocked servlet environment to test the HTTP controller
* endpoints without the need to launch the embedded servlet container.
*/
// Used to set up mocked servlet environment to test the HTTP controller
// endpoints without the need to launch the embedded servlet container.
private MockMvc mockMvc;
/**
* Represents the Page for the Controller under test.
*/
// Represents the Page for the Controller under test.
private final Page page;
// Pre-prefix path for all the Controllers.
// There's an option in Page to add prefix path used for some Controllers.
private static final String PRE_PREFIX_PATH = "/HIRS_AttestationCAPortal/portal/";
/**
* Constructor requiring the Page's display and routing specification.
*
@ -59,15 +64,6 @@ public abstract class PageControllerTest {
this.page = page;
}
/**
* Returns the Page's pre-prePrefix path for routing.
*
* @return the Page's pre-prePrefix path
*/
public String getPrePrefixPath() {
return prePrefixPath;
}
/**
* Returns the Page's display and routing specification.
*
@ -86,6 +82,112 @@ public abstract class PageControllerTest {
return mockMvc;
}
/**
* Returns a blank model for initPage tests.
*
* @return a blank model for initPage tests.
*/
protected static final Model getBlankModel() {
return new ExtendedModelMap();
}
/**
* If the AssertionError is a redirected URL error, check the results of the executed request
* for the actual redirected URL and throw a new error containing the comparison to the expected
* URL.
*
* If the error is not a redirected URL error, rethrow the original error.
*
* @param expectedURL the expected redirected URL AntMatcher pattern
* @param actions the results of the executed request
* @param err the AssertionError to indicate if the error is a redirected URL error
* @throws AssertionError with added information if a redirected URL error or the original error
*/
protected static final void enhanceRedirectedUrlError(
final String expectedURL,
final ResultActions actions,
final AssertionError err) throws AssertionError {
if ("Redirected URL".equals(err.getMessage())) {
final String actualURL = actions.andReturn().getResponse().getRedirectedUrl();
final String msg
= err.getMessage() + ": "
+ " expected [" + expectedURL + "]"
+ " but found [" + actualURL + "]";
throw new AssertionError(msg);
} else {
throw err;
}
}
/**
* Construct a test certificate from the given parameters.
* @param <T> the type of Certificate that will be created
* @param certificateClass the class of certificate to generate
* @param filename the location of the certificate to be used
* @return the newly-constructed Certificate
* @throws IOException if there is a problem constructing the test certificate
*/
public <T extends Certificate> Certificate getTestCertificate(
final Class<T> certificateClass,
final String filename)
throws IOException {
return getTestCertificate(certificateClass, filename, null, null);
}
/**
* Construct a test certificate from the given parameters.
* @param <T> the type of Certificate that will be created
* @param certificateClass the class of certificate to generate
* @param filename the location of the certificate to be used
* @param endorsementCredential the endorsement credentials (can be null)
* @param platformCredentials the platform credentials (can be null)
* @return the newly-constructed Certificate
* @throws IOException if there is a problem constructing the test certificate
*/
public <T extends Certificate> Certificate getTestCertificate(
final Class<T> certificateClass,
final String filename,
final EndorsementCredential endorsementCredential,
final List<PlatformCredential> platformCredentials)
throws IOException {
Path fPath;
try {
fPath = Paths.get(this.getClass().getResource(filename).toURI());
} catch (URISyntaxException e) {
throw new IOException("Could not resolve path URI", e);
}
switch (certificateClass.getSimpleName()) {
case "EndorsementCredential":
return new EndorsementCredential(fPath);
case "PlatformCredential":
return new PlatformCredential(fPath);
case "CertificateAuthorityCredential":
return new CertificateAuthorityCredential(fPath);
case "IssuedAttestationCertificate":
return new IssuedAttestationCertificate(fPath,
endorsementCredential, platformCredentials);
default:
throw new IllegalArgumentException(
String.format("Unknown certificate class %s", certificateClass.getName())
);
}
}
/**
* Create page path (add pre-prefix and prefix path)
*/
public String getPagePath() {
String pagePath = PRE_PREFIX_PATH + page.getPrefixPath() + page.getViewName();
if (page.getPrefixPath() == null) {
pagePath = PRE_PREFIX_PATH + page.getViewName();
}
return pagePath;
}
/**
* Sets up the test environment.
*/
@ -104,9 +206,9 @@ public abstract class PageControllerTest {
public final void doTestPagesExist() throws Exception {
// Add prefix path for page verification
String pagePath = "/" + prePrefixPath + page.getPrefixPath() + getPage().getViewName();
String pagePath = PRE_PREFIX_PATH + page.getPrefixPath() + getPage().getViewName();
if (page.getPrefixPath() == null) {
pagePath = "/" + prePrefixPath + getPage().getViewName();
pagePath = PRE_PREFIX_PATH + getPage().getViewName();
}
getMockMvc()
@ -119,5 +221,4 @@ public abstract class PageControllerTest {
PageController.PAGES_ATTRIBUTE, equalTo(Page.values()))
);
}
}
}

View File

@ -1,21 +1,6 @@
package hirs.attestationca.portal.page;
import hirs.attestationca.portal.PageConfiguration;
import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.io.IOException;
import java.net.URISyntaxException;
@ -24,6 +9,17 @@ import java.nio.file.Paths;
import java.security.*;
import java.security.cert.X509Certificate;
import java.util.Properties;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
/**
* A configuration class for testing Attestation CA Portal classes that require a database.
@ -32,7 +28,6 @@ import java.util.Properties;
* A few 'dummy' beans had to be created to override PersistenceJPAConfig beans that were
* not needed and would interfere with the tests.
*/
//@Import({ PageConfiguration.class })
@TestConfiguration
@EnableJpaRepositories(basePackages = "hirs.attestationca.persist.entity.manager")
public class PageTestConfiguration {
@ -118,18 +113,6 @@ public class PageTestConfiguration {
return hibernateProperties;
}
/**
* Generates JPA transaction manager.
*
* @return transaction manager
*/
// @Bean
// public PlatformTransactionManager transactionManager() {
// final JpaTransactionManager transactionManager = new JpaTransactionManager();
// transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
// return transactionManager;
// }
/**
* @return a blank {@link PrivateKey}
* this function is only used to override the PersistenceJPAConfig privateKey bean during test

View File

@ -0,0 +1,441 @@
package hirs.attestationca.portal.page.controllers;
import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.manager.DeviceRepository;
import hirs.attestationca.persist.entity.userdefined.Device;
import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential;
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.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 java.io.IOException;
import java.util.*;
import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.hasItem;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Integration tests that test the URL End Points of CertificateDetailsPageController.
*/
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class CertificateDetailsPageControllerTest extends PageControllerTest {
// Base path for the page
private String pagePath;
// Repository manager to handle data access between device entity and data storage in db
@Autowired
private DeviceRepository deviceRepository;
// Repository manager to handle data access between certificate entity and data storage in db
@Autowired
private CertificateRepository certificateRepository;
private CertificateAuthorityCredential caCertificate;
private CertificateAuthorityCredential caRootCertificate;
private PlatformCredential platformCredential;
private PlatformCredential platformCredential2;
private PlatformCredential platformCertificatePCI;
private EndorsementCredential endorsementCredential;
private IssuedAttestationCertificate issuedCredential;
// Random UUID for certificate search.
private static final String ID = "046b6c7f-0b8a-43b9-b35d-6489e6daee91";
private static final String TEST_CA_CERTIFICATE
= "/certificates/fakestmtpmekint02.pem";
private static final String TEST_ROOT_CA_CERTIFICATE
= "/certificates/fakeCA.pem";
private static final String ISSUED_CLIENT_CERT
= "/certificates/sample_identity_cert.cer";
private static final String TEST_ENDORSEMENT_CREDENTIAL
= "/endorsement_credentials/tpmcert.pem";
private static final String TEST_PLATFORM_CREDENTIAL
= "/platform_credentials/Intel_pc.cer";
private static final String TEST_PLATFORM_CREDENTIAL_2
= "/platform_credentials/basic_plat_cert_2-0.pem";
private static final String TEST_PLATFORM_CREDENTIAL_2_PCI
= "/platform_credentials/pciids_plat_cert_2-0.pem";
/**
* Constructor providing the Page's display and routing specification.
*/
public CertificateDetailsPageControllerTest() {
super(Page.CERTIFICATE_DETAILS);
pagePath = getPagePath();
}
/**
* Prepares tests.
*
* @throws IOException if test resources are not found
*/
@BeforeAll
public void prepareTests() throws IOException {
// Fake device to store in db for test
Device device;
Security.addProvider(new BouncyCastleProvider());
// list of platformCredentials that have been saved in the db
List<PlatformCredential> platformCredentialsList = new LinkedList<>();
// Create new device to be used in test and save it to db
device = new Device("Test Device", null, HealthStatus.TRUSTED, AppraisalStatus.Status.PASS,
null, false, "tmp_overrideReason", "tmp_summId");
device = deviceRepository.save(device);
//Upload and save EK Cert
endorsementCredential = (EndorsementCredential)
getTestCertificate(
EndorsementCredential.class,
TEST_ENDORSEMENT_CREDENTIAL);
certificateRepository.save(endorsementCredential);
//Upload and save CA Cert
caCertificate = (CertificateAuthorityCredential)
getTestCertificate(
CertificateAuthorityCredential.class,
TEST_CA_CERTIFICATE);
certificateRepository.save(caCertificate);
//Upload and save root Cert
caRootCertificate = (CertificateAuthorityCredential)
getTestCertificate(
CertificateAuthorityCredential.class,
TEST_ROOT_CA_CERTIFICATE);
certificateRepository.save(caRootCertificate);
//Upload and save Platform Cert, add it to platformCredentials list
platformCredential = (PlatformCredential)
getTestCertificate(
PlatformCredential.class,
TEST_PLATFORM_CREDENTIAL);
certificateRepository.save(platformCredential);
platformCredentialsList.add(platformCredential);
//Upload and save Platform Cert 2.0, add it to platformCredentials list
platformCredential2 = (PlatformCredential)
getTestCertificate(
PlatformCredential.class,
TEST_PLATFORM_CREDENTIAL_2);
certificateRepository.save(platformCredential2);
platformCredentialsList.add(platformCredential);
//Upload and save Platform Cert 2.0 PCI, add it to platformCredentials list
platformCertificatePCI = (PlatformCredential)
getTestCertificate(
PlatformCredential.class,
TEST_PLATFORM_CREDENTIAL_2_PCI);
certificateRepository.save(platformCertificatePCI);
platformCredentialsList.add(platformCertificatePCI);
//Upload and save Issued Attestation Cert
issuedCredential = (IssuedAttestationCertificate)
getTestCertificate(
IssuedAttestationCertificate.class,
ISSUED_CLIENT_CERT,
endorsementCredential,
platformCredentialsList);
issuedCredential.setDeviceId(device.getId());
certificateRepository.save(issuedCredential);
}
/**
* Tests initial page when the certificate was not found
* (uses ID that doesn't correspond to anything).
*
* @throws Exception if an exception occurs
*/
@Test
public void testInitPage() throws Exception {
// Get error message
getMockMvc()
.perform(MockMvcRequestBuilders.get(pagePath)
.param("id", ID)
.param("type", "certificateauthority"))
.andExpect(status().isOk())
.andExpect(model().attribute(PageController.MESSAGES_ATTRIBUTE, hasProperty("error",
hasItem("Unable to find certificate with ID: " + ID))))
.andReturn();
}
/**
* Tests initial page when invalid type.
*
* @throws Exception if an exception occurs
*/
@Test
public void testInitPageInvalidType() throws Exception {
// Get error message
getMockMvc()
.perform(MockMvcRequestBuilders.get(pagePath)
.param("id", ID)
.param("type", "invalid"))
.andExpect(status().isOk())
.andExpect(model().attribute(PageController.MESSAGES_ATTRIBUTE, hasProperty("error",
hasItem("Invalid certificate type: invalid"))))
.andReturn();
}
/**
* Tests initial page when missing a parameter.
*
* @throws Exception if an exception occurs
*/
@Test
public void testInitPageMissingParam() throws Exception {
// Get error message
getMockMvc()
.perform(MockMvcRequestBuilders.get(pagePath)
.param("id", ID))
.andExpect(status().isOk())
.andExpect(model().attribute(PageController.MESSAGES_ATTRIBUTE, hasProperty("error",
hasItem("Type was not provided"))))
.andReturn();
}
/**
* Tests initial page when the certificate type is
* a Certificate Authority.
*
* @throws Exception if an exception occurs
*/
@Test
@Rollback
@SuppressWarnings("unchecked")
public void testInitPageCertificateAuthority() throws Exception {
MvcResult result = getMockMvc()
.perform(MockMvcRequestBuilders.get(pagePath)
.param("id", caCertificate.getId().toString())
.param("type", "certificateauthority"))
.andExpect(status().isOk())
.andExpect(model().attributeExists(PolicyPageController.INITIAL_DATA))
.andReturn();
// Obtain initialData HashMap
Map<String, String> initialData = (Map<String, String>) result
.getModelAndView()
.getModel()
.get(PolicyPageController.INITIAL_DATA);
assertEquals(caCertificate.getIssuer(), initialData.get("issuer"));
}
/**
* Tests initial page when the certificate type is
* a Platform Certificate.
*
* @throws Exception if an exception occurs
*/
@Test
@Rollback
@SuppressWarnings("unchecked")
public void testInitPagePlatform() throws Exception {
MvcResult result = getMockMvc()
.perform(MockMvcRequestBuilders.get(pagePath)
.param("id", platformCredential.getId().toString())
.param("type", "platform"))
.andExpect(status().isOk())
.andExpect(model().attributeExists(PolicyPageController.INITIAL_DATA))
.andReturn();
// Obtain initialData HashMap
Map<String, String> initialData = (Map<String, String>) result
.getModelAndView()
.getModel()
.get(PolicyPageController.INITIAL_DATA);
assertEquals(platformCredential.getIssuer(), initialData.get("issuer"));
assertEquals(((PlatformCredential) platformCredential).getCredentialType(),
initialData.get("credentialType"));
}
/**
* Tests initial page when the certificate type is
* a Platform Certificate 2.0.
*
* @throws Exception if an exception occurs
*/
@Test
@Rollback
@SuppressWarnings("unchecked")
public void testInitPagePlatform20() throws Exception {
MvcResult result = getMockMvc()
.perform(MockMvcRequestBuilders.get(pagePath)
.param("id", platformCredential2.getId().toString())
.param("type", "platform"))
.andExpect(status().isOk())
.andExpect(model().attributeExists(PolicyPageController.INITIAL_DATA))
.andReturn();
// Obtain initialData HashMap
Map<String, Object> initialData = (Map<String, Object>) result
.getModelAndView()
.getModel()
.get(PolicyPageController.INITIAL_DATA);
assertEquals(platformCredential2.getIssuer(), initialData.get("issuer"));
assertEquals(((PlatformCredential) platformCredential2).getCredentialType(),
initialData.get("credentialType"));
// Check component identifier
assertNotNull(initialData.get("componentsIdentifier"));
List<?> obj = (List<?>) initialData.get("componentsIdentifier");
assertEquals(7, obj.size());
// Check platform properties
assertNotNull(initialData.get("platformProperties"));
obj = (List<?>) initialData.get("platformProperties");
assertEquals(2, obj.size());
}
/**
* Tests initial page when the certificate type is
* a Platform Certificate 2.0 with PCI IDs.
*
* @throws Exception if an exception occurs
*/
@Test
@Rollback
@SuppressWarnings("unchecked")
public void testInitPagePlatform20PCI() throws Exception {
MvcResult result = getMockMvc()
.perform(MockMvcRequestBuilders.get(pagePath)
.param("id", platformCertificatePCI.getId().toString())
.param("type", "platform"))
.andExpect(status().isOk())
.andExpect(model().attributeExists(PolicyPageController.INITIAL_DATA))
.andReturn();
// Obtain initialData HashMap
Map<String, Object> initialData = (Map<String, Object>) result
.getModelAndView()
.getModel()
.get(PolicyPageController.INITIAL_DATA);
assertEquals(platformCertificatePCI.getIssuer(), initialData.get("issuer"));
assertEquals(((PlatformCredential) platformCertificatePCI).getCredentialType(),
initialData.get("credentialType"));
// Check component identifier
assertNotNull(initialData.get("componentsIdentifier"));
List<?> obj = (List<?>) initialData.get("componentsIdentifier");
assertEquals(14, obj.size());
// Check platform properties
assertNotNull(initialData.get("platformProperties"));
obj = (List<?>) initialData.get("platformProperties");
assertEquals(0, obj.size());
}
/**
* Tests initial page when the certificate type is
* an Endorsement Certificate.
*
* @throws Exception if an exception occurs
*/
@Test
@Rollback
@SuppressWarnings("unchecked")
public void testInitPageEndorsement() throws Exception {
MvcResult result = getMockMvc()
.perform(MockMvcRequestBuilders.get(pagePath)
.param("id", endorsementCredential.getId().toString())
.param("type", "endorsement"))
.andExpect(status().isOk())
.andExpect(model().attributeExists(PolicyPageController.INITIAL_DATA))
.andReturn();
// Obtain initialData HashMap
Map<String, String> initialData = (Map<String, String>) result
.getModelAndView()
.getModel()
.get(PolicyPageController.INITIAL_DATA);
assertEquals(endorsementCredential.getIssuer(), initialData.get("issuer"));
assertEquals(((EndorsementCredential) endorsementCredential).getManufacturer(),
initialData.get("manufacturer"));
}
/**
* Tests initial page for issuer ID.
*
* @throws Exception if an exception occurs
*/
@Test
@Rollback
@SuppressWarnings("unchecked")
public void testInitPageID() throws Exception {
// use mock MVC to access a cert from Certificate Details Page path;
// send it some parameters, including the ID of the cert you want, and
// a type (which is different than the credential type);
// check that the certificate details Model attributes exist,
// and return the MVC data call into a result object
MvcResult result = getMockMvc()
.perform(MockMvcRequestBuilders.get(pagePath)
.param("id", caCertificate.getId().toString())
.param("type", "certificateauthority"))
.andExpect(model().attributeExists(
CertificateDetailsPageController.INITIAL_DATA))
.andReturn();
// Obtain initialData HashMap
Map<String, String> initialData = (Map<String, String>) result
.getModelAndView()
.getModel()
.get(PolicyPageController.INITIAL_DATA);
assertEquals(caCertificate.getIssuer(), initialData.get("issuer"));
assertEquals(caRootCertificate.getId().toString(),
initialData.get("issuerID"));
}
/**
* Tests initial page when the certificate type is
* an Issued Attestation Certificate.
*
* @throws Exception if an exception occurs
*/
@Test
@Rollback
@SuppressWarnings("unchecked")
public void testInitPageIssuedAttestation() throws Exception {
MvcResult result = getMockMvc()
.perform(MockMvcRequestBuilders.get(pagePath)
.param("id", issuedCredential.getId().toString())
.param("type", "issued"))
.andExpect(status().isOk())
.andExpect(model().attributeExists(PolicyPageController.INITIAL_DATA))
.andReturn();
// Obtain initialData HashMap
Map<String, String> initialData = (Map<String, String>) result
.getModelAndView()
.getModel()
.get(PolicyPageController.INITIAL_DATA);
assertEquals(issuedCredential.getIssuer(), initialData.get("issuer"));
assertEquals(issuedCredential.getEndorsementCredential().getId().toString(),
initialData.get("endorsementID"));
}
}

View File

@ -2,38 +2,40 @@ package hirs.attestationca.portal.page.controllers;
import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.manager.DeviceRepository;
import hirs.attestationca.persist.entity.userdefined.Certificate;
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
import hirs.attestationca.persist.entity.userdefined.Device;
import hirs.attestationca.persist.enums.AppraisalStatus;
import hirs.attestationca.persist.enums.HealthStatus;
import hirs.attestationca.portal.page.PageControllerTest;
import hirs.attestationca.persist.entity.userdefined.Device;
import static hirs.attestationca.portal.page.Page.DEVICES;
import java.io.IOException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import static hirs.attestationca.portal.page.Page.DEVICES;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
/**
* Integration tests that test the URL End Points of DevicePageController.
*/
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class DevicePageControllerTest extends PageControllerTest {
/**
* Name of device
*/
private static final String DEVICE_NAME = "Test Device";
// Base path for the page
private String pagePath;
/**
* Location of test credentials for device
*/
// Repository manager to handle data access between device entity and data storage in db
@Autowired
private DeviceRepository deviceRepository;
// Repository manager to handle data access between certificate entity and data storage in db
@Autowired
private CertificateRepository certificateRepository;
// Location of test certs
private static final String TEST_ENDORSEMENT_CREDENTIAL
= "/endorsement_credentials/tpmcert.pem";
private static final String TEST_ENDORSEMENT_CREDENTIAL_2
@ -41,44 +43,34 @@ public class DevicePageControllerTest extends PageControllerTest {
private static final String TEST_PLATFORM_CREDENTIAL
= "/platform_credentials/Intel_pc.cer";
/**
* Device object to be stored in db for test
*/
private Device device;
/**
* Repository manager to handle data access between device entity and data storage (db).
*/
@Autowired
private DeviceRepository deviceRepository;
/**
* Repository manager to handle data access between certificate entity and data storage (db).
*/
@Autowired
private CertificateRepository certificateRepository;
/**
* Constructor providing the Page's display and routing specification.
*/
public DevicePageControllerTest() { super(DEVICES); }
public DevicePageControllerTest() {
super(DEVICES);
pagePath = getPagePath();
}
/**
* Prepares a testing environment.
* @throws IOException if there is a problem constructing the test certificate
*/
@BeforeAll
public void beforeMethod() throws IOException {
public void prepareTests() throws IOException {
// Fake device to store in db for test
Device device;
// Create new device to be used in test and save it to db
device = new Device(DEVICE_NAME,null, HealthStatus.TRUSTED, AppraisalStatus.Status.PASS,
device = new Device("Test Device",null, HealthStatus.TRUSTED, AppraisalStatus.Status.PASS,
null,false,"tmp_overrideReason", "tmp_summId");
device = deviceRepository.save(device);
// Upload and save EK Cert
EndorsementCredential ec = (EndorsementCredential)
getTestCertificate(EndorsementCredential.class,
TEST_ENDORSEMENT_CREDENTIAL);
getTestCertificate(EndorsementCredential.class,
TEST_ENDORSEMENT_CREDENTIAL);
ec.setDeviceId(device.getId());
certificateRepository.save(ec);
@ -95,60 +87,19 @@ public class DevicePageControllerTest extends PageControllerTest {
}
/**
* Construct a test certificate from the given parameters.
* @param <T> the type of Certificate that will be created
* @param certificateClass the class of certificate to generate
* @param filename the location of the certificate to be used
* @return the newly-constructed Certificate
* @throws IOException if there is a problem constructing the test certificate
*/
public <T extends Certificate> Certificate getTestCertificate(
final Class<T> certificateClass,
final String filename)
throws IOException {
Path fPath;
try {
fPath = Paths.get(this.getClass().getResource(filename).toURI());
} catch (URISyntaxException e) {
throw new IOException("Could not resolve path URI", e);
}
switch (certificateClass.getSimpleName()) {
case "EndorsementCredential":
return new EndorsementCredential(fPath);
case "PlatformCredential":
return new PlatformCredential(fPath);
default:
throw new IllegalArgumentException(
String.format("Unknown certificate class %s", certificateClass.getName())
);
}
}
/**
* Tests retrieving the device list using a mocked device manager.
* Tests retrieving the device list using a mocked device repository.
*
* @throws Exception if test fails
*/
@Test
public void getDeviceList() throws Exception {
// Add pre-prefix and prefix path for page verification
String pagePath = "/" + getPrePrefixPath() + getPage().getPrefixPath() + getPage().getViewName() + "/list";
if (getPage().getPrefixPath() == null) {
pagePath = "/" + getPrePrefixPath() + getPage().getViewName() + "/list";
}
// perform test
getMockMvc()
.perform(MockMvcRequestBuilders.get(pagePath))
.perform(MockMvcRequestBuilders.get(pagePath + "/list"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data", hasSize(1)))
.andReturn()
;
.andReturn();
}
}
}

View File

@ -0,0 +1,156 @@
package hirs.attestationca.portal.page.controllers;
import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.manager.EndorsementCredentialRepository;
import hirs.attestationca.persist.entity.userdefined.Certificate;
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
import hirs.attestationca.portal.page.PageControllerTest;
import hirs.attestationca.portal.page.PageMessages;
import java.io.IOException;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.web.servlet.FlashMap;
import static hirs.attestationca.portal.page.Page.ENDORSEMENT_KEY_CREDENTIALS;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.annotation.DirtiesContext.MethodMode.BEFORE_METHOD;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Integration tests that test the URL End Points of EndorsementKeyCredentialsPageController.
*/
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class EndorsementKeyCredentialsPageControllerTest extends PageControllerTest {
// Base path for the page
private String pagePath;
// Repository manager to handle data access between certificate entity and data storage in db
@Autowired
private CertificateRepository certificateRepository;
// Repository manager to handle data access between endorsement certificate entity and data storage in db
@Autowired
private EndorsementCredentialRepository endorsementCredentialRepository;
// Location of test certs
private static final String EKCERT = "certificates/fakeIntelIntermediateCA.pem";
private static final String BADEKCERT = "certificates/badCert.pem";
// 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.
private MockMultipartFile nonEkCertFile;
// A file that is not a cert at all, and just contains garbage text.
private MockMultipartFile badCertFile;
/**
* Constructor providing the Page's display and routing specification.
*/
public EndorsementKeyCredentialsPageControllerTest() {
super(ENDORSEMENT_KEY_CREDENTIALS);
pagePath = getPagePath();
}
/**
* Prepares tests.
* @throws IOException if test resources are not found
*/
@BeforeAll
public void prepareTests() throws IOException {
// create a multi part file for the controller upload
String[] pathTokens = EKCERT.split("/");
nonEkCertFile = new MockMultipartFile("file", pathTokens[1], "",
new ClassPathResource(EKCERT).getInputStream());
pathTokens = BADEKCERT.split("/");
badCertFile = new MockMultipartFile("file", pathTokens[1], "",
new ClassPathResource(BADEKCERT).getInputStream());
}
/**
* Tests uploading a cert that is not an Endorsement Credential. Eventually, this
* should indicate a failure, but for now, EndorsementCredential just parses it as a
* generic credential successfully.
* @throws Exception if an exception occurs
*/
@Test
@Rollback
public void uploadAndArchiveNonEndorsementCert() throws Exception {
String[] pathTokens = EKCERT.split("/");
// perform upload. Attach csv file and add HTTP parameters for the baseline name and type.
MvcResult result = getMockMvc().perform(MockMvcRequestBuilders
.multipart(pagePath + "/upload")
.file(nonEkCertFile))
.andExpect(status().is3xxRedirection())
.andReturn();
// verify redirection messages
FlashMap flashMap = result.getFlashMap();
PageMessages pageMessages = (PageMessages) flashMap.get("messages");
assertEquals("New certificate successfully uploaded (" + pathTokens[1] + "): ",
pageMessages.getSuccess().get(0));
assertEquals(0, pageMessages.getError().size());
// verify the cert was actually stored
List<EndorsementCredential> records =
endorsementCredentialRepository.findAll();
assertEquals(1, records.size());
// verify the cert is not yet archived
Certificate cert = records.iterator().next();
assertFalse(cert.isArchived());
// now, archive the record
getMockMvc().perform(MockMvcRequestBuilders
.post(pagePath + "/delete")
.param("id", cert.getId().toString()))
.andExpect(status().is3xxRedirection())
.andReturn();
records = endorsementCredentialRepository.findAll();
assertEquals(1, records.size());
// verify the cert is now archived
cert = records.iterator().next();
assertTrue(cert.isArchived());
}
/**
* Tests that uploading something that is not a cert at all results in an error returned
* to the web client.
* @throws Exception an exception occurs
*/
@Test
@Rollback
@DirtiesContext(methodMode = BEFORE_METHOD) // clear endorsement cert from db
public void uploadBadEndorsementCert() throws Exception {
// perform upload. Attach csv file and add HTTP parameters for the baseline name and type.
MvcResult result = getMockMvc().perform(MockMvcRequestBuilders
.multipart(pagePath + "/upload")
.file(badCertFile))
.andExpect(status().is3xxRedirection())
.andReturn();
// verify redirection messages
FlashMap flashMap = result.getFlashMap();
PageMessages pageMessages = (PageMessages) flashMap.get("messages");
assertEquals(1, pageMessages.getError().size());
assertEquals(0, pageMessages.getSuccess().size());
// verify the cert was not actually stored
List<EndorsementCredential> records =
endorsementCredentialRepository.findAll();
assertEquals(0, records.size());
}
}

View File

@ -0,0 +1,175 @@
package hirs.attestationca.portal.page.controllers;
import hirs.attestationca.persist.entity.manager.CertificateRepository;
import hirs.attestationca.persist.entity.manager.DeviceRepository;
import hirs.attestationca.persist.entity.userdefined.Device;
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.enums.AppraisalStatus;
import hirs.attestationca.persist.enums.HealthStatus;
import hirs.attestationca.portal.page.PageControllerTest;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import static hirs.attestationca.portal.page.Page.ISSUED_CERTIFICATES;
import static org.hamcrest.Matchers.hasSize;
//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
/**
* Integration tests that test the URL End Points of IssuedCertificatesPageController.
*/
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class IssuedCertificatesPageControllerTest extends PageControllerTest {
// Base path for the page
private String pagePath;
// Fake device to store in db for test
private Device device;
// Repository manager to handle data access between device entity and data storage in db
@Autowired
private DeviceRepository deviceRepository;
// Repository manager to handle data access between certificate entity and data storage in db
@Autowired
private CertificateRepository certificateRepository;
// Location of test certs
private static final String TEST_ENDORSEMENT_CREDENTIAL
= "/endorsement_credentials/tpmcert.pem";
private static final String TEST_PLATFORM_CREDENTIAL
= "/platform_credentials/Intel_pc.cer";
private static final String TEST_PLATFORM_CREDENTIAL_2
= "/platform_credentials/Intel_pc2.pem";
private static final String ISSUED_CLIENT_CERT
= "/certificates/sample_identity_cert.cer";
// Certs objects
private List<PlatformCredential> platformCredentialList;
private IssuedAttestationCertificate issued;
/**
* Constructor providing the Page's display and routing specification.
*/
public IssuedCertificatesPageControllerTest() {
super(ISSUED_CERTIFICATES);
pagePath = getPagePath();
}
/**
* Prepares a testing environment.
* @throws IOException if there is a problem constructing the test certificate
*/
@BeforeAll
public void beforeMethod() throws IOException {
// Create new device to be used in test and save it to db
device = new Device("Test Device",null, HealthStatus.TRUSTED, AppraisalStatus.Status.PASS,
null,false,"temp", "temp");
device = deviceRepository.save(device);
// Upload and save EK Cert
EndorsementCredential ec = (EndorsementCredential)
getTestCertificate(
EndorsementCredential.class,
TEST_ENDORSEMENT_CREDENTIAL,
null,
null);
ec.setDeviceId(device.getId());
certificateRepository.save(ec);
//Set up multi-platform cert Attestation Cert
platformCredentialList = new LinkedList<>();
//Upload and save Platform Cert, add it to platformCredentials list
PlatformCredential pc = (PlatformCredential)
getTestCertificate(
PlatformCredential.class,
TEST_PLATFORM_CREDENTIAL,
null,
null);
pc.setDeviceId(device.getId());
certificateRepository.save(pc);
platformCredentialList.add(pc);
//Upload and save a second Platform Cert, add it to platformCredentials list
pc = (PlatformCredential)
getTestCertificate(
PlatformCredential.class,
TEST_PLATFORM_CREDENTIAL_2,
null,
null);
pc.setDeviceId(device.getId());
certificateRepository.save(pc);
platformCredentialList.add(pc);
//Upload and save Issued Attestation Cert
issued = (IssuedAttestationCertificate)
getTestCertificate(
IssuedAttestationCertificate.class,
ISSUED_CLIENT_CERT,
ec,
platformCredentialList);
issued.setDeviceId(device.getId());
certificateRepository.save(issued);
}
/**
* Tests retrieving the issued-certificates list using a mocked certificate repository.
*
* @throws Exception if test fails
*/
@Test
@Rollback
public void getDeviceList() throws Exception {
// perform test
getMockMvc().perform(MockMvcRequestBuilders.get(pagePath + "/list"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data", hasSize(1)))
.andExpect(jsonPath("$.data[0].platformCredentials",
hasSize(platformCredentialList.size())))
.andReturn();
}
/**
* Tests downloading the certificate.
* @throws Exception when getting raw report
*/
@Test
@Rollback
public void testDownloadCert() throws Exception {
StringBuilder fileName = new StringBuilder("attachment;filename=\"");
fileName.append("IssuedAttestationCertificate_");
fileName.append(issued.getSerialNumber());
fileName.append(".cer\"");
// verify cert file attachment and content
getMockMvc()
.perform(MockMvcRequestBuilders.get(
pagePath + "/download")
.param("id", issued.getId().toString())
)
.andExpect(status().isOk())
.andExpect(content().contentType("application/octet-stream"))
.andExpect(header().string("Content-Disposition",
fileName.toString()))
.andExpect(content().bytes(issued.getRawBytes()));
}
}

View File

@ -0,0 +1 @@
not a real cert. shouldn't be parsable as one.

View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDGDCCAgKgAwIBAgIBAjALBgkqhkiG9w0BAQswFzEVMBMGA1UEAwwMRmFrZSBS
b290IENBMB4XDTE3MDIwNDE2MTgyOVoXDTI3MDIwNDE2MTgyOVowJzElMCMGA1UE
AwwcRmFrZSBJbnRlbCBJbnRlcm1lZGlhdGUgQ0EgMTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAJazRiYf5J/QajAvSmUh+HYbBebXCaf7iIbYKEd1O0eF
qXGIbaWnNss53zyrBXos38fnIUl8NNFFywegnhtk2WgyF8fOgqwL0umr32Q1KMjS
bnDMwPqZFeWuDDt+JzxIz2GnI4JqqM/N/hWeEVqk4BzGeCCjFjuI5bypyvIWua3t
bV2Z4B36VHZ0pUz5wX3v86BLgRdHggBDpwPEMEp39A494X2k9YDuZdXjEsGf9i7a
yDoUBswOZfIubBweibXOd7slvR1utzPg5AfSfR6J8DPa9/hXmcQmezWroc6MX4TR
VJwv+Bv4g5rnPKxnYkEy5oEPgi+MqHYTpju0AhXqhysCAwEAAaNjMGEwDwYDVR0T
AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0OBBYEFLWs0BQDIqbT/Q7Z
dOWPEHF2opvqMB8GA1UdIwQYMBaAFFjsMToWmflMHIxOLGQSQCsljwF3MAsGCSqG
SIb3DQEBCwOCAQEAH5RkL203pAaKH03VtE0Fv3Hzv08M0aDBs7OcfNY8fNX38oPT
axdZ2hf9W5TyTfIMyfZde+Lo6C26LdfRT4YQE3h9O2TdCarU58FiYfRGf1n2QAHb
rMnItYpNRjDvqe0Om4jk2fUqzbVikDSS4Ca0yu86STO8+RIAKlro5dNyQ89GAMcj
LrtzDhQRxIhDQUUfH/brOqFulNx55Fbkd60eRAASIai7t4aWLIC7K/MKkC/Mn+aH
ayYbtXbHNEPsExkIN4i7wtsKklOoflBRPxHqe8iUd3MA3sYlh6kmVGGiElx8enUT
SQMwd2Eua7amb2mvpFhQ79BvzAarkIgFII2NXQ==
-----END CERTIFICATE-----

View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDjzCCAnmgAwIBAgIBBTALBgkqhkiG9w0BAQswFzEVMBMGA1UEAwwMRmFrZSBS
b290IENBMB4XDTExMDEyMTAwMDAwMFoXDTI5MTIzMTAwMDAwMFowVTELMAkGA1UE
BhMCQ0gxHjAcBgNVBAoTFVNUTWljcm9lbGVjdHJvbmljcyBOVjEmMCQGA1UEAxMd
U1RNIFRQTSBFSyBJbnRlcm1lZGlhdGUgQ0EgMDIwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQCTt4oZ/7h4Fdx65T2ab/PtfsYPXHC396VVyaE+Z/Dxx4sT
emUQZn/zYPOfzg2c8Z6LQuuFg/BhzC8kNAp2tzCRfjBiWeUeSZLiUQeArYEz8HE1
WSLArrqdGg1pz82Kh8L32og9hQ9GmsQp0yiI1lPTs7Uw9iOtcVtiyhGOFXXvltwu
1mYEuU6apG4Sc8tjSY+qEjAypJXyN1/I1X+254DHAkd19zXCKN+PSA7da9Rn8Afq
Fq4aIGVZzBSSgKEmD/GkKyw1Ze0kDgIE189iAw+m6NY4Gv/Cm+9nQ4fA9qq5Kloe
x8HWrN46qm2/boqujtnSSWPOhY3341z6N4xpRY07AgMBAAGjgaswgagwDwYDVR0T
AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAgQwRQYDVR0gAQH/BDswOTA3BgRVHSAA
MC8wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cuc3QuY29tL1RQTS9yZXBvc2l0b3J5
LzAdBgNVHQ4EFgQUVx+Aa0fM55v6NZR87Yi40QBa4J4wHwYDVR0jBBgwFoAUWOwx
OhaZ+UwcjE4sZBJAKyWPAXcwCwYJKoZIhvcNAQELA4IBAQB8IaDIWicxm7m2qyDv
v4L253D3qRcx+sdM2GM0IpvK3u9z3BQraAhF6PPLlgFGP6slZdDY6ryrP8PEkvsH
tHoapB1MWe+eMrxw7dXQLnpzm/P++8AWMtY8roziiO7x3AYTbRb9lB2HjOWc2aGZ
1xW+su+aTnr9U4uYO1+HrDDKYgkypIcousRwUMW6c6szAZY2UtWS2e4346V3LVLz
sv22n4rqWWRzJ2tl+jIqLepChqOdgscDL+aO2iowmzTSWV/WLJRaTs0AsOYJkdlG
8wWRzygRbfGdIL7A/hKK42o0b7v3R/NI0nemwAzVN/QOYjTbkOCIUBg/6mT8CkYx
pmiq
-----END CERTIFICATE-----

View File

@ -0,0 +1,42 @@
-----BEGIN ATTRIBUTE CERTIFICATE-----
MIIHVTCCBj0CAQEwgZWggZIwgYmkgYYwgYMxCzAJBgNVBAYTAkRFMSEwHwYDVQQK
DBhJbmZpbmVvbiBUZWNobm9sb2dpZXMgQUcxGjAYBgNVBAsMEU9QVElHQShUTSkg
VFBNMi4wMTUwMwYDVQQDDCxJbmZpbmVvbiBPUFRJR0EoVE0pIFJTQSBNYW51ZmFj
dHVyaW5nIENBIDAyMgIEewdr5KBaMFikVjBUMQswCQYDVQQGEwJVUzEUMBIGA1UE
CgwLRXhhbXBsZS5vcmcxDTALBgNVBAsMBHRlc3QxIDAeBgNVBAMMF1BsYXRmb3Jt
IENlcnRpZmljYXRlIENBMA0GCSqGSIb3DQEBCwUAAhRgKWfqeST97mzBULkeg3d9
H0J5mTAiGA8yMDE4MDEwMTE1NTM0NFoYDzIwMjUwMTAxMTU1MzQ0WjCCA5kwHAYF
Z4EFAhExEzARMAkCAQICAQACASsEBAAAAAEwFAYFZ4EFAhcxCzAJAgEBAgEAAgEL
MIHHBgVngQUCEzGBvTCBugIBAKB0FgMzLjEKAQcKAQIBAQCAAQGBBSoDBAUGoi0W
K2h0dHBzOi8vd3d3LmludGVsLmNvbS9wcm90ZWN0aW9ucHJvZmlsZS5wZGaDBSoD
BAUHpCQWImh0dHBzOi8vd3d3LmludGVsLmNvbS9jY3RhcmdldC5wZGahDRYFMTQw
LTIKAQQBAQCCAQMBAQAWKmh0dHBzOi8vd3d3LmludGVsLmNvbS9pc29jZXJ0aWZp
Y2F0aW9uLnBkZjAsBgZngQUFAQMxIjAgFh5odHRwczovL3d3dy5pbnRlbC5jb20v
UENScy54bWwwggJpBgdngQUFAQcBMYICXDCCAligggIHMDgMEUludGVsIENvcnBv
cmF0aW9uDAtPVVQgT0YgU1BFQ4AHKGJsYW5rKYEBMoIHKwYBBAGCV4MB/zBEDBFJ
bnRlbCBDb3Jwb3JhdGlvbgwJTlVDN2k1RE5CgAxCVERONzMyMDAwUU2BCko1NzYy
Ni00MDGCBysGAQQBgleDAf8wbQwUSW50ZWwoUikgQ29ycG9yYXRpb24MB0NvcmUg
aTWAFlRvIEJlIEZpbGxlZCBCeSBPLkUuTS6BKEludGVsKFIpIENvcmUoVE0pIGk1
LTczMDBVIENQVSBAIDIuNjBHSHqCBysGAQQBgleDAf8wQQwLSW50ZWwgQ29ycC4M
BEJJT1OBIEROS0JMaTV2Ljg2QS4wMDE5LjIwMTcuMDgwNC4xMTQ2ggcrBgEEAYJX
gwH/MHEMEUludGVsIENvcnBvcmF0aW9uDBtFdGhlcm5ldCBDb25uZWN0aW9uIEky
MTktTE2AEThjOjBmOjZmOjcyOmM2OmM1gQIyMYIHKwYBBAGCV4MB/6QcMBoGBWeB
BREBDBE4YzowZjo2Zjo3MjpjNjpjNTAtDAhLSU5HU1RPTgwMU0E0MDBTMzcxMjBH
gBA1MDAyNkI3Nzc4MDUyNzBCgwH/MDEMB1NhbXN1bmcMEE00NzFBNTE0M0VCMC1D
UEKACDk4NTBFQjJEggcrBgEEAYFsgwH/oRswDAwEdlBybwwEdHJ1ZTALDANBTVQM
BHRydWWiLhYsaHR0cHM6Ly93d3cuaW50ZWwuY29tL3BsYXRmb3JtcHJvcGVydGll
cy54bWwwggFcMGoGA1UdIARjMGEwXwYKKoZIhvhNAQUCBDBRMB8GCCsGAQUFBwIB
FhNodHRwczovL2V4YW1wbGUub3JnMC4GCCsGAQUFBwICMCIMIFRDRyBUcnVzdGVk
IFBsYXRmb3JtIEVuZG9yc2VtZW50MB8GA1UdIwQYMBaAFHAm0J7ZNdzcRNhNfadc
zwq8H94KMDYGCCsGAQUFBwEBBCowKDAmBggrBgEFBQcwAYYaaHR0cHM6Ly93d3cu
aW50ZWwuY29tL29jc3AwgZQGA1UdEQSBjDCBiaSBhjCBgzEdMBsGBmeBBQUBAQwR
SW50ZWwgQ29ycG9yYXRpb24xFTATBgZngQUFAQIwCQYHKwYBBAGCVzEWMBQGBmeB
BQUBBAwKTlVDN2k1RE5IRTEWMBQGBmeBBQUBBQwKSjcxNzM5LTQwMTEbMBkGBmeB
BQUBBgwPRFcxNjAwNDIwMzAwMTEwMA0GCSqGSIb3DQEBCwUAA4IBAQBdDVmlopIC
lt092SyqssVSHEZscNLb1C2bFmwJvlYX+8lzB1pI6wLEYccI3Vbz46g2k7dbb8ke
Ver126inffbm/3eJh+Dy4547xY3vijD0p0EZhLGW3hTnhkF91fD8VXYRSMJdCrJo
9MHE/kWTapmh9xidCGusCHlSG3v9OGvBuDEQhvnLKVLpR5ud9hqxccOr/VaB5gbo
16iW0ZD1U1l7bXkrRGqWWVK+TBKcnFy//mkhrEPed7+8gZUf/0G8MzXOPQvz55eH
3rSr8d1UQlv070uw9ly/pKp7blu1xJRnbjJmi8+NkPDRj6Hv4g8c5oVqkoHZJt3K
JLM5v9PY8uQn
-----END ATTRIBUTE CERTIFICATE-----

View File

@ -0,0 +1,37 @@
-----BEGIN ATTRIBUTE CERTIFICATE-----
MIIHuzCCBqMCAQEwc6BxMFmkVzBVMQswCQYDVQQGEwJDSDEeMBwGA1UEChMVU1RNaWNyb2VsZWN0
cm9uaWNzIE5WMSYwJAYDVQQDEx1TVE0gVFBNIEVLIEludGVybWVkaWF0ZSBDQSAwMgIUS5gujeW5
kYvYdMJZlIUT6s3F0cygOjA4pDYwNDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC2V4YW1wbGUuY29t
MQ8wDQYDVQQLDAZQQ1Rlc3QwDQYJKoZIhvcNAQELBQACAQEwIhgPMjAxODAxMDEwNTAwMDBaGA8y
MDI4MDEwMTA1MDAwMFowggRkMAsGBWeBBQITMQIwADAcBgVngQUCETETMBEwCQIBAQIBAwIBFgQE
AAAAATASBgVngQUCGTEJMAcGBWeBBQgCMIIECwYHZ4EFBQEHAjGCA/4wggP6oIID9DBbMA4GBmeB
BRIDAQQEAAIAAQwWVG8gQmUgRmlsbGVkIEJ5IE8uRS5NLgwBM4AWVG8gQmUgRmlsbGVkIEJ5IE8u
RS5NLoEWVG8gQmUgRmlsbGVkIEJ5IE8uRS5NLjAoMA4GBmeBBRIDAQQEAAMAAwwGQVNSb2NrDAtY
NTggRXh0cmVtZYMB/zBAMA4GBmeBBRIDAQQEABMAAwwYQW1lcmljYW4gTWVnYXRyZW5kcyBJbmMu
DA1Ob3QgU3BlY2lmaWVkgQVQMi45MDBoMA4GBmeBBRIDAQQEAAEAAgwFSW50ZWwMAzE5OIAWVG8g
QmUgRmlsbGVkIEJ5IE8uRS5NLoEvSW50ZWwoUikgQ29yZShUTSkgaTcgQ1BVICAgICAgICAgOTIw
ICBAIDIuNjdHSHqDAf8wSjAOBgZngQUSAwEEBAAGAAEMDk1hbnVmYWN0dXJlcjAwDA1PQ1ozRzE2
MDBMVjJHgAgwMDAwMDAwMIEMQXNzZXRUYWdOdW0wgwH/MEowDgYGZ4EFEgMBBAQABgABDA5NYW51
ZmFjdHVyZXIwMQwNT0NaM0cxNjAwTFYyR4AIMDAwMDAwMDCBDEFzc2V0VGFnTnVtMYMB/zBKMA4G
BmeBBRIDAQQEAAYAAQwOTWFudWZhY3R1cmVyMDIMDU5vdCBTcGVjaWZpZWSACDAwMDAwMDAwgQxB
c3NldFRhZ051bTKDAf8wSjAOBgZngQUSAwEEBAAGAAEMDk1hbnVmYWN0dXJlcjAzDA1PQ1ozRzE2
MDBMVjJHgAgwMDAwMDAwMIEMQXNzZXRUYWdOdW0zgwH/MEowDgYGZ4EFEgMBBAQABgABDA5NYW51
ZmFjdHVyZXIwNAwNT0NaM0cxNjAwTFYyR4AIMDAwMDAwMDCBDEFzc2V0VGFnTnVtNIMB/zBKMA4G
BmeBBRIDAQQEAAYAAQwOTWFudWZhY3R1cmVyMDUMDU5vdCBTcGVjaWZpZWSACDAwMDAwMDAwgQxB
c3NldFRhZ051bTWDAf8wSjAOBgZngQUSAwEEBAAJAAIMBDgwODYMBDI0RjOADEE0MzREOTEyMzQ1
NoECM0GDAf+kFzAVBgVngQURAgwMQTQzNEQ5MTIzNDU2MEowDgYGZ4EFEgMBBAQACQACDAQxMEVD
DAQ4MTY4gAwwMDE5NjZBQkNERUaBAjAzgwH/pBcwFQYFZ4EFEQEMDDAwMTk2NkFCQ0RFRjA6MA4G
BmeBBRIDAQQEAAcAAgwNTm90IFNwZWNpZmllZAwMU1QzMTUwMDM0MUFTgAg4WDY4WTMyMIMB/zAj
MA4GBmeBBRIDAQQEAAUAAgwEMTAwMgwENjg5OYECMDCDAf+iADAUBgVngQUCFzELMAkCAQECAQEC
AREwggFNMGQGA1UdIwRdMFuAFGQP4SIG+UWEJp5BdqBD3dUDaRgOoTikNjA0MQswCQYDVQQGEwJV
UzEUMBIGA1UECgwLZXhhbXBsZS5jb20xDzANBgNVBAsMBlBDVGVzdIIJAISFLMl6DJA8MEEGA1Ud
IAQ6MDgwNgYCKgMwMDAuBggrBgEFBQcCAjAiDCBUQ0cgVHJ1c3RlZCBQbGF0Zm9ybSBFbmRvcnNl
bWVudDCBoQYDVR0RBIGZMIGWpIGTMIGQMSIwIAYGZ4EFBQEEDBZUbyBCZSBGaWxsZWQgQnkgTy5F
Lk0uMSIwIAYGZ4EFBQEBDBZUbyBCZSBGaWxsZWQgQnkgTy5FLk0uMSIwIAYGZ4EFBQEFDBZUbyBC
ZSBGaWxsZWQgQnkgTy5FLk0uMSIwIAYGZ4EFBQEGDBZUbyBCZSBGaWxsZWQgQnkgTy5FLk0uMA0G
CSqGSIb3DQEBCwUAA4IBAQCiJcOtpVn43jbGkEhNq0rfdtnvnn9/N99eNeYO2+jGbKOQDkC1TxYO
QXgaWl32KVc9q044KX4062tt2cQHIwFDK7dPLAaUkCJ8x7mjg7Np7ddzqWHtkAyr+USntdjf0o/z
8Ru5aUSVBA0sphpRN66nVU8sGKSf31CZhSBMpBCToKyil+eFUF3n6X2Z9fjhzermoPVNqkff7/Ai
cldsbnTb46CGdQSWhctw7sbyy9B9VTYbqDMfMQdpifl2JQBkXaC7XPe9Z6J8VJVWiTh91be5JSAd
Uyq5/X2IajIEGp8OP+zQSaStT2RaoeN1VdmPGrv87YbUs9buKTpTSYNZwI2d
-----END ATTRIBUTE CERTIFICATE-----