From a8e2c5cc6ec07e224fe1079dc3adaf1b69c57812 Mon Sep 17 00:00:00 2001 From: Cyrus <24922493+cyrus-dev@users.noreply.github.com> Date: Mon, 24 Jun 2019 13:01:32 -0400 Subject: [PATCH] [#163] Delta issuer validation (#164) * This code change will add in the delta certficates to the platform validation check. The current base passes the policy check as long as the base is valid. The deltas are ignored. This is because the validation pulls in what is associated with a particular EK associated with the machine provisioning. --- .../SupplyChainValidationServiceImpl.java | 82 ++++++++++++++----- .../SupplyChainValidationServiceImplTest.java | 1 + .../CertificateDetailsPageControllerTest.java | 80 +++++++++--------- .../certificate/PlatformCredential.java | 2 +- 4 files changed, 102 insertions(+), 63 deletions(-) diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java index 0439ab9d..4feba80d 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -18,7 +18,6 @@ import java.util.List; import java.util.Set; import java.util.Comparator; import java.util.LinkedList; -import java.util.Map; import java.util.stream.Collectors; import java.util.HashMap; import org.apache.logging.log4j.Level; @@ -106,7 +105,7 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe HashMap credentialMap = new HashMap<>(); PlatformCredential baseCredential = null; List validations = new LinkedList<>(); - Map multiBaseCheckMap = new HashMap<>(); + List deltaValidations = new LinkedList<>(); // validate all supply chain pieces. Potentially, a policy setting could be made // to dictate stopping after the first validation failure. @@ -141,28 +140,13 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe // check if this cert has been verified for multiple base associated // with the serial number if (pc != null) { - boolean checked = multiBaseCheckMap.containsKey(pc.getPlatformSerial()); - if (!checked) { - // if not checked, update the map - boolean result = checkForMultipleBaseCredentials( - pc.getPlatformSerial()); - multiBaseCheckMap.put(pc.getPlatformSerial(), result); - // if it is, then update the SupplyChainValidation message and result - if (result) { - String message = "Multiple Base certificates found in chain."; - if (!platformScv.getResult() - .equals(AppraisalStatus.Status.PASS)) { - message = String.format("%s,%n%s", - platformScv.getMessage(), message); - } - platformScv = buildValidationRecord( - SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, - AppraisalStatus.Status.FAIL, - message, pc, Level.ERROR); - } - } + platformScv = validatePcPolicy(pc, platformScv, + deltaValidations, acceptExpiredCerts); } validations.add(platformScv); + if (!deltaValidations.isEmpty()) { + validations.addAll(deltaValidations); + } if (pc != null) { pc.setDevice(device); this.certificateManager.update(pc); @@ -248,6 +232,60 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe return summary; } + /** + * This method is a sub set of the validate supply chain method and focuses on the specific + * multibase validation check for a delta chain. This method also includes the check + * for delta certificate CA validation as well. + * + * @param pc The platform credential getting checked + * @param platformScv The validation record + * @return The validation record + */ + private SupplyChainValidation validatePcPolicy( + final PlatformCredential pc, + final SupplyChainValidation platformScv, + final List deltaValidations, + final boolean acceptExpiredCerts) { + SupplyChainValidation subPlatformScv = platformScv; + + if (pc != null) { + // if not checked, update the map + boolean result = checkForMultipleBaseCredentials( + pc.getPlatformSerial()); + // if it is, then update the SupplyChainValidation message and result + if (result) { + String message = "Multiple Base certificates found in chain."; + if (!platformScv.getResult().equals(AppraisalStatus.Status.PASS)) { + message = String.format("%s,%n%s", platformScv.getMessage(), message); + } + subPlatformScv = buildValidationRecord( + SupplyChainValidation.ValidationType.PLATFORM_CREDENTIAL, + AppraisalStatus.Status.FAIL, + message, pc, Level.ERROR); + } + } + + // Grab all certs associated with this platform chain + List chainCertificates = PlatformCredential + .select(certificateManager) + .byBoardSerialNumber(pc.getPlatformSerial()) + .getCertificates().stream().collect(Collectors.toList()); + + SupplyChainValidation deltaScv; + KeyStore trustedCa; + // verify that the deltas trust chain is valid. + for (PlatformCredential delta : chainCertificates) { + if (delta != null && !delta.isBase()) { + trustedCa = getCaChain(delta); + deltaScv = validatePlatformCredential( + delta, trustedCa, acceptExpiredCerts); + deltaValidations.add(deltaScv); + } + } + + return subPlatformScv; + } + private SupplyChainValidation validateEndorsementCredential(final EndorsementCredential ec, final boolean acceptExpiredCerts) { final SupplyChainValidation.ValidationType validationType diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/service/SupplyChainValidationServiceImplTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/service/SupplyChainValidationServiceImplTest.java index aacad0b3..5b2633b5 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/service/SupplyChainValidationServiceImplTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/service/SupplyChainValidationServiceImplTest.java @@ -130,6 +130,7 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest when(pc.getId()).thenReturn(UUID.randomUUID()); when(pc.getX509Certificate()).thenReturn(cert); when(pc.getSerialNumber()).thenReturn(BigInteger.ONE); + when(pc.getPlatformSerial()).thenReturn(String.valueOf(Integer.MIN_VALUE)); when(pc.getIssuerOrganization()).thenReturn("STMicroelectronics NV"); when(ec.getSubjectOrganization()).thenReturn("STMicroelectronics NV"); pcs = new HashSet(); 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 be6d00ff..baff75ec 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 @@ -56,8 +56,8 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest { private CertificateAuthorityCredential caCertificate; private CertificateAuthorityCredential caRootCertificate; - private PlatformCredential platofrmCredential; - private PlatformCredential platofrmCredential2; + private PlatformCredential platformCredential; + private PlatformCredential platformCredential2; private EndorsementCredential endorsementCredential; private IssuedAttestationCertificate issuedCredential; @@ -93,7 +93,7 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest { Set pcCertSet = new HashSet<>(); - //Create new device grup + //Create new device group DeviceGroup group = new DeviceGroup("default"); group = deviceGroupManager.saveDeviceGroup(group); @@ -130,26 +130,26 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest { certificateManager.save(caRootCertificate); //Upload and save Platform Cert - platofrmCredential = (PlatformCredential) + platformCredential = (PlatformCredential) getTestCertificate( PlatformCredential.class, TEST_PLATFORM_CREDENTIAL, null, null); - certificateManager.save(platofrmCredential); + certificateManager.save(platformCredential); - pcCertSet.add(platofrmCredential); + pcCertSet.add(platformCredential); //Upload and save Platform Cert 2.0 - platofrmCredential2 = (PlatformCredential) + platformCredential2 = (PlatformCredential) getTestCertificate( PlatformCredential.class, TEST_PLATFORM_CREDENTIAL_2, null, null); - certificateManager.save(platofrmCredential2); + certificateManager.save(platformCredential2); - pcCertSet.add(platofrmCredential); + pcCertSet.add(platformCredential); //Upload and save Issued Attestation Cert issuedCredential = (IssuedAttestationCertificate) @@ -233,12 +233,12 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest { .andExpect(model().attributeExists(PolicyPageController.INITIAL_DATA)) .andReturn(); - // Obtain initalData HashMap - Map initalData = (Map) result + // Obtain initialData HashMap + Map initialData = (Map) result .getModelAndView() .getModel() .get(PolicyPageController.INITIAL_DATA); - Assert.assertEquals(initalData.get("issuer"), caCertificate.getIssuer()); + Assert.assertEquals(initialData.get("issuer"), caCertificate.getIssuer()); } @@ -254,20 +254,20 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest { MvcResult result = getMockMvc() .perform(MockMvcRequestBuilders.get("/" + getPage().getViewName()) - .param("id", platofrmCredential.getId().toString()) + .param("id", platformCredential.getId().toString()) .param("type", "platform")) .andExpect(status().isOk()) .andExpect(model().attributeExists(PolicyPageController.INITIAL_DATA)) .andReturn(); - // Obtain initalData HashMap - Map initalData = (Map) result + // Obtain initialData HashMap + Map initialData = (Map) result .getModelAndView() .getModel() .get(PolicyPageController.INITIAL_DATA); - Assert.assertEquals(initalData.get("issuer"), platofrmCredential.getIssuer()); - Assert.assertEquals(initalData.get("credentialType"), - ((PlatformCredential) platofrmCredential).getCredentialType()); + Assert.assertEquals(initialData.get("issuer"), platformCredential.getIssuer()); + Assert.assertEquals(initialData.get("credentialType"), + ((PlatformCredential) platformCredential).getCredentialType()); } @@ -283,28 +283,28 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest { MvcResult result = getMockMvc() .perform(MockMvcRequestBuilders.get("/" + getPage().getViewName()) - .param("id", platofrmCredential2.getId().toString()) + .param("id", platformCredential2.getId().toString()) .param("type", "platform")) .andExpect(status().isOk()) .andExpect(model().attributeExists(PolicyPageController.INITIAL_DATA)) .andReturn(); - // Obtain initalData HashMap - Map initalData = (Map) result + // Obtain initialData HashMap + Map initialData = (Map) result .getModelAndView() .getModel() .get(PolicyPageController.INITIAL_DATA); - Assert.assertEquals(initalData.get("issuer"), platofrmCredential2.getIssuer()); - Assert.assertEquals(initalData.get("credentialType"), - ((PlatformCredential) platofrmCredential2).getCredentialType()); + Assert.assertEquals(initialData.get("issuer"), platformCredential2.getIssuer()); + Assert.assertEquals(initialData.get("credentialType"), + ((PlatformCredential) platformCredential2).getCredentialType()); // Check component identifier - Assert.assertNotNull(initalData.get("componentsIdentifier")); - List obj = (List) initalData.get("componentsIdentifier"); + Assert.assertNotNull(initialData.get("componentsIdentifier")); + List obj = (List) initialData.get("componentsIdentifier"); Assert.assertEquals(obj.size(), 7); // Check platform properties - Assert.assertNotNull(initalData.get("platformProperties")); - obj = (List) initalData.get("platformProperties"); + Assert.assertNotNull(initialData.get("platformProperties")); + obj = (List) initialData.get("platformProperties"); Assert.assertEquals(obj.size(), 2); } @@ -327,13 +327,13 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest { .andExpect(model().attributeExists(PolicyPageController.INITIAL_DATA)) .andReturn(); - // Obtain initalData HashMap - Map initalData = (Map) result + // Obtain initialData HashMap + Map initialData = (Map) result .getModelAndView() .getModel() .get(PolicyPageController.INITIAL_DATA); - Assert.assertEquals(initalData.get("issuer"), endorsementCredential.getIssuer()); - Assert.assertEquals(initalData.get("manufacturer"), + Assert.assertEquals(initialData.get("issuer"), endorsementCredential.getIssuer()); + Assert.assertEquals(initialData.get("manufacturer"), ((EndorsementCredential) endorsementCredential).getManufacturer()); } @@ -355,14 +355,14 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest { .andReturn(); - // Obtain initalData HashMap - Map initalData = (Map) result + // Obtain initialData HashMap + Map initialData = (Map) result .getModelAndView() .getModel() .get(PolicyPageController.INITIAL_DATA); - Assert.assertEquals(initalData.get("issuer"), caCertificate.getIssuer()); - Assert.assertEquals(initalData.get("issuerID"), + Assert.assertEquals(initialData.get("issuer"), caCertificate.getIssuer()); + Assert.assertEquals(initialData.get("issuerID"), caRootCertificate.getId().toString()); } @@ -384,13 +384,13 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest { .andExpect(model().attributeExists(PolicyPageController.INITIAL_DATA)) .andReturn(); - // Obtain initalData HashMap - Map initalData = (Map) result + // Obtain initialData HashMap + Map initialData = (Map) result .getModelAndView() .getModel() .get(PolicyPageController.INITIAL_DATA); - Assert.assertEquals(initalData.get("issuer"), issuedCredential.getIssuer()); - Assert.assertEquals(initalData.get("endorsementID"), + Assert.assertEquals(initialData.get("issuer"), issuedCredential.getIssuer()); + Assert.assertEquals(initialData.get("endorsementID"), issuedCredential.getEndorsementCredential().getId().toString()); diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java index e73ff3ed..8a6a713f 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/PlatformCredential.java @@ -305,7 +305,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate { AttributeCertificate attCert = getAttributeCertificate(); AttributeCertificateInfo acinfo = getAttributeCertificate().getAcinfo(); - // Check if the algorith identifier is the same + // Check if the algorithm identifier is the same if (!isAlgIdEqual(acinfo.getSignature(), attCert.getSignatureAlgorithm())) { throw new IOException("signature invalid - algorithm identifier mismatch"); }