From 620982ee7207061d97693c001bdb98979ad97fc2 Mon Sep 17 00:00:00 2001 From: iadgovuser58 <124906646+iadgovuser58@users.noreply.github.com> Date: Thu, 25 Jan 2024 09:48:14 -0500 Subject: [PATCH 1/2] added 2 new unit tests --- HIRS_AttestationCA/build.gradle | 4 +- .../CredentialManagementHelperTest.java | 117 ++++++++++ .../IssuedCertificateAttributeHelperTest.java | 206 ++++++++++++++++++ 3 files changed, 325 insertions(+), 2 deletions(-) create mode 100644 HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelperTest.java create mode 100644 HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/IssuedCertificateAttributeHelperTest.java diff --git a/HIRS_AttestationCA/build.gradle b/HIRS_AttestationCA/build.gradle index 893997d90..30f6e4158 100644 --- a/HIRS_AttestationCA/build.gradle +++ b/HIRS_AttestationCA/build.gradle @@ -46,10 +46,10 @@ dependencies { implementation 'org.apache.logging.log4j:log4j-core:2.19.0' implementation 'org.apache.logging.log4j:log4j-api:2.19.0' + testImplementation 'org.apache.directory.studio:org.apache.commons.io:2.4' + testImplementation 'org.hamcrest:hamcrest:2.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.9.3' testImplementation 'org.junit.platform:junit-platform-launcher:1.9.3' - testImplementation 'org.hamcrest:hamcrest:2.2' - testImplementation 'org.mockito:mockito-core:4.2.0' // spring management diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelperTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelperTest.java new file mode 100644 index 000000000..07c99470f --- /dev/null +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/CredentialManagementHelperTest.java @@ -0,0 +1,117 @@ +package hirs.attestationca.persist.provision.helper; + +import hirs.attestationca.persist.entity.manager.CertificateRepository; +import hirs.attestationca.persist.entity.userdefined.Certificate; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.io.FileInputStream; +import java.io.IOException; + +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}. + */ +public class CredentialManagementHelperTest { + + @Mock + private CertificateRepository certificateRepository; + + 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"; + + /** + * Setup mocks. + */ + @BeforeEach + public void setUp() { + //certificateRepository = mock(CertificateRepository.class); + MockitoAnnotations.initMocks(this); + } + + /** + * 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, "testName")); + } + + /** + * Tests exception generated when providing an empty array of bytes as the EK. + */ + @Test + public void processEmptyEndorsementCredential() { + assertThrows(IllegalArgumentException.class, () -> + CredentialManagementHelper.storeEndorsementCredential(certificateRepository, new byte[0], "testName")); + } + + /** + * Tests processing an invalid EK (too small of an array). + */ + @Test + public void processInvalidEndorsementCredentialCase1() { + byte[] ekBytes = new byte[] {1}; + assertThrows(IllegalArgumentException.class, () -> + CredentialManagementHelper.storeEndorsementCredential(certificateRepository, ekBytes, "testName")); + } + + /** + * Tests processing an invalid EK (garbage bytes of a reasonable length). + */ + @Test + public void processInvalidEndorsementCredentialCase2() { + byte[] ekBytes = new byte[] {1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}; + assertThrows(IllegalArgumentException.class, () -> + CredentialManagementHelper.storeEndorsementCredential(certificateRepository, ekBytes, "testName")); + } + + /** + * Tests processing a valid EK with the 7 byte header in tact. + * @throws IOException if an IO error occurs + */ + @Test + public void parseUntouchedEndorsementCredential() throws IOException { + String path = CredentialManagementHelperTest.class.getResource(EK_UNTOUCHED).getPath(); + byte[] ekBytes = IOUtils.toByteArray(new FileInputStream(path)); + + CredentialManagementHelper.storeEndorsementCredential(certificateRepository, ekBytes, "testName"); + verify(certificateRepository).save(any(Certificate.class)); + } + + /** + * Tests processing a valid EK with the 7 byte header already stripped. + * @throws IOException if an IO error occurs + */ + @Test + public void parseHeaderTruncatedEndorsementCredential() throws IOException { + String path = CredentialManagementHelperTest.class.getResource(EK_HEADER_TRUNCATED) + .getPath(); + byte[] ekBytes = IOUtils.toByteArray(new FileInputStream(path)); + + CredentialManagementHelper.storeEndorsementCredential(certificateRepository, ekBytes, "testName"); + verify(certificateRepository).save(any(Certificate.class)); + } +} diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/IssuedCertificateAttributeHelperTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/IssuedCertificateAttributeHelperTest.java new file mode 100644 index 000000000..eb4710a95 --- /dev/null +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/persist/provision/helper/IssuedCertificateAttributeHelperTest.java @@ -0,0 +1,206 @@ +package hirs.attestationca.persist.provision.helper; + +import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential; +import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DLSequence; +import org.bouncycastle.asn1.x509.Extension; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * Tests for {@see IssuedCertificateAttributeHelper}. + */ +public class IssuedCertificateAttributeHelperTest { + + private static final String NUC1_EC = "/certificates/nuc-1/tpmcert.pem"; + + private static final String INTEL_PC = "/certificates/platform_certs_2/" + + "Intel_pc.pem"; + + private static final String TEST_HOSTNAME = "box1"; + + private static final String TPM_MANUFACTURER = "2.23.133.2.1"; + + private static final String TPM_MODEL = "2.23.133.2.2"; + + private static final String TPM_VERSION = "2.23.133.2.3"; + + private static final String TPM_ID_LABEL_OID = "2.23.133.2.15"; + + private static final String PLATFORM_MANUFACTURER = "2.23.133.2.4"; + + private static final String PLATFORM_MODEL = "2.23.133.2.5"; + + private static final String PLATFORM_VERSION = "2.23.133.2.6"; + + /** + * Test that provide a null host name and is rejected. + * @throws IOException an IO error occurs + */ + @Test + public void rejectNullHostName() throws IOException { + assertThrows(IllegalArgumentException.class, () -> + IssuedCertificateAttributeHelper.buildSubjectAlternativeNameFromCerts(null, null, "")); + } + + /** + * Test that subject alt name can be built without an EC or PC. + * @throws IOException an IO error occurs + */ + @Test + public void buildAttributesNoEndorsementNoPlatform() throws IOException { + Extension subjectAlternativeName = + IssuedCertificateAttributeHelper.buildSubjectAlternativeNameFromCerts( + null, new ArrayList(), TEST_HOSTNAME); + + Map subjectAlternativeNameAttrMap = getSubjectAlternativeNameAttributes( + subjectAlternativeName); + + assertNull(subjectAlternativeNameAttrMap.get(TPM_MANUFACTURER)); + assertNull(subjectAlternativeNameAttrMap.get(TPM_MODEL)); + assertNull(subjectAlternativeNameAttrMap.get(TPM_VERSION)); + assertNull(subjectAlternativeNameAttrMap.get(PLATFORM_MANUFACTURER)); + assertNull(subjectAlternativeNameAttrMap.get(PLATFORM_MODEL)); + assertNull(subjectAlternativeNameAttrMap.get(PLATFORM_VERSION)); + assertEquals(TEST_HOSTNAME, subjectAlternativeNameAttrMap.get(TPM_ID_LABEL_OID)); + } + + /** + * Test that subject alt name can be built with an EC but no PC. + * @throws IOException an IO error occurs + * @throws URISyntaxException unrecognized URI for EC Path + */ + @Test + public void buildAttributesEndorsementNoPlatform() throws IOException, URISyntaxException { + Path endorsementCredentialPath = Paths.get(getClass().getResource( + NUC1_EC).toURI()); + EndorsementCredential endorsementCredential = new EndorsementCredential( + endorsementCredentialPath); + Extension subjectAlternativeName = + IssuedCertificateAttributeHelper.buildSubjectAlternativeNameFromCerts( + endorsementCredential, new ArrayList(), TEST_HOSTNAME); + + Map subjectAlternativeNameAttrMap = getSubjectAlternativeNameAttributes( + subjectAlternativeName); + + assertEquals(endorsementCredential.getManufacturer(), + subjectAlternativeNameAttrMap.get(TPM_MANUFACTURER)); + assertEquals(endorsementCredential.getModel(), + subjectAlternativeNameAttrMap.get(TPM_MODEL)); + assertEquals(endorsementCredential.getVersion(), + subjectAlternativeNameAttrMap.get(TPM_VERSION)); + assertNull(subjectAlternativeNameAttrMap.get(PLATFORM_MANUFACTURER)); + assertNull(subjectAlternativeNameAttrMap.get(PLATFORM_MODEL)); + assertNull(subjectAlternativeNameAttrMap.get(PLATFORM_VERSION)); + assertEquals(subjectAlternativeNameAttrMap.get(TPM_ID_LABEL_OID), + TEST_HOSTNAME); + } + + /** + * Test that subject alt name can be built with an PC but no EC. + * @throws IOException an IO error occurs + * @throws URISyntaxException unrecognized URI for PC Path + */ + @Test + public void buildAttributesPlatformNoEndorsement() throws IOException, URISyntaxException { + Path platformCredentialPath = Paths.get(getClass().getResource( + INTEL_PC).toURI()); + PlatformCredential platformCredential = new PlatformCredential( + platformCredentialPath); + List platformCredentialList = new ArrayList<>(); + platformCredentialList.add(platformCredential); + Extension subjectAlternativeName = + IssuedCertificateAttributeHelper.buildSubjectAlternativeNameFromCerts( + null, platformCredentialList, TEST_HOSTNAME); + + Map subjectAlternativeNameAttrMap = getSubjectAlternativeNameAttributes( + subjectAlternativeName); + + assertNull(subjectAlternativeNameAttrMap.get(TPM_MANUFACTURER)); + assertNull(subjectAlternativeNameAttrMap.get(TPM_MODEL)); + assertNull(subjectAlternativeNameAttrMap.get(TPM_VERSION)); + assertEquals(platformCredential.getManufacturer(), + subjectAlternativeNameAttrMap.get(PLATFORM_MANUFACTURER)); + assertEquals(platformCredential.getModel(), + subjectAlternativeNameAttrMap.get(PLATFORM_MODEL)); + assertEquals(platformCredential.getVersion(), + subjectAlternativeNameAttrMap.get(PLATFORM_VERSION)); + assertEquals(TEST_HOSTNAME, + subjectAlternativeNameAttrMap.get(TPM_ID_LABEL_OID)); + } + + /** + * Test that subject alt name can be built with a PC and an EC. + * @throws IOException an IO error occurs + * @throws URISyntaxException unrecognized URI for EC or PC Path + */ + @Test + public void buildAttributesPlatformAndEndorsement() throws IOException, URISyntaxException { + Path endorsementCredentialPath = Paths.get(getClass().getResource( + NUC1_EC).toURI()); + Path platformCredentialPath = Paths.get(getClass().getResource( + INTEL_PC).toURI()); + EndorsementCredential endorsementCredential = new EndorsementCredential( + endorsementCredentialPath); + PlatformCredential platformCredential = new PlatformCredential( + platformCredentialPath); + List platformCredentialList = new ArrayList<>(); + platformCredentialList.add(platformCredential); + Extension subjectAlternativeName = + IssuedCertificateAttributeHelper.buildSubjectAlternativeNameFromCerts( + endorsementCredential, platformCredentialList, TEST_HOSTNAME); + + Map subjectAlternativeNameAttrMap = getSubjectAlternativeNameAttributes( + subjectAlternativeName); + + assertEquals(endorsementCredential.getManufacturer(), + subjectAlternativeNameAttrMap.get(TPM_MANUFACTURER)); + assertEquals(endorsementCredential.getModel(), + subjectAlternativeNameAttrMap.get(TPM_MODEL)); + assertEquals(endorsementCredential.getVersion(), + subjectAlternativeNameAttrMap.get(TPM_VERSION)); + assertEquals(platformCredential.getManufacturer(), + subjectAlternativeNameAttrMap.get(PLATFORM_MANUFACTURER)); + assertEquals(platformCredential.getModel(), + subjectAlternativeNameAttrMap.get(PLATFORM_MODEL)); + assertEquals(platformCredential.getVersion(), + subjectAlternativeNameAttrMap.get(PLATFORM_VERSION)); + assertEquals(TEST_HOSTNAME, + subjectAlternativeNameAttrMap.get(TPM_ID_LABEL_OID)); + } + + private Map getSubjectAlternativeNameAttributes( + Extension subjectAlternativeName) { + Map subjectAlternativeNameAttrMap = new HashMap<>(); + + DLSequence dlSequence = (DLSequence) subjectAlternativeName.getParsedValue(); + ASN1TaggedObject asn1TaggedObject = (ASN1TaggedObject) dlSequence.getObjectAt(0); + ASN1Sequence asn1Sequence = (ASN1Sequence) asn1TaggedObject.getObject(); + + Enumeration enumeration = asn1Sequence.getObjects(); + while (enumeration.hasMoreElements()) { + ASN1Set set = (ASN1Set) enumeration.nextElement(); + ASN1Sequence innerAsn1Sequence = (ASN1Sequence) set.getObjectAt(0); + + subjectAlternativeNameAttrMap.put(innerAsn1Sequence.getObjectAt(0).toString(), + innerAsn1Sequence.getObjectAt(1).toString()); + } + return subjectAlternativeNameAttrMap; + } +} From ca83d8556b7a90c4d7d85703428a759b2e2c4a0d Mon Sep 17 00:00:00 2001 From: iadgovuser58 <124906646+iadgovuser58@users.noreply.github.com> Date: Thu, 25 Jan 2024 09:51:06 -0500 Subject: [PATCH 2/2] added resources --- .../nuc-1/ek_cert_7_byte_header_removed.cer | Bin 0 -> 1122 bytes .../certificates/nuc-1/ek_cert_untouched.cer | Bin 0 -> 1129 bytes .../certificates/platform_certs_2/Intel_pc.pem | Bin 0 -> 914 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/nuc-1/ek_cert_7_byte_header_removed.cer create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/nuc-1/ek_cert_untouched.cer create mode 100644 HIRS_AttestationCA/src/test/resources/certificates/platform_certs_2/Intel_pc.pem diff --git a/HIRS_AttestationCA/src/test/resources/certificates/nuc-1/ek_cert_7_byte_header_removed.cer b/HIRS_AttestationCA/src/test/resources/certificates/nuc-1/ek_cert_7_byte_header_removed.cer new file mode 100644 index 0000000000000000000000000000000000000000..f14093b1fd8a17332996c9d9e802350bdc9c2493 GIT binary patch literal 1122 zcmXqLVu>?oVs=}=%*4pVB*M8iEz((@?=Kr zY}Mig?t33Ty?(XP{e-6z*Q7I#|68SQVAeFeC(X0Ky+MpC?2B6F(na>O6h$TOO>@4H zTF6(~{6!(?_gdKnXJgF$n=eNsHgBpgD_hjScJ#=%sGT}fzm{KKwbsWeCTyvrym}LZ z?)je9@RCVOHlJJ4e5~`{?z11RYU|HjQGK6l+R~M8R_GDjo-}4pg9@|YR z(+=_6_2f>}O}6v%-d7i&zT9w@A>no0li&wlEd>*I3h^iTzO^lU^}Nhlo%=qQM@wje z$d7|ODbwv;h4|*C2bCBb%1%wsmf5gIpDSQlsdUBMKdGLzFV@?Og}R6*Ze(I+WMEv} z#FzpMkpu&IU{uH|vq%_-HHd`EH)Ok?c|QA>>6Dtc9Xl>EL_L^i-~>{jz+!D+X<*LA z0%S56=o{#=acHvvwaW`-^6f+QEV@+>lWn$#v&P=f~H8wRdaWOJ56gLosh%@o<1cw+K zM+F#}1cU_#7z!B(KqQ!X*nt`hTnwBI>OsbGvQ!w98Hhn71q^u&xOtcj^^8D?m$Ae^ z0U|C0GMEYIZ^r)%n7J4k7Xk@}MIge!3TOzciJ`H93NcB^0F=^MwfUHtq<{&Z2jl=@ zkiVFKsZkijQw8xj4cNikF=#hOcrw(x_UrgDaAz##dNm_|HzN_YLl-{!nUrXi} z2Uqy))N2g<&Zuq7^KR0P3#rQH&y{-CZ9Vf-pOHaZ$U!~i_T*!qEr n*iv&HQi|T5(8<|Up7;J&&F*y!dG)7RGZ!~2Nk4uf+WHUx#-@Di literal 0 HcmV?d00001 diff --git a/HIRS_AttestationCA/src/test/resources/certificates/nuc-1/ek_cert_untouched.cer b/HIRS_AttestationCA/src/test/resources/certificates/nuc-1/ek_cert_untouched.cer new file mode 100644 index 0000000000000000000000000000000000000000..fbcbe8fba7d823535bf80994f940632a8aa793a5 GIT binary patch literal 1129 zcmWe&WMD}VU@~Z8i8E+oc3Z&A#K^=X!p_jxn*QIkQf$JdD=brDzh?909yj1+W6b@VFGnOcZ>ldVThzdI^vJiUojOy$mS0}A*2gI( zY^kHXdJ}{0`JUGBl1WQ8pIg#=tn=RPvmdT%>(5+KeV=RE(v@#kvP7&8_{|{pWM6mR z^A+nJ+f6Cc4)NUebmnV&vh@OtCUGHZ?JEF)}a|HxPx0 zGx6{QhZq}21sItGgaro}3KFff@{444e(>LB?{jR2Y;Qh(RO;40#Q>d6*6L zj6jK(vBW?DA}$0nm9}O~7zj=tqv`>`Cznw(rlpxWFoXrEJZgpgs3y zoo-p@XK-KV4V&yz#lDK(qt|9k44vF~b$O2Hk$oCU?N^$?aP<&AA|Ps5O3ie4feYHGwwHYXYp>;9c&X;X@@zZj? uWtQ&dJ9$f?S|Y2oFF}H!c3vTFb)R~le42C&_s|7I}dko zVqQt2f^$w{QKF%gfdojDi$~BiuOu}`!8yOEAipTFBr`wHP|-jhB*)Do5mJ)FR?K>|cBP%Nd zlL*t~1Ha8xg86M;O4^)U{;$AM^6WMPB?*2b14DBI6C*<)X=-E{1rjheFf=j-B2!CK z%P0dw14%a4^hQ=DK~QiQZ~{Y!iIE9N@-P|#?FLH;gFMQ_$k4>d%*e=K(8Rdjpm8nG zS+WX@jQ?307a26pH)x#0#szZG4_`)BCKh0L8R)ZdXtM!b$IirLpvfH zT#}li5Rj8tl9peTtKgcKl3!GunhW%}K@?mAqnKYtNl8JmmA-xnL`QLIQCVhkYB3@R z^po>}p^;aj9}?`WpPX7$QVe2&7yR(hSN$&J_eXH`gG0Nv1(M zIP$^1W8q;1M~$JVfiT3stUO#UuErLIrXi8u9tdGJ9xe|fGfPVgT@wQ%LsbK1Ha1|u zu`;spNV=OvdYc#-8yGlSnCrN^hC~8`+`z!lJq#SfvdSzH24W2&8kaY`_^&emTMzT2 z?xQ?O>vVsmHyI?ue9g$n5^fM`5DeoRFtxdp6AEC@1ZSq_W#*-Or&j6#g9I(PFgG?b zlrP@gb0hY_@=rc5vaFjA7w&j9#iGsT?QNFh8?&xXR=<&2Ly{>@N6|ay049I k{ln^v$xGV5{t48Miz(gH|1E!NiAckd+ZJla{2X5a0Fet4>i_@% literal 0 HcmV?d00001