package de.persosim.simulator.protocols.ta; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import de.persosim.simulator.cardobjects.DateTimeCardObject; import de.persosim.simulator.cardobjects.MasterFile; import de.persosim.simulator.cardobjects.TrustPointCardObject; import de.persosim.simulator.cardobjects.TrustPointIdentifier; import de.persosim.simulator.cardobjects.TypeIdentifier; import de.persosim.simulator.crypto.certificates.CardVerifiableCertificate; import de.persosim.simulator.crypto.certificates.ExtensionOid; import de.persosim.simulator.crypto.certificates.GenericExtension; import de.persosim.simulator.crypto.certificates.PublicKeyReference; import de.persosim.simulator.exception.CarParameterInvalidException; import de.persosim.simulator.exception.CertificateNotParseableException; import de.persosim.simulator.platform.CardStateAccessor; import de.persosim.simulator.protocols.RoleOid; import de.persosim.simulator.test.PersoSimTestCase; import de.persosim.simulator.tlv.PrimitiveTlvDataObject; import de.persosim.simulator.tlv.TlvConstants; import de.persosim.simulator.tlv.TlvDataObjectContainer; import de.persosim.simulator.utils.BitField; import mockit.Deencapsulation; import mockit.Mocked; import mockit.NonStrictExpectations; public class AbstractTaProtocolTest extends PersoSimTestCase { @Mocked CardStateAccessor mockedCardStateAccessor; @Mocked MasterFile mockedMf; DateTimeCardObject currentDate; Date future; Date past; Date current; AbstractTaProtocol taProtocol; CertificateHolderAuthorizationTemplate isCvcaChat; CertificateHolderAuthorizationTemplate isDvDomesticChat; CertificateHolderAuthorizationTemplate isDvForeignChat; CertificateHolderAuthorizationTemplate isTerminalChat; PublicKeyReference chr; TrustPointCardObject trustPoint; @Mocked CardVerifiableCertificate certificate; @Mocked CardVerifiableCertificate issuingCertificate; @Mocked GenericExtension certificateExtension; @Before public void setUp() throws CarParameterInvalidException { Calendar calendar = Calendar.getInstance(); calendar.set(2014, 4, 5, 0, 0, 0); calendar.set(Calendar.MILLISECOND, 0); current = calendar.getTime(); calendar.set(2014, 4, 4, 0, 0, 0); calendar.set(Calendar.MILLISECOND, 0); past = calendar.getTime(); calendar.set(2014, 4, 6, 0, 0, 0); calendar.set(Calendar.MILLISECOND, 0); future = calendar.getTime(); currentDate = new DateTimeCardObject(current); taProtocol = new DefaultTaProtocol(); taProtocol.setCardStateAccessor(mockedCardStateAccessor); taProtocol.init(); isCvcaChat = new CertificateHolderAuthorizationTemplate(RoleOid.id_IS, TerminalType.IS, new RelativeAuthorization(CertificateRole.CVCA, new BitField( new boolean[] {}))); isDvDomesticChat = new CertificateHolderAuthorizationTemplate( RoleOid.id_IS, TerminalType.IS, new RelativeAuthorization( CertificateRole.DV_TYPE_1, new BitField( new boolean[] {}))); isDvForeignChat = new CertificateHolderAuthorizationTemplate( RoleOid.id_IS, TerminalType.IS, new RelativeAuthorization( CertificateRole.DV_TYPE_2, new BitField( new boolean[] {}))); isTerminalChat = new CertificateHolderAuthorizationTemplate( RoleOid.id_IS, TerminalType.IS, new RelativeAuthorization( CertificateRole.TERMINAL, new BitField(new boolean[] {}))); chr = new PublicKeyReference("DE", "JUNIT", "00000"); trustPoint = new TrustPointCardObject(null, issuingCertificate); } /** * Test the permanent certificate import by using a valid certificate * replacing an expired one in the trust point and check if the trust point * contains the newly imported certificate. */ @Test public void testImportCertificatePermanent() { // prepare the mock new NonStrictExpectations() { { mockedCardStateAccessor.getMasterFile(); result = mockedMf; mockedMf.findChildren( withInstanceOf(TrustPointIdentifier.class)); result = trustPoint; mockedMf.findChildren( withInstanceOf(TypeIdentifier.class)); result = currentDate; issuingCertificate.getEffectiveDate(); result = past; issuingCertificate.getExpirationDate(); result = past; issuingCertificate.getCertificateHolderReference(); result = chr; certificate.getEffectiveDate(); result = current; certificate.getExpirationDate(); result = future; certificate.getCertificateHolderAuthorizationTemplate(); result = isCvcaChat; certificate.getCertificateHolderReference(); result = chr; } }; Deencapsulation.setField(taProtocol, trustPoint); // call MUT Deencapsulation.invoke(taProtocol, "importCertificate", certificate, issuingCertificate); assertEquals(trustPoint.getCurrentCertificate(), certificate); } /** * Test the temporary certificate import by using a valid domestic DV * certificate and checking if the internal variables representing the last * temporary imported certificate are set. */ @Test public void testImportCertificateTemporary() { // prepare the mock new NonStrictExpectations() { { mockedCardStateAccessor.getMasterFile(); result = mockedMf; mockedMf.findChildren( withInstanceOf(TrustPointIdentifier.class)); result = trustPoint; mockedMf.findChildren( withInstanceOf(TypeIdentifier.class)); result = currentDate; certificate.getEffectiveDate(); result = current; certificate.getExpirationDate(); result = future; certificate.getCertificateHolderAuthorizationTemplate(); result = isDvDomesticChat; certificate.getCertificateHolderReference(); result = chr; } }; // call MUT Deencapsulation.invoke(taProtocol, "importCertificate", certificate, issuingCertificate); assertEquals(Deencapsulation.getField(taProtocol, "mostRecentTemporaryCertificate"), certificate); } /** * Positive test for the date validity checks using domestic dv certificate */ @Test public void testCheckValidityDvDomesticPositive() { // prepare the mock new NonStrictExpectations() { { mockedCardStateAccessor.getMasterFile(); result = mockedMf; mockedMf.findChildren( withInstanceOf(TypeIdentifier.class)); result = currentDate; certificate.getCertificateHolderAuthorizationTemplate(); result = isDvDomesticChat; certificate.getExpirationDate(); result = future; issuingCertificate.getCertificateHolderAuthorizationTemplate(); result = isCvcaChat; issuingCertificate.getExpirationDate(); result = future; } }; // call MUT assertTrue(AbstractTaProtocol.checkValidity(certificate, issuingCertificate, current)); } /** * Positive test for the date validity checks using an accurate terminal certificate (signed by domestic DV) */ @Test public void testCheckValidityAccurateTerminalPositive() { // prepare the mock new NonStrictExpectations() { { mockedCardStateAccessor.getMasterFile(); result = mockedMf; mockedMf.findChildren( withInstanceOf(TypeIdentifier.class)); result = currentDate; certificate.getCertificateHolderAuthorizationTemplate(); result = isDvDomesticChat; certificate.getExpirationDate(); result = future; certificate.getEffectiveDate(); result = past; issuingCertificate.getCertificateHolderAuthorizationTemplate(); result = isDvDomesticChat; } }; // call MUT assertTrue(AbstractTaProtocol.checkValidity(certificate, issuingCertificate, current)); } /** * Negative test for the date validity checks using a non accurate terminal certificate (signed by foreign DV) */ @Test public void testCheckValidityNonAccurateTerminalNegative() { // prepare the mock new NonStrictExpectations() { { mockedCardStateAccessor.getMasterFile(); result = mockedMf; mockedMf.findChildren( withInstanceOf(TypeIdentifier.class)); result = currentDate; issuingCertificate.getCertificateHolderAuthorizationTemplate(); result = isDvForeignChat; certificate.getCertificateHolderAuthorizationTemplate(); result = isTerminalChat; certificate.getExpirationDate(); result = future; } }; // call MUT assertTrue(AbstractTaProtocol.checkValidity(certificate, issuingCertificate, current)); } /** * Positive test for the date validity checks using a CVCA link certificate */ @Test public void testCheckValidityCvcaLinkIssuingCvcaExpired() { // prepare the mock new NonStrictExpectations() { { mockedCardStateAccessor.getMasterFile(); result = mockedMf; mockedMf.findChildren( withInstanceOf(TypeIdentifier.class)); result = currentDate; certificate.getCertificateHolderAuthorizationTemplate(); result = isCvcaChat; certificate.getExpirationDate(); result = future; issuingCertificate.getExpirationDate(); result = past; issuingCertificate.getCertificateHolderAuthorizationTemplate(); result = isCvcaChat; } }; // call MUT assertTrue(AbstractTaProtocol.checkValidity(certificate, issuingCertificate, current)); } /** * Positive test for the date validity checks using a CVCA link certificate */ @Test public void testCheckValidityCvcaLinkIssuingCvcaValid() { // prepare the mock new NonStrictExpectations() { { mockedCardStateAccessor.getMasterFile(); result = mockedMf; mockedMf.findChildren( withInstanceOf(TypeIdentifier.class)); result = currentDate; certificate.getCertificateHolderAuthorizationTemplate(); result = isCvcaChat; certificate.getExpirationDate(); result = future; issuingCertificate.getExpirationDate(); result = future; issuingCertificate.getCertificateHolderAuthorizationTemplate(); result = isCvcaChat; } }; // call MUT assertTrue(AbstractTaProtocol.checkValidity(certificate, issuingCertificate, current)); } /** * Test for checking the date validity using an expired CVCA certificate */ @Test public void testCheckValidityDomesticDvIssuingCvcaInvalid(){ // prepare the mock new NonStrictExpectations() { { mockedCardStateAccessor.getMasterFile(); result = mockedMf; mockedMf.findChildren( withInstanceOf(TypeIdentifier.class)); result = currentDate; certificate.getCertificateHolderAuthorizationTemplate(); result = isDvDomesticChat; certificate.getExpirationDate(); result = future; issuingCertificate.getExpirationDate(); result = past; issuingCertificate.getCertificateHolderAuthorizationTemplate(); result = isCvcaChat; } }; // call MUT assertFalse(AbstractTaProtocol.checkValidity(certificate, issuingCertificate, current)); } /** * Positive test for the update date mechanism that uses an accurate * terminal certificate (signed by domestic DV) */ @Test public void testUpdateDatePositive() { // prepare the mock new NonStrictExpectations() { { certificate.getCertificateHolderAuthorizationTemplate(); result = isCvcaChat; certificate.getEffectiveDate(); result = future; } }; // call MUT AbstractTaProtocol.updateDate(certificate, issuingCertificate, currentDate); assertEquals(future, currentDate.getDate()); } /** * Negative test for the update date mechanism that uses a non accurate * terminal certificate (signed by foreign DV) */ @Test public void testUpdateDateNegative() { // prepare the mock new NonStrictExpectations() { { issuingCertificate.getCertificateHolderAuthorizationTemplate(); result = isDvForeignChat; certificate.getCertificateHolderAuthorizationTemplate(); result = isTerminalChat; certificate.getEffectiveDate(); result = future; } }; // call MUT AbstractTaProtocol.updateDate(certificate, issuingCertificate, currentDate); assertEquals(current, currentDate.getDate()); } @Test public void testIsCertificateIssuerValidPositiveDv() throws CertificateNotParseableException { // prepare the mock new NonStrictExpectations() { { certificate.getCertificateHolderAuthorizationTemplate(); result = isDvDomesticChat; issuingCertificate.getCertificateHolderAuthorizationTemplate(); result = isCvcaChat; } }; // call MUT assertTrue(AbstractTaProtocol.isCertificateIssuerValid(issuingCertificate, issuingCertificate)); } @Test public void testIsCertificateIssuerValidPositiveTerminal() throws CertificateNotParseableException { // prepare the mock new NonStrictExpectations() { { certificate.getCertificateHolderAuthorizationTemplate(); result = isTerminalChat; issuingCertificate.getCertificateHolderAuthorizationTemplate(); result = isDvDomesticChat; } }; // call MUT assertTrue(AbstractTaProtocol.isCertificateIssuerValid(certificate, issuingCertificate)); } @Test public void testIsCertificateIssuerValidPositiveCvcaLink() throws CertificateNotParseableException { // prepare the mock new NonStrictExpectations() { { certificate.getCertificateHolderAuthorizationTemplate(); result = isCvcaChat; issuingCertificate.getCertificateHolderAuthorizationTemplate(); result = isCvcaChat; } }; // call MUT assertTrue(AbstractTaProtocol.isCertificateIssuerValid(issuingCertificate, issuingCertificate)); } @Test public void testIsCertificateIssuerValidNegativeCvcaTerminal() throws CertificateNotParseableException { // prepare the mock new NonStrictExpectations() { { certificate.getCertificateHolderAuthorizationTemplate(); result = isTerminalChat; issuingCertificate.getCertificateHolderAuthorizationTemplate(); result = isCvcaChat; } }; // call MUT assertFalse(AbstractTaProtocol.isCertificateIssuerValid(certificate, issuingCertificate)); } @Test public void testExtractTerminalSector(){ // prepare the mock final ArrayList<GenericExtension> extensions = new ArrayList<>(); extensions.add(certificateExtension); PrimitiveTlvDataObject firstObject = new PrimitiveTlvDataObject(TlvConstants.TAG_80, new byte [] {1,2,3,4}); PrimitiveTlvDataObject secondObject = new PrimitiveTlvDataObject(TlvConstants.TAG_81, new byte [] {5,6,7,8}); final TlvDataObjectContainer dataObjects = new TlvDataObjectContainer(firstObject); dataObjects.addTlvDataObject(secondObject); new NonStrictExpectations() { { certificate.getCertificateExtensions(); result = extensions; certificateExtension.getObjectIdentifier(); result = ExtensionOid.id_Sector; certificateExtension.getDataObjects(); result = dataObjects; } }; Deencapsulation.invoke(taProtocol, "extractTerminalSector", certificate); assertArrayEquals(firstObject.getValueField(), (byte []) Deencapsulation.getField(taProtocol, "firstSectorPublicKeyHash")); assertArrayEquals(secondObject.getValueField(), (byte []) Deencapsulation.getField(taProtocol, "secondSectorPublicKeyHash")); } }